On 20 Dec 2010, at 22:03, Wes Gamble wrote:

> I was reading through this post on Shared Layouts 
> (http://www.ruby-forum.com/topic/158686),
> 
> and came across the explanation of the "Application" page type.

That was a while ago and what Sean was referring to is now just called a 
RailsPage. Still not a very good name but share_layouts is a very useful tool.

Essentially, it undoes the twist that radiant has applied to the normal rails 
MVC. In radiant the Page model class acts like a controller, the page content 
acts like a view template and the layout content acts as a layout template. 
There are no real view templates (outside admin) and the SiteController is just 
a page-picker: rendering is delegated to the requested page. You can add more 
public-facing controllers and views, but they exist in the normal rails world, 
cut off from the rendering of radiant content. 

Share_layouts fixes that by letting your normal rails controller wrap radiant 
layouts around view-rendered content, and by letting your views define 
pseudo-page-parts for use in those layouts.

Here's a rough hello world:

  # in app/controllers/greetings_controller.rb

  class GreetingsController < ApplicationController
    radiant_layout "standard"
    def index
      @greeting = "Hello World"
    end
  end
 
  # in views/greetings/index.html.haml:

  %p
      The :main page part is populated for you.
  - content_for :title do
    %h1
      = @greeting
  - content_for :introduction do
    %p
      This is the intro.

  # in the "standard" layout:

  <r:title />
  <r:content part="introduction" />
  <r:content />

The output from this, given a route to GreetingsController#index, will be:

<h1>Hello World</h1>
<p> This is the intro.</p>
<p>The :main page part is created automatically.</p>

As you see, the overall rendering of the view template is captured as a :main 
page page part, and any other page part you want to bring into the template can 
be declared with a content_for block. Title, :breadcrumbs and I think :slug are 
treated specially.

If you don't want to hard-code the name of your radiant layout in the 
controller, you can supply a block that optionally takes the controller as 
argument:

  radiant_layout { Radiant::Config['configured.layout'] }

or

  radiant_layout { |controller| controller.choose_layout }
  def choose_layout
    # here all the usual request machinery is available
    # include current_user and current_site, if relevant
  end

Note that the block must return the name of a layout, not the layout itself.

You may also be interested in Dirk's amalgamation of this and nested_layouts 
into a single layouts extension or my mailer_layouts which lets you build email 
messages the same way.

best,

will


Reply via email to