Rails Study(V)Layouts and Rendering
2.4 Using head To Build Header-Only Responses
The head method can be used to send responses with only headers to the browser.
head :bad_request # error header message HTTP/1.1 400 Bad Request
Or we can use other HTTP headers to convey additional information:
head :created, :location => photo_path(@photo) # Location: /photos/1
3. Structuring Layouts
Within a layout, you have access to three tools for combining different bits of output to form the overall response:
* Asset tags
* yield and content_for
* Partials
3.1 Asset Tags
Asset tags provide methods for generating HTML that links views to feeds, JavaScript, stylesheets, images, videos and audios.
* auto_discovery_link_tag
* javascript_include_tag
* stylesheet_link_tag
* image_tag
* video_tag
* audio_tag
3.1.1 Linking to Feeds with auto_discovery_link_tag
3.1.2 Linking to Javascript Files with javascript_include_tag
The javascript_include_tag helper returns an HTML script tag for each source provided.
Rails looks in public/javascripts for these files by default, but you can specify a full path relative to the document root, or a URL.
<%= javascript_include_tag "main" %> #public/javascripts/main.js
<%= javascript_include_tag "main", "columns" %> #public/javascripts/main.js and public/javascripts/columns.js
<%= javascript_include_tag "main", "/photos/columns" %> #public/javascripts/main.js and public/photos/columns.js
<%= javascript_include_tag "http://example.com/main.js" %> #
<%= javascript_include_tag :defaults %> # The defaults option loads the Prototype and Scriptaculous libraries.
<%= javascript_include_tag :all %> # The all option loads every javascript file in public/javascripts, starting with the Prototype and Scriptaculous libraries.
<%= javascript_include_tag :all, :recursive => true %> # load files in subfolders of public/javascripts as well.
<%= javascript_include_tag "main", "columns", :cache => true %>
Create a better user experience by combining multiple files into a single download.
3.1.3 Linking to CSS Files with stylesheet_link_tag
Rails looks in public/stylesheets for these files by default.
<%= stylesheet_link_tag "main" %> #public/stylesheets/main.css
<%= stylesheet_link_tag "main", "column" %> #public/stylesheets/main.css and public/stylesheets/columns.css
<%= stylesheet_link_tag "main", "/photos/columns" %> # public/stylesheets/main.css and public/photos/columns.css
<%= stylesheet_link_tag "http://example.com/main.css" %> #
<%= stylesheet_link_tag "main_print", :media => "print" %>
By default, stylesheet_link_tag creates links with media="screen" ref="sytlesheet" type="text/css". Option(:media, :rel, :type)
<%= stylesheet_link_tag :all %>
<%= stylesheet_link_tag :all, :recursive => true %>
<%= stylesheet_link_tag "main", "columns", :cache => true %>
<%= stylesheet_link_tag "main", "columns", :cache => 'cache/main/display' %>
or
<%= stylesheet_link_tag "main", "columns", :cache => 'cache/#{current_site}/main/display' %>
3.1.4 Linking to Images with images_tag
By default, files are loaded from public/images.
<%= image_tag "header.png" %>
<%= image_tag "icons/delete.gif" %> # supply a path to the image
<%= image_tag "icons/delete.gif", {:height => 45} %>
<%= image_tag "home.gif", :onmouseover => "menu/home_highlight.gif" %>
<%= image_tag "home.gif", :alt => "Home" %>
<%= image_tag "home.gif", :size => "50x20" %>
<%= image_tag "home.gif", :alt => "Go Home",
:id => "HomeImage",
:class => 'nav_bar' %>
3.1.5 Linking to Videos with video_tag
3.1.6 Linking to Audio files with audio_tag
3.2 Understanding yield
Within the context of a layout, yield identifies a section where content from the view should be inserted.
Layout with simple regions.
<html>
<head>
</head>
<body>
<%= yield %>
</body>
</html>
Layout with multiple yielding regions.
<html>
<head>
<%= yield :head %>
</head>
<body>
<%= yield %>
</body>
</html>
The main body of the view will always render into the nunamed yield. To render content into a named yield, use content_for method.
3.3 Using content_for
<% content_for :head do %>
<title>A simple page</title>
<% end %>
<p>Hello, Sillycat!</p>
3.4 Using Partials
3.4.1 Naming Partials
To render a partial as part of a view, you use the render method within the view:
<%= render "menu" %>
This will render a file named _menu.html.erb at that point within the view being rendered.
<%= render "shared/menu" %>
Pull in a partial from another folder, that code will pull in the partial from app/views/shared/_menu.html.erb
3.4.2 Using Partials to Simplify Views
<%= render "shared/ad_banner" %>
<h1>Products</h1>
...
<%= render "shared/footer" %>
For content that is shared among all pages in your application, you can use partials directly from layouts.
3.4.3 Partial Layouts
<%= render "link_area", :layout => "graybar" %>
This would look for a partial named _link_area.html.erb and render it using the layout _graybar.html.erb.
The layout is placed in the same folder with the partial that they belong to.
3.4.4 Passing Local Variables
new.html.erb
<h1>New zone</h1>
<%= error_messages_for :zone %>
<%= render :partial => "form", :locals => { :zone => @zone } %>
edit.html.erb
<h1>Editing zone</h1>
<%= error_messages_for :zone %>
<%= render :partial => "form", :locals => { :zone => @zone } %>
_form.html.erb
<%= form_for(zone) do |f| %>
<p>
<b>Zone name</b><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
3.4.5 Rendering Collections
index.html.erb
<h1>Products</h1>
<%= render :partial => "product", :collection => @products %>
_product.html.erb
<p>Product Name: <%= product.name %></p>
short to
<h1>Products</h1>
<%= render @products %>
or
index.html.erb
<%= render [customer1, employee1, customer2, employee2] %>
customers/_customer.html.erb
<p>Customer: <%= customer.name %></p>
employees/_employee.html.erb
<p>Employee: <%= employee.name %></p>
3.4.6 Local Variables
To use a custom local variable name within the partial, specify the :as option in the call to the partial:
<%= render :partial => "product", :collection => @products, :as => :item %>
We can access an instance of the @products collection as the item local variable within the partial.
Pass in arbitrary local variables to any partial you are rendering with the :locals => {}
<%= render :partial => 'products', :collection => @products,
:as => :item, :locals => {:title => "Products Page"} %>
3.4.7 Spacer Templates
<%= render @products, :spacer_template => "product_ruler" %>
Specify a second partial to be rendered between instances of the main partial.
Rails will render the _product_ruler partial (with no data passed in to it) between each pair of _product partials.
3.5 Using Nested Layouts
app/views/layouts/application.html.erb
<html>
<head>
<title>
<%= @page_title or 'Page Title' %>
</title>
<%= stylesheet_link_tag 'layout' %>
<style type="text/css">
<%= yield :stylesheets %>
</style>
</head>
<body>
<div id="top_menu">Top menu items here</div>
<div id="menu">Menu items here</div>
<div id="content"><%= content_for?(:content) ? yield(:content) : yield %></div>
</body>
</html>
On pages generated by NewController, want another layout
app/views/layouts/news.html.erb
<% content_for :stylesheets do %>
#top_menu {display: none}
#right_menu {float: right; background-color: yellow; color: black}
<% end %>
<% content_for :content do %>
<div id="right_menu">
Right menu items here
</div>
<%= yield(:news_content) or yield %>
<% end %>
<%= render :file => 'layouts/application' %>
references:
http://guides.rubyonrails.org/layouts_and_rendering.html
http://guides.rubyonrails.org/active_record_querying.html
2.4 Using head To Build Header-Only Responses
The head method can be used to send responses with only headers to the browser.
head :bad_request # error header message HTTP/1.1 400 Bad Request
Or we can use other HTTP headers to convey additional information:
head :created, :location => photo_path(@photo) # Location: /photos/1
3. Structuring Layouts
Within a layout, you have access to three tools for combining different bits of output to form the overall response:
* Asset tags
* yield and content_for
* Partials
3.1 Asset Tags
Asset tags provide methods for generating HTML that links views to feeds, JavaScript, stylesheets, images, videos and audios.
* auto_discovery_link_tag
* javascript_include_tag
* stylesheet_link_tag
* image_tag
* video_tag
* audio_tag
3.1.1 Linking to Feeds with auto_discovery_link_tag
3.1.2 Linking to Javascript Files with javascript_include_tag
The javascript_include_tag helper returns an HTML script tag for each source provided.
Rails looks in public/javascripts for these files by default, but you can specify a full path relative to the document root, or a URL.
<%= javascript_include_tag "main" %> #public/javascripts/main.js
<%= javascript_include_tag "main", "columns" %> #public/javascripts/main.js and public/javascripts/columns.js
<%= javascript_include_tag "main", "/photos/columns" %> #public/javascripts/main.js and public/photos/columns.js
<%= javascript_include_tag "http://example.com/main.js" %> #
<%= javascript_include_tag :defaults %> # The defaults option loads the Prototype and Scriptaculous libraries.
<%= javascript_include_tag :all %> # The all option loads every javascript file in public/javascripts, starting with the Prototype and Scriptaculous libraries.
<%= javascript_include_tag :all, :recursive => true %> # load files in subfolders of public/javascripts as well.
<%= javascript_include_tag "main", "columns", :cache => true %>
Create a better user experience by combining multiple files into a single download.
3.1.3 Linking to CSS Files with stylesheet_link_tag
Rails looks in public/stylesheets for these files by default.
<%= stylesheet_link_tag "main" %> #public/stylesheets/main.css
<%= stylesheet_link_tag "main", "column" %> #public/stylesheets/main.css and public/stylesheets/columns.css
<%= stylesheet_link_tag "main", "/photos/columns" %> # public/stylesheets/main.css and public/photos/columns.css
<%= stylesheet_link_tag "http://example.com/main.css" %> #
<%= stylesheet_link_tag "main_print", :media => "print" %>
By default, stylesheet_link_tag creates links with media="screen" ref="sytlesheet" type="text/css". Option(:media, :rel, :type)
<%= stylesheet_link_tag :all %>
<%= stylesheet_link_tag :all, :recursive => true %>
<%= stylesheet_link_tag "main", "columns", :cache => true %>
<%= stylesheet_link_tag "main", "columns", :cache => 'cache/main/display' %>
or
<%= stylesheet_link_tag "main", "columns", :cache => 'cache/#{current_site}/main/display' %>
3.1.4 Linking to Images with images_tag
By default, files are loaded from public/images.
<%= image_tag "header.png" %>
<%= image_tag "icons/delete.gif" %> # supply a path to the image
<%= image_tag "icons/delete.gif", {:height => 45} %>
<%= image_tag "home.gif", :onmouseover => "menu/home_highlight.gif" %>
<%= image_tag "home.gif", :alt => "Home" %>
<%= image_tag "home.gif", :size => "50x20" %>
<%= image_tag "home.gif", :alt => "Go Home",
:id => "HomeImage",
:class => 'nav_bar' %>
3.1.5 Linking to Videos with video_tag
3.1.6 Linking to Audio files with audio_tag
3.2 Understanding yield
Within the context of a layout, yield identifies a section where content from the view should be inserted.
Layout with simple regions.
<html>
<head>
</head>
<body>
<%= yield %>
</body>
</html>
Layout with multiple yielding regions.
<html>
<head>
<%= yield :head %>
</head>
<body>
<%= yield %>
</body>
</html>
The main body of the view will always render into the nunamed yield. To render content into a named yield, use content_for method.
3.3 Using content_for
<% content_for :head do %>
<title>A simple page</title>
<% end %>
<p>Hello, Sillycat!</p>
3.4 Using Partials
3.4.1 Naming Partials
To render a partial as part of a view, you use the render method within the view:
<%= render "menu" %>
This will render a file named _menu.html.erb at that point within the view being rendered.
<%= render "shared/menu" %>
Pull in a partial from another folder, that code will pull in the partial from app/views/shared/_menu.html.erb
3.4.2 Using Partials to Simplify Views
<%= render "shared/ad_banner" %>
<h1>Products</h1>
...
<%= render "shared/footer" %>
For content that is shared among all pages in your application, you can use partials directly from layouts.
3.4.3 Partial Layouts
<%= render "link_area", :layout => "graybar" %>
This would look for a partial named _link_area.html.erb and render it using the layout _graybar.html.erb.
The layout is placed in the same folder with the partial that they belong to.
3.4.4 Passing Local Variables
new.html.erb
<h1>New zone</h1>
<%= error_messages_for :zone %>
<%= render :partial => "form", :locals => { :zone => @zone } %>
edit.html.erb
<h1>Editing zone</h1>
<%= error_messages_for :zone %>
<%= render :partial => "form", :locals => { :zone => @zone } %>
_form.html.erb
<%= form_for(zone) do |f| %>
<p>
<b>Zone name</b><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
3.4.5 Rendering Collections
index.html.erb
<h1>Products</h1>
<%= render :partial => "product", :collection => @products %>
_product.html.erb
<p>Product Name: <%= product.name %></p>
short to
<h1>Products</h1>
<%= render @products %>
or
index.html.erb
<%= render [customer1, employee1, customer2, employee2] %>
customers/_customer.html.erb
<p>Customer: <%= customer.name %></p>
employees/_employee.html.erb
<p>Employee: <%= employee.name %></p>
3.4.6 Local Variables
To use a custom local variable name within the partial, specify the :as option in the call to the partial:
<%= render :partial => "product", :collection => @products, :as => :item %>
We can access an instance of the @products collection as the item local variable within the partial.
Pass in arbitrary local variables to any partial you are rendering with the :locals => {}
<%= render :partial => 'products', :collection => @products,
:as => :item, :locals => {:title => "Products Page"} %>
3.4.7 Spacer Templates
<%= render @products, :spacer_template => "product_ruler" %>
Specify a second partial to be rendered between instances of the main partial.
Rails will render the _product_ruler partial (with no data passed in to it) between each pair of _product partials.
3.5 Using Nested Layouts
app/views/layouts/application.html.erb
<html>
<head>
<title>
<%= @page_title or 'Page Title' %>
</title>
<%= stylesheet_link_tag 'layout' %>
<style type="text/css">
<%= yield :stylesheets %>
</style>
</head>
<body>
<div id="top_menu">Top menu items here</div>
<div id="menu">Menu items here</div>
<div id="content"><%= content_for?(:content) ? yield(:content) : yield %></div>
</body>
</html>
On pages generated by NewController, want another layout
app/views/layouts/news.html.erb
<% content_for :stylesheets do %>
#top_menu {display: none}
#right_menu {float: right; background-color: yellow; color: black}
<% end %>
<% content_for :content do %>
<div id="right_menu">
Right menu items here
</div>
<%= yield(:news_content) or yield %>
<% end %>
<%= render :file => 'layouts/application' %>
references:
http://guides.rubyonrails.org/layouts_and_rendering.html
http://guides.rubyonrails.org/active_record_querying.html