RailsCasts中文版,#7 All About Layouts 页面关联布局文件

这次咱们聊聊页面布局文件。布局文件其实也是一个页面,用来定义一些公共的或者框架的页面结构。普通的页面文件再嵌入到布局文件预留的空间中来形成整个页面的样子。布局文件是可以在各个页面之间公用的公共资源。

全局范围布局文件

下面的页面列出所有的项目名称

<h2>Projects</h2>
<ul>
<% for project in @projects %>
    <li><%= project.name %></li>
<% end %>
</ul>

这是一个普通页面:

E007I01 (1)

 

比如说,我们想为这个站点的每一个页面都增加一个页首、图标、导航菜单栏,就应该使用布局文件。布局文件的标准存放位置在/app/view/layouts目录。在其中创建一个名为application.rhtml[1]的应用全局布局文件。这个文件的布局规则将会作用域所有的控制器和页面请求中。我们把布局文件定义成:

<h1>Application Layout!</h1>
<%= yield %>

请注意第二行,yield告诉布局文件说在这里应该是插入应用了这个布局文件的页面内容。重新刷新后可以看出,定义的布局已经生效了。

E007I02

这么着定义的布局文件是全局范围的,将会作用于所有的页面上。实际应用中肯定还不能这么粗狂,还得定义一些特定于不同类型页面的布局文件。

特定于控制器的布局文件

通过把控制器的名称指定给布局文件,来将布局文件和控制器关联。这样一来,这个布局文件就会作用到所有指向这个控制器页面。比如说,在layouts目录建立一个projects.rhtml[2]文件意味着这个布局只在Project对应的控制器生效。

<h1>Project Layout!</h1>
<%= yield %>

E007I03

如果好几个控制器想共享一个布局文件该怎么办呢?比如说,我想共享名字叫admin的那个布局文件。那就在控制器代码中明确指定吧:

class ProjectsController < ApplicationController
  layout "admin"

  def index
    @projects = Project.find(:all)
  end
end

在控制器中通过layout方法指定的布局文件会覆盖通过文件名字规则指定的布局定义。

动态指定布局文件

也可以动态关联布局文件,比如说我们只是想让用户登录之后再让页面关联名为admin的布局文件。可以通过给layout方法传递参数的方式实现;定义一个与参数名相同的方法,方法逻辑中计算在什么时候应该使用哪个名字的布局文件即可。

class ProjectsController < ApplicationController
  layout :user_layout

  def index
    @projects = Project.find(:all)
  end

  protected
  def user_layout
    if current_user.admin?
      "admin"
    else
      "application"
    end
  end
end

通过render方法,可以更加精细地设定哪个控制器的那个请求使用哪个布局文件。

def index
  @projects = Project.find(:all)
  render :layout => 'projects'
end

通过render方法指定的布局文件会覆盖控制器关联布局文件的定义。想清空布局关联可以使用:

render :layout => false
注:
  1. 在Rails2及以后版本,布局文件命名按照application.html.erb的规则
  2. 在Rails2及以后版本,布局文件命名按照.html.erb

作者授权:Your welcome to post the translated text on your blog as well if the episode is free(not Pro). I just ask that you post a link back to the original episode on railscasts.com.

原文链接:http://railscasts.com/episodes/7-all-about-layouts

posted on 2012-11-21 20:10  边晓宇  阅读(845)  评论(1编辑  收藏  举报