转自:http://ihower.tw/rails3/actionview.html
Layout版型
Layout可以用来包裹Template样板,让不同View可以共用Layout作为文件的头尾。因此我们可以为全站的页面建立共用的版型。这个档案预设是app/views/layouts/application.html.erb。如果在app/views/layouts目录下有跟某Controller同名的Layout档案,那这个Controller下的所有Views就会使用这个同名的Layout。
预设的Layout长得如下:
<!DOCTYPE html>
<html>
<head>
<title>YourApplicationName</title>
<%= stylesheet_link_tag "application" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
其中的<%= yield %>
会被替换成个别Action
的样板。
如果需要指定Controller的Layout,可以这么做:
class EventsController < ApplicationController
layout "special"
end
这样就会指定Events Controller下的Views都使用app/views/layouts/special.html.erb这个Layout,你可以加上参数:only
或:except
表示只有特定的Action:
class EventsController < ApplicationController
layout "special", :only => :index
end
或是
class EventsController < ApplicationController
layout "special", :except => [:show, :edit, :new]
end
请注意到使用字串和Symbol是不同的。使用Symbol的话,它会透过一个同名的方法来动态决定,例如以下的Layout是透过determine_layout
这个方法来决定:
class EventsController < ApplicationController
layout :determine_layout
private
def determine_layout
( rand(100)%2 == 0 )? "event_open" : "event_closed"
end
end
除了 在Controller层级设定Layout,我们也可以设定个别的Action使用不同的Layout,例如:
def show
@event = Event.find(params[:id])
render :layout => "foobar"
end
这样show Action的样板就会套用foobar Layout。更常见的情形是关掉Layout,这时候我们可以写render :layout => false
。
自定Layout内容
除了<%= yield %>
会载入Template内容之外,我们也可以预先自定一些其他的区块让Template可以置入内容。例如,要在Layout中放一个侧栏用的区块,取名叫做:sidebar
:
<div id="sidebar">
<%= yield :sidebar %>
</div>
<div id="content">
<%= yield %>
</div>
那么在Template样板中,任意地方放:
<%= content_for :sidebar do %>
<ul>
<li>foo</li>
<li>bar</li>
</ul>
<% end %>
那么这段内容就会被置入到Layout的<%= yield :sidebar %>
之中。
Layout版型的继承(进阶)
- http://edgerails.info/articles/what-s-new-in-edge-rails/2011/01/12/template-inheritance/index.html
- http://asciicasts.com/episodes/269-template-inheritance