Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > 8b99df826c3b6cf56a1caaae5f931d50 > files > 396

ruby-actionpack-2.3.4-1mdv2010.0.noarch.rpm

<?xml version="1.0" encoding="iso-8859-1"?>
<!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>
  <title>Module: ActionController::Layout::ClassMethods</title>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  <meta http-equiv="Content-Script-Type" content="text/javascript" />
  <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
  <script type="text/javascript">
  // <![CDATA[

  function popupCode( url ) {
    window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
  }

  function toggleCode( id ) {
    if ( document.getElementById )
      elem = document.getElementById( id );
    else if ( document.all )
      elem = eval( "document.all." + id );
    else
      return false;

    elemStyle = elem.style;
    
    if ( elemStyle.display != "block" ) {
      elemStyle.display = "block"
    } else {
      elemStyle.display = "none"
    }

    return true;
  }
  
  // Make codeblocks hidden by default
  document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
  
  // ]]>
  </script>

</head>
<body>



    <div id="classHeader">
        <table class="header-table">
        <tr class="top-aligned-row">
          <td><strong>Module</strong></td>
          <td class="class-name-in-header">ActionController::Layout::ClassMethods</td>
        </tr>
        <tr class="top-aligned-row">
            <td><strong>In:</strong></td>
            <td>
                <a href="../../../files/lib/action_controller/layout_rb.html">
                lib/action_controller/layout.rb
                </a>
        <br />
            </td>
        </tr>

        </table>
    </div>
  <!-- banner header -->

  <div id="bodyContent">



  <div id="contextContent">

    <div id="description">
      <p>
Layouts reverse the common pattern of including shared headers and footers
in many templates to isolate changes in repeated setups. The inclusion
pattern has pages that look like this:
</p>
<pre>
  &lt;%= render &quot;shared/header&quot; %&gt;
  Hello World
  &lt;%= render &quot;shared/footer&quot; %&gt;
</pre>
<p>
This approach is a decent way of keeping common structures isolated from
the changing content, but it&#8216;s verbose and if you ever want to change
the structure of these two includes, you&#8216;ll have to change all the
templates.
</p>
<p>
With layouts, you can flip it around and have the common structure know
where to insert changing content. This means that the header and footer are
only mentioned in one place, like this:
</p>
<pre>
  // The header part of this layout
  &lt;%= yield %&gt;
  // The footer part of this layout
</pre>
<p>
And then you have content pages that look like this:
</p>
<pre>
   hello world
</pre>
<p>
At rendering time, the content page is computed and then inserted in the <a
href="ClassMethods.html#M000069">layout</a>, like this:
</p>
<pre>
  // The header part of this layout
  hello world
  // The footer part of this layout
</pre>
<p>
NOTE: The old notation for rendering the view from a <a
href="ClassMethods.html#M000069">layout</a> was to expose the magic
<tt>@content_for_layout</tt> instance variable. The preferred notation now
is to use <tt>yield</tt>, as documented above.
</p>
<h2>Accessing shared variables</h2>
<p>
Layouts have access to variables specified in the content pages and vice
versa. This allows you to have layouts with references that won&#8216;t
materialize before rendering time:
</p>
<pre>
  &lt;h1&gt;&lt;%= @page_title %&gt;&lt;/h1&gt;
  &lt;%= yield %&gt;
</pre>
<p>
&#8230;and content pages that fulfill these references <em>at</em>
rendering time:
</p>
<pre>
   &lt;% @page_title = &quot;Welcome&quot; %&gt;
   Off-world colonies offers you a chance to start a new life
</pre>
<p>
The result after rendering is:
</p>
<pre>
  &lt;h1&gt;Welcome&lt;/h1&gt;
  Off-world colonies offers you a chance to start a new life
</pre>
<h2>Automatic <a href="ClassMethods.html#M000069">layout</a> assignment</h2>
<p>
If there is a template in <tt>app/views/layouts/</tt> with the same name as
the current controller then it will be automatically set as that
controller&#8216;s <a href="ClassMethods.html#M000069">layout</a> unless
explicitly told otherwise. Say you have a WeblogController, for example. If
a template named <tt>app/views/layouts/weblog.erb</tt> or
<tt>app/views/layouts/weblog.builder</tt> exists then it will be
automatically set as the <a href="ClassMethods.html#M000069">layout</a> for
your WeblogController. You can create a <a
href="ClassMethods.html#M000069">layout</a> with the name
<tt>application.erb</tt> or <tt>application.builder</tt> and this will be
set as the default controller if there is no <a
href="ClassMethods.html#M000069">layout</a> with the same name as the
current controller and there is no <a
href="ClassMethods.html#M000069">layout</a> explicitly assigned with the
<tt><a href="ClassMethods.html#M000069">layout</a></tt> method. Nested
controllers use the same folder structure for automatic <a
href="ClassMethods.html#M000069">layout</a>. assignment. So an
Admin::WeblogController will look for a template named
<tt>app/views/layouts/admin/weblog.erb</tt>. Setting a <a
href="ClassMethods.html#M000069">layout</a> explicitly will always override
the automatic behaviour for the controller where the <a
href="ClassMethods.html#M000069">layout</a> is set. Explicitly setting the
<a href="ClassMethods.html#M000069">layout</a> in a parent class, though,
will not override the child class&#8216;s <a
href="ClassMethods.html#M000069">layout</a> assignment if the child class
has a <a href="ClassMethods.html#M000069">layout</a> with the same name.
</p>
<h2>Inheritance for layouts</h2>
<p>
Layouts are shared downwards in the inheritance hierarchy, but not upwards.
Examples:
</p>
<pre>
  class BankController &lt; ActionController::Base
    layout &quot;bank_standard&quot;

  class InformationController &lt; BankController

  class VaultController &lt; BankController
    layout :access_level_layout

  class EmployeeController &lt; BankController
    layout nil
