Agile Web Development wiht Rails 2nd ed

 19.9 Layouts and Components

         Layouts 是为了解决页面显示重复:

             The average web site,though, has lots of duplication.
                • Many pages share the same tops, tails, and sidebars.
                • Multiple pages may contain the same snippets of rendered HTML (a blog site, for example, may have multiple places where an article is displayed).
                • The same functionality may appear in multiple places. Many sites have a standard search component, or a polling component, that appears in most of the sites’ sidebars.

             Rails has layouts, partials, and components that reduce the need for duplication in these three situations.

 

Layouts

          Let’s look at a layout template.

  1.            <html>
  2.               <head>
  3.                     <title>Form: <%= controller.action_name %></title>
  4.                     <%= stylesheet_link_tag 'scaffold' %>
  5.             </head>
  6.             <body>
  7.                     <%= @content_for_layout %>
  8.              </body>
  9.           </html>

          

          #控制器里的action

          def my_action
             @msg = "Hello, World!"
           end

         #视图

         my_action.rhtml template

             <h1><%= @msg %></h1>

 

       #最终html代码

       the browser would see the following HTML.
     <html>
          <head>
             <title>Form: my_action</title>
            <link href="/stylesheets/scaffold.css" media="screen" el="Stylesheet" type="text/css" />
         </head>
         <body>
            <h1>Hello, World!</h1>
        </body>
    </html>

 

Locating Layout Files

   #使用模板

   The layout file will be looked for in the app/views/layouts directory.
    class StoreController < ApplicationController
           layout "standard"
            # ...
    end

 

    #设置except和only模板

    You can qualify which actions will have the layout applied to them using the :only and :except qualifiers.
     class StoreController < ApplicationController
                     layout "standard" , :except => [ :rss, :atom ]
                     # ...
      end

 

  #:determine_layout是一个标签,其规则是相应action名字的返回值才是真正的模板,比如说store_down或standard模板

  class StoreController < ApplicationController
           layout :determine_layout
           # ...
           private
                   def determine_layout
                        if Store.is_closed?
                                 "store_down"
                        else
                                 "standard"
                       end
                   end
          end

 

#给action单独制定模板

Finally, individual actions can choose to render using a specific layout (or with no layout at all) by passing render( ) the :layout option.
          def rss
                 render(:layout => false) # never use a layout
          end

          def checkout
                render(:layout => "layouts/simple" )
           end

 

#传递数据到模板

#子模板@title = "My Wonderful Life"对@title赋值,会把值带到父模板

Passing Data to Layouts

<html>
    <head>
            <title><%= @title %></title>
            <%= stylesheet_link_tag 'scaffold' %>
     </head>
     <body>
             <h1><%= @title %></h1>
             <%= @content_for_layout %>
      </body>
</html>

 

An individual template could set the title by assigning to the @title variable.
<% @title = "My Wonderful Life" %>
    <p>
        Dear Diary:
     </p>
     <p>
           Yesterday I had pizza for dinner. It was nice.
     </p>

 

Partial Page Templates

_article.rhtml

 <div class="article" >
      <div class="articleheader" >
             <h3><%= article.title %></h3>
      </div>
      <div class="articlebody" >
            <%= h(article.body) %>
       </div>
</div>

 

Other templates use the render(:partial=>) method to invoke this
        <%= render(:partial => "article" , :object => @an_article) %>
       <h3>Add Comment</h3>
       . . .

   #render的:partial参数 是要载入到模板中的页面名称(但是这个名字不需要"_",例如"_article.rhtml"在此处的名字为article),

   #:object的值是传递给_article.html的实例,而在_article.html里我们不使用@an_article变量名而是使用页面却不要"_"的名字,

   #及我们在_article中使用article来代替 @an_article

 

#如果传递给局部模板的对象是一个控制器里的变量,并且这个变量与局部模板同名,则可以忽略object参数

If the object to be passed to the partial is in a controller instance variable with
the same name as the partial, you can omit the :object parameter.

#在我们前面的例子中,如果我们的控制器里有一个@article实例变量,视图可以仅仅像这样,完成前面的功能

If, in the previous example, our controller had set up the article in the instance
variable @article, the view could have rendered the partial using just
<%= render(:partial => "article" ) %> # = <%= render(:partial => "article",:object=>@article ) %>
<h3>Add Comment</h3>
. . .

 

#可以通过:locals参数传递本地变量到模板,:locals是一个hash,hash中每个实体为本地变量的名字和值

You can set additional local variables in the template by passing render( ) a :locals parameter. This takes a hash where the entries represent the names and values of the local variables to set.
render(:partial => 'article' ,
           :object => @an_article,
           :locals => { :authorized_by => session[:user_name],
                               :from_ip => @request.remote_ip })

 

#局部模板和集合

Partials and Collections

<%= render(:partial => "article" , :collection => @article_list,[:spacer_template=>"spacer"]) %>

集合@article_list根据集合元素的个数来循环的引用_article.rhtml页面,其中的每一个元素在_article.rhtml中的变量名为article

其中:spacer_template是可选的,它的作用是在每个局部模块中间隔的局部模板

例如:_spacer.rhtml代码如下

   <hr />

即在每个局部模板_article之间加上一个换行符;

 

Shared Partial Page Templates

在render()方法中的:partial参数是一个简单的名字,则在当前控制器的视图目录下找相应页面;

如果是"/"的形式,例如"contorllername/viewname"则到相应的controller下面去找view,这样就实现了局部模板的共享;

但是,根据惯例,应该把这些共享模板放在app/views/shared目录下

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值