Another layout question - Layouts on a per method basis - La


#1

I feel I am very close to understanding how layouts are used in Rails:

Q1. I know one can specify a “default” layout for all methods in a
controller by specifying
layout ‘my-default-layout’

How can this be overridden for individual methods so when those
methods are called/executed, the overridden layout will be used. Is
this possible?

Q2. With no “default” layout specified, I tried to use the following
for a method:
render (:layout => ‘custom-layout-for-method’)
and
render_component(:action => ‘login’, :controller=>‘member’,
:layout=>‘custom-layout-for-method’)

but the page is rendered with no layout. Can anyone please explain why
no layout was used? How can I make it use a custom layout on a per
method basis?

Q3. I am displaying paginated results for the list action of tags
controller. This page already has a layout defined. Everything works
fine. Now, I am interested in implementing the ajax_pagination_links
(http://www.bigbold.com/snippets/posts/show/386). However since the
layout has already been defined, every time I click on the page number,
the entire page including the header is loaded again within my div. I
cannot find how I can turn off the layout conditionally or alltogether
only for subsequent calls.
Since my @resource_pages collection is retrieved in a method that
has a layout defined “globally” how can I turn off the header for
subsequent pages only? I hope I am making sense here.

Thank you for making me a part of this wonderful community.

Frank


#2

Hello Frank,
When you make your layout deceleration in your controller you can pass
:only and :except as parameters.
like this:
layout ‘layout_name’, :only => [:method1, :method2]

You can also replace the name of the layout with a symbol which
designates a method in the controller to call for determining the
layout.
like this:
layout :determin_layout_method

def determin_layout_method
if condition == true
‘method1’
else
false # returning false will mean no layout is rendered
end
end

finally you can pass the layout as a parameter in your render call
inside a method but you will need to include a path from template_root
like this:
render :layout => ‘layout/template’ # notice that is layout/template and
not template

Also remember that layout is just a class method so you can also do
something like this in an instance method:
self.class.layout ‘new_layout_for_class’ #this is nice because it sets
the layout but you dont need to call render. This is probably good
practice because you can call the method from other methods in the class
and you wont run into more than one call to render problems.

I hope that helps.

softwareengineer 99 wrote:

I feel I am very close to understanding how layouts are used in Rails:

Q1. I know one can specify a “default” layout for all methods in a
controller by specifying
layout ‘my-default-layout’

How can this be overridden for individual methods so when those
methods are called/executed, the overridden layout will be used. Is
this possible?

Q2. With no “default” layout specified, I tried to use the following
for a method:
render (:layout => ‘custom-layout-for-method’)
and
render_component(:action => ‘login’, :controller=>‘member’,
:layout=>‘custom-layout-for-method’)

but the page is rendered with no layout. Can anyone please explain why
no layout was used? How can I make it use a custom layout on a per
method basis?

Q3. I am displaying paginated results for the list action of tags
controller. This page already has a layout defined. Everything works
fine. Now, I am interested in implementing the ajax_pagination_links
(http://www.bigbold.com/snippets/posts/show/386). However since the
layout has already been defined, every time I click on the page number,
the entire page including the header is loaded again within my div. I
cannot find how I can turn off the layout conditionally or alltogether
only for subsequent calls.
Since my @resource_pages collection is retrieved in a method that
has a layout defined “globally” how can I turn off the header for
subsequent pages only? I hope I am making sense here.

Thank you for making me a part of this wonderful community.

Frank


#3

william heartwell wrote:

finally you can pass the layout as a parameter in your render call
inside a method but you will need to include a path from template_root
like this:
render :layout => ‘layout/template’ # notice that is layout/template and
not template

Also remember that layout is just a class method so you can also do
something like this in an instance method:
self.class.layout ‘new_layout_for_class’ #this is nice because it sets
the layout but you dont need to call render. This is probably good
practice because you can call the method from other methods in the class
and you wont run into more than one call to render problems.

I tried your advice in my account controller but I cant seem to get it
to work.
I tried:
self.class.layout ‘frontend’
self.class.layout ‘layout/frontend’
self.class.layout ‘layouts/frontend’

Here is my code:

class AccountController < ApplicationController
include AuthenticatedSystem
before_filter :login_required, :except => [:login]
layout ‘backend’, :except => [:login]

def login
self.class.layout ‘frontend’ # My public layout is
app/views/layouts/frontend.rhtml
return unless request.post?
self.current_user = User.authenticate(params[:login],
params[:password])
if current_user
redirect_back_or_default(:controller => ‘/account’, :action =>
‘index’)
flash[:notice] = “Logged in successfully”
else
flash[:notice] = “Error logging in”
end
end

What am I doing wrong?


#4

Hello William,

Yes, this does help a lot.

Thank you very much for your time and assistance. It is much
appreciated.

Frank

william heartwell removed_email_address@domain.invalid wrote:I hope that helps.


#5

http://api.rubyonrails.org/classes/ActionController/Layout/ClassMethods.html

If you have a layout that by default is applied to all the actions of a
controller, you still have the option of rendering a given action or set
of
actions without a layout, or restricting a layout to only a single
action or
a set of actions. The :only and :except options can be passed to the
layout
call. For example:

class WeblogController < ActionController::Base
layout “weblog_standard”, :except => :rss

# ...

end

This will assign “weblog_standard” as the WeblogController’s layout
except
for the rss action, which will not wrap a layout around the rendered
view.

Both the :only and :except condition can accept an arbitrary number of
method references, so #:except => [ :rss, :text_only ] is valid, as is
:except
=> :rss.