</pre>
<p>
The InformationController uses &quot;bank_standard&quot; inherited from the
BankController, the VaultController overwrites and picks the <a
href="ClassMethods.html#M000069">layout</a> dynamically, and the
EmployeeController doesn&#8216;t want to use a <a
href="ClassMethods.html#M000069">layout</a> at all.
</p>
<h2>Types of layouts</h2>
<p>
Layouts are basically just regular templates, but the name of this template
needs not be specified statically. Sometimes you want to alternate layouts
depending on runtime information, such as whether someone is logged in or
not. This can be done either by specifying a method reference as a symbol
or using an inline method (as a proc).
</p>
<p>
The method reference is the preferred approach to variable layouts and is
used like this:
</p>
<pre>
  class WeblogController &lt; ActionController::Base
    layout :writers_and_readers

    def index
      # fetching posts
    end

    private
      def writers_and_readers
        logged_in? ? &quot;writer_layout&quot; : &quot;reader_layout&quot;
      end
</pre>
<p>
Now when a new request for the index action is processed, the <a
href="ClassMethods.html#M000069">layout</a> will vary depending on whether
the person accessing is logged in or not.
</p>
<p>
If you want to use an inline method, such as a proc, do something like
this:
</p>
<pre>
  class WeblogController &lt; ActionController::Base
    layout proc{ |controller| controller.logged_in? ? &quot;writer_layout&quot; : &quot;reader_layout&quot; }
</pre>
<p>
Of course, the most common way of specifying a <a
href="ClassMethods.html#M000069">layout</a> is still just as a plain
template name:
</p>
<pre>
  class WeblogController &lt; ActionController::Base
    layout &quot;weblog_standard&quot;
</pre>
<p>
If no directory is specified for the template name, the template will by
default be looked for in <tt>app/views/layouts/</tt>. Otherwise, it will be
looked up relative to the template root.
</p>
<h2>Conditional layouts</h2>
<p>
If you have a <a href="ClassMethods.html#M000069">layout</a> 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 <a
href="ClassMethods.html#M000069">layout</a>, or restricting a <a
href="ClassMethods.html#M000069">layout</a> to only a single action or a
set of actions. The <tt>:only</tt> and <tt>:except</tt> options can be
passed to the <a href="ClassMethods.html#M000069">layout</a> call. For
example:
</p>
<pre>
  class WeblogController &lt; ActionController::Base
    layout &quot;weblog_standard&quot;, :except =&gt; :rss

    # ...

  end
</pre>
<p>
This will assign &quot;weblog_standard&quot; as the
WeblogController&#8216;s <a href="ClassMethods.html#M000069">layout</a>
except for the <tt>rss</tt> action, which will not wrap a <a
href="ClassMethods.html#M000069">layout</a> around the rendered view.
</p>
<p>
Both the <tt>:only</tt> and <tt>:except</tt> condition can accept an
arbitrary number of method references, so #<tt>:except =&gt; [ :rss,
:text_only ]</tt> is valid, as is <tt>:except =&gt; :rss</tt>.
</p>
<h2>Using a different <a href="ClassMethods.html#M000069">layout</a> in the action render call</h2>
<p>
If most of your actions use the same <a
href="ClassMethods.html#M000069">layout</a>, it makes perfect sense to
define a controller-wide <a href="ClassMethods.html#M000069">layout</a> as
described above. Sometimes you&#8216;ll have exceptions where one action
wants to use a different <a href="ClassMethods.html#M000069">layout</a>
than the rest of the controller. You can do this by passing a <tt>:<a
href="ClassMethods.html#M000069">layout</a></tt> option to the
<tt>render</tt> call. For example:
</p>
<pre>
  class WeblogController &lt; ActionController::Base
    layout &quot;weblog_standard&quot;

    def help
      render :action =&gt; &quot;help&quot;, :layout =&gt; &quot;help&quot;
    end
  end
</pre>
<p>
This will render the help action with the &quot;help&quot; <a
href="ClassMethods.html#M000069">layout</a> instead of the controller-wide
&quot;weblog_standard&quot; <a href="ClassMethods.html#M000069">layout</a>.
</p>

    </div>


   </div>

    <div id="method-list">
      <h3 class="section-bar">Methods</h3>

      <div class="name-list">
      <a href="#M000069">layout</a>&nbsp;&nbsp;
      </div>
    </div>

  </div>


    <!-- if includes -->

    <div id="section">





      


    <!-- if method_list -->
    <div id="methods">
      <h3 class="section-bar">Public Instance methods</h3>

      <div id="method-M000069" class="method-detail">
        <a name="M000069"></a>

        <div class="method-heading">
          <a href="ClassMethods.src/M000069.html" target="Code" class="method-signature"
            onclick="popupCode('ClassMethods.src/M000069.html');return false;">
          <span class="method-name">layout</span><span class="method-args">(template_name, conditions = {}, auto = false)</span>
          </a>
        </div>
      
        <div class="method-description">
          <p>
If a <a href="ClassMethods.html#M000069">layout</a> is specified, all
rendered actions will have their result rendered when the <a
href="ClassMethods.html#M000069">layout</a> <tt>yield</tt>s. This <a
href="ClassMethods.html#M000069">layout</a> can itself depend on instance
variables assigned during action performance and have access to them as any
normal template would.
</p>
        </div>
      </div>


    </div>


  </div>


<div id="validator-badges">
  <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>

</body>
</html>