#125 Dynamic Layouts
Discover how to dynamically change the layout using content in the database. Check out this episode for details.
- Download:
- source codeProject Files in Zip (113 KB)
- mp4Full Size H.264 Video (18.9 MB)
- m4vSmaller H.264 Video (12.7 MB)
- webmFull Size VP8 Video (33 MB)
- ogvFull Size Theora Video (26.3 MB)
Resources
bash
script/generate migration add_layout_to_blogs layout_name:string custom_layout_content:text
rake db:migrate
gem install liquid
script/generate migration add_layout_to_blogs layout_name:string custom_layout_content:text rake db:migrate gem install liquid
controllers/application.rb
def load_blog
@current_blog = Blog.find_by_subdomain(current_subdomain)
if @current_blog.nil?
flash[:error] = "Blog invalid"
redirect_to root_url
else
self.class.layout(@current_blog.layout_name || 'application')
end
end
def load_blog @current_blog = Blog.find_by_subdomain(current_subdomain) if @current_blog.nil? flash[:error] = "Blog invalid" redirect_to root_url else self.class.layout(@current_blog.layout_name || 'application') end end
config/environment.rb
config.gem 'liquid'
config.gem 'liquid'
layouts/custom.html.erb
<%= Liquid::Template.parse(@current_blog.custom_layout_content).
render('page_content' => yield, 'page_title' => yield(:title)) %>
<%= Liquid::Template.parse(@current_blog.custom_layout_content).
render('page_content' => yield, 'page_title' => yield(:title)) %>
blogs/_form.html.erb
<p>
<%= f.label :layout_name %><br />
<%= f.select :layout_name, [["Standard", 'application'], ["Plain", 'plain'], ["Custom", 'custom']] %>
</p>
<p>
<%= f.label :custom_layout_content %><br />
<%= f.text_area :custom_layout_content, :rows => 12 %>
</p>
<p> <%= f.label :layout_name %><br /> <%= f.select :layout_name, [["Standard", 'application'], ["Plain", 'plain'], ["Custom", 'custom']] %> </p> <p> <%= f.label :custom_layout_content %><br /> <%= f.text_area :custom_layout_content, :rows => 12 %> </p>
UPDATE: As Pratik mentioned in the comments, the above code is not thread safe. Here is a better way to handle the layout which is thread safe.
application.rb
layout :set_layout
def load_blog
@current_blog = Blog.find_by_subdomain(current_subdomain)
if @current_blog.nil?
flash[:error] = "Blog invalid"
redirect_to root_url
end
end
def set_layout
(@current_blog && @current_blog.layout_name) || 'application'
end
layout :set_layout def load_blog @current_blog = Blog.find_by_subdomain(current_subdomain) if @current_blog.nil? flash[:error] = "Blog invalid" redirect_to root_url end end def set_layout (@current_blog && @current_blog.layout_name) || 'application' end

