Setting layout template in .rhtml


#1

I’ve a single controller -

class ContentController < ApplicationController end

in the app/views/content folder I have quite a few .rhtml files

I need to be able to choose a different layout template to
use in each of these .rhtml files.

i’d like to be able to do something like (which doesn’t work…)

<% layout ‘layout1’ %>

Any suggestions?


#2

You can set the layout as part of the render method, when you decide
which
.rhtml template to render

From http://api.rubyonrails.com/classes/ActionController/Base.html#M000178

Renders the template for the action “goal” within the current

controller
render :action => “goal”

Renders the template for the action “short_goal” within the

current controller,

but without the current active layout

render :action => “short_goal”, :layout => false

Renders the template for the action “long_goal” within the current

controller,

but with a custom layout

render :action => “long_goal”, :layout => “spectacular”


#3

Paul B. wrote:

You can set the layout as part of the render method, when you decide
which
.rhtml template to render

Yeah - that’s not exactly what I’m looking for - I want to decide what
layout to use in the .rhtml itself -

my controller defines no actions - so the behaviour is a file

app/views/content/file.rhtml

is rendered when i hit

http://example.com/content/file

if the ContentController set’s layout like

class ContentController < ApplicationController
layout ‘example_layout’
end

then app/views/layout/example_layout.rhtml is used as the layout.

calling ‘render’ in the file.rhtml has no effect.

I’ve had a good trawl of docs and src - without finding anything
obvious. So I’m just wondering if someone has come across a solution or
if someone with better knowledge of rails source knows of an approach.

Cheers
Darragh


#4

It may be possible to make it work the way you want, but the easiest way
to
make this work is to use an action in the controller to decide. The
whole
point of a controller is to decide what to do, and part of that can be
to
decide which layout to use.

Use the controller to control and the view to view.


#5

Tom F. wrote:

use an action in the controller to decide.

The ContentController I’m using deals with arbitrary content in the app
i’m working on - pages with static content (apart from some dynamic bits
handled in layouts)

The reason I want to be able to control the layout in the rhtml file is
so I can keep the advantage of the default behaviour - (ie not define
actions - for every page I add)

I’d prefer something like <% layout ‘layout1’ %> in each of these
content rhtml files - than have to define an action like

def xxxx_page
render :action => ‘xxx_page’, :layout => ‘layout1’
end

for every new content file I add.

you may be thinking why do i need to change layouts like this within a
single controller - the answer is the web design being imposed on the
app i’m working on makes this necessary…


#6

Just curious, what defines which rhtml file get’s which layout? If it’s
some attribute (database, param, session, etc …) then you can write
code
in the application.rb controller to switch layouts based on this
attribute.
I’ve done this, so it’s easy. :slight_smile:

-andy


#7

ok - one solution I can use is to split my layout into ‘header’ and
‘footer’ and have something like

<%= render ‘/layouts/example_layout_header’%>

Normal template contents

<%= render '/layouts/example_layout_footer'%>

which is ok for me at the moment until I can figure a better solution.


#8

Take a look at this to get some ideas on how to get the correct layout
in
the controller code:

http://habtm.com/articles/2005/04/28/rails-layout-fun

What dynamic bits are in the layouts?

I don’t think it’s possible to have a view change its layout, as the
layout
has already been picked before the view gets rendered.

The documentation indicates you can do this be having a single layout
that
picks sub-layout file, calls

<%= render "sub-layout-file-name" %>

Your sub-layout code would do exactly as a layout does, including having
the
@content_for_layout variable which contains the output from the action
rendering.


#9

I;ve figured out a workable approach - with the benefit to me of nicer
urls

in routes.rb for each section of static content - which maps to logical
section of site and specific layout

map.connect ‘content/info/:template’, :controller => ‘content’, :action
=> ‘info’

I define action ‘info’ in ContentController something like

def info
template_name = ‘content/info/#{}’ + params[:template]
render :template => template_name, :layout => ‘info_layout’
end

This is ok for me - I traced through how action controller handles
requests which don’t have actions - and couldn’t see any easy way to get
behaviour i originally wanted.


#10

Tom F. wrote:

The documentation indicates you can do this be having a single layout
that picks sub-layout file,

Sorry - didn’t pick up on this the first time -

I could have ContentController - and all controllers choose the same
layout - but each of them set some variable and in the main layout
switch amongst sublayouts based on the value of the variable.

Which isn’t too bad a solution either - I think i’ll stick with the
routes.rb based solution for the moment.