More than 2 dynamic layout options per controller in Rails

138 Views Asked by At

Using multiple layout statements in Rails will throw an error. Rails ignores all but the last layout statement.

However, I have a complicated layout system where I need to dynamically render several different layouts other than the standard application layout (the layout option in a controller allows for just one alternative layout, the rest defaulting to app/layouts/application.html.erb). I was hoping the following would be a good substitute:

In this case, I'm using a static_controller.rb to render the following static content pages (about.html.erb, contact.html.erb, careers.html.erb, help.html.erb, home.html.erb, landing.html.erb, legal.html.erb, and policies.html.erb).

  1. landing.html.erb will have a custom, full-page layout with no header or footer.
  2. about, contact, home, and legal will each follow the "main" layout [app/views/layouts/main.html.erb].
  3. careers, help, and policies will each follow the "not_main" layout [app/views/layouts/not_main.html.erb].

I need something similar to this in the target controller:

class StaticController < ApplicationController
...
layout 'full', :only => [:landing]

%w[about contact home legal ].each do |static_page|
  layout 'main'
end

%w[careers help policies].each do |static_page|
  layout 'not_main'
end
...
def about
end
...
end #Closes the Static Controller

This would be preferable to setting the layout in each action call. However, Rails continues to ignore the previous layout statements, even though they are wrapped in a %w array. Any ideas how to make something like this work?

2

There are 2 best solutions below

0
On BEST ANSWER

This works for me on Rails7:

class StaticController < ApplicationController

  layout :select_layout

private
  def select_layout
    "main" if %w[about contact home legal].include? action_name
    "full" if %w[landing].include? action_name
    # ...etc
  end

end

1
On
class StaticController < ApplicationController
  layout 'full', only: [:landing]
  layout 'main', only: [:about, :contact, :home, :legal]
  layout  'not_main', only: [:careers, :help, :policies]

  .....
end