Recipe 5.5. Factoring Out Common Display Code with Layouts


Problem

Most multipage web sites have common visual elements that appear on most pages (or even all) of the site. You want to factor out this common display code and avoid repeating yourself unnecessarily within your view templates.

Solution

Create a layout file in app/views/layouts containing the display elements that you want to appear on all templates rendered by a particular controller. Name this file after the controller whose templates you want it applied to. At some point in this file, call yield to output the contents of the code to which the layout is to apply.

app/views/layouts/main.rhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head>   <meta http-equiv="content-type" content="text/html;charset=utf-8" />   <%= stylesheet_link_tag "main" %>   <title>Some CSS Site</title> </head> <body>   <div >     <h1>Header content...</h1>   </div>     <div >     <h3>Navigation:</h3>     <ul>           <li><a href="/main/">Home</a></li>       <li><a href="/sales/">Sales</a></li>         <li><a href="/reports/">Reports</a></li>       <li><a href="/support/">Support</a></li>     </ul>      </div>     <div >     <%= yield %>   </div>   <div >     <p>Footer text goes here...</p>   </div>   </body> </html>

Once the main.rhtml layout file is created and in place, every template file in app/views/main/ will be surrounded by the contents of the layout. For example, the following index.rhtml file will be substituted for the call to yield in the layout file.

app/views/main/index.rhtml:

<h2>What Is Web 2.0</h2> <p>The bursting of the dot-com bubble in the fall of 2001 marked a turning point for the web. Many people concluded that the web was overhyped, when in fact bubbles and consequent shakeouts appear to be a common feature of all technological revolutions. Shakeouts typically mark the point at which an ascendant technology is ready to take its place at center stage. The pretenders are given the bum's rush, the real success stories show their strength, and there begins to be an understanding of what separates one from the other.</p>

Notice that the layout file includes a call to stylesheet_link_tag "main" that outputs a script include tag for the following CSS file, which positions the various elements of the page.

public/stylesheets/main.css:

body {   margin: 0;   padding: 0;   color: #000;   width: 500px;   border: 1px solid black; } #header {   background-color: #666; } #header h1 { margin: 0; padding: .5em; color: white; } #leftcol {   float: left;   width: 120px;   margin-left: 5px;   padding-top: 1em;   margin-top: 0;  } #leftcol h3 { margin-top: 0; } #maincol { margin-left: 125px; margin-right: 10px; }  #footer { clear: both; background-color: #ccc; padding: 6px; }

Discussion

By default, one layout file corresponds to each controller of your application. The solution sets up a layout for an application with a Main controller. By default, views rendered by the Main controller use the main.rhtml layout.

Figure 5-5 shows the output of the layout for the contents of the index.rhtml template, with the main.css stylesheet applied.

Figure 5-5. A typical four-region web page created using layouts


You can explicitly declare which layout a controller uses with Action Controller's layout method. For example, if you want the Gallery controller to use the same layout as the Main controller, add this layout call to the controller class definition:

class GalleryController < ApplicationController   layout 'main'   ... end

layout also accepts conditional options. So if you want the layout to apply to all actions except the popup action, use:

  layout 'main', :except => :popup

Additionally, instance variables defined in an action are available within the view rendered based on that action as well as the layout template that's applied to the view.

In older projects, you may see the following instead of the newer yield syntax.

<%= @content_for_layout %>

Each does the same thing, including content into the template.

See Also

  • Section 5.6"




Rails Cookbook
Rails Cookbook (Cookbooks (OReilly))
ISBN: 0596527314
EAN: 2147483647
Year: 2007
Pages: 250
Authors: Rob Orsini

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net