Action View Layouts
Layouts
反轉常見的模式,將共用標題和頁尾包含在許多範本中,以隔離重複設定中的變更。包含模式的頁面看起來像這樣
<%= render "application/header" %>
Hello World
<%= render "application/footer" %>
這種方法是讓共用結構與變更內容隔離的不錯方式,但它很冗長,如果您想變更這兩個包含的結構,您必須變更所有範本。
使用 Layouts,您可以反轉它,讓共用結構知道在何處插入變更內容。這表示僅在一個地方提及標題和頁尾,如下所示
// The header part of this layout
<%= yield %>
// The footer part of this layout
然後,您有看起來像這樣的內容頁面
hello world
在呈現時間,內容頁面會被計算,然後插入在 Layout 中,如下所示
// The header part of this layout
hello world
// The footer part of this layout
存取共用變數
Layouts
可以存取在內容頁面中指定的變數,反之亦然。這允許您使用在呈現時間之前不會具體化的參照建立 Layouts
<h1><%= @page_title %></h1>
<%= yield %>
…和在呈現時間填入這些參照的內容頁面
<% @page_title = "Welcome" %>
Off-world colonies offers you a chance to start a new life
呈現後的結果是
<h1>Welcome</h1>
Off-world colonies offers you a chance to start a new life
Layout 指派
您可以宣告指定 Layout (使用 layout 類別方法),或為其指定與您的控制器相同的名稱,並將其置於 app/views/layouts
中。如果子類別沒有指定 Layout,它會使用常規 Ruby 繼承繼承其 Layout。
例如,如果您有 PostsController 和一個名為 app/views/layouts/posts.html.erb
的範本,該範本會用在 PostsController 和繼承自 PostsController 的控制器中的所有動作。
如果您使用模組 (例如 Weblog::PostsController),您會需要一個名為 app/views/layouts/weblog/posts.html.erb
的範本。
由於您的所有控制器都繼承自 ApplicationController,如果未指定或提供其他 Layout,它們會使用 app/views/layouts/application.html.erb
。
繼承範例
class BankController < ActionController::Base
# bank.html.erb exists
class ExchangeController < BankController
# exchange.html.erb exists
class CurrencyController < BankController
class InformationController < BankController
layout "information"
class TellerController < InformationController
# teller.html.erb exists
class EmployeeController < InformationController
# employee.html.erb exists
layout nil
class VaultController < BankController
layout :access_level_layout
class TillController < BankController
layout false
在這些範例中,我們有三個內部查詢情境
-
BankController
使用「bank」Layout。 -
ExchangeController
使用「exchange」Layout。 -
CurrencyController
從 BankController 繼承 Layout。
但是,當 Layout 被明確設定時,明確設定的 Layout 會勝出
-
InformationController
使用明確設定的「information」Layout。 -
TellerController
也使用「information」Layout,因為父項明確設定了它。 -
EmployeeController
使用「employee」Layout,因為它將 Layout 設定為nil
,重新設定父項組態。 -
VaultController
透過呼叫access_level_layout
方法動態選擇 Layout。 -
TillController
完全不使用 Layout。
Layout 類型
Layouts
基本上就只是常規範本,但此範本的名稱不需要靜態指定。有時,您想根據執行時間資訊來交替 Layout,例如某人是否已登入。這可以透過將方法參照指定為符號,或使用內嵌方法 (以 proc 的形式) 來執行。
方法參照是可變 Layout 的首選方法,並且這樣使用
class WeblogController < ActionController::Base
layout :writers_and_readers
def index
# fetching posts
end
private
def writers_and_readers
logged_in? ? "writer_layout" : "reader_layout"
end
end
現在當新的請求處理索引動作時,佈局將依據存取的人是否已登入而有所不同。
若要使用內聯方法(如 proc),請執行以下操作
class WeblogController < ActionController::Base
layout proc { |controller| controller.logged_in? ? "writer_layout" : "reader_layout" }
end
若未提供引數給 proc,將在目前控制器的內容中評估。
class WeblogController < ActionController::Base
layout proc { logged_in? ? "writer_layout" : "reader_layout" }
end
當然,指定佈局最常見的方式仍然只是作為一般範本名稱
class WeblogController < ActionController::Base
layout "weblog_standard"
end
範本將始終在 app/views/layouts/
資料夾中找到。但您也可以直接指向 layouts
資料夾。layout "layouts/demo"
與 layout "demo"
相同。
設定佈局為 nil
會強制在檔案系統中找出它,且若不存在,將會回歸至父級行為。將其設定為 nil
有助於重新啟用範本查詢,覆寫先前的父級設定
class ApplicationController < ActionController::Base
layout "application"
end
class PostsController < ApplicationController
# Will use "application" layout
end
class CommentsController < ApplicationController
# Will search for "comments" layout and fall back to "application" layout
layout nil
end
條件式佈局
若您有一個佈局預設套用至控制器的所有動作,您仍然可以選擇呈現給定動作或動作組而無佈局,或將佈局限制在僅一個動作或動作組。:only
和 :except
選項可以傳遞給佈局呼叫。例如
class WeblogController < ActionController::Base
layout "weblog_standard", except: :rss
# ...
end
這將指定「weblog_standard」為 WeblogController 的佈局,用於除 rss
動作以外的所有動作,並將直接呈現 rss
動作,而不會在呈現的檢視周圍加上佈局。
:only
和 :except
條件都可以接受任意數量的參照方法,因此 except: [ :rss, :text_only ]
是有效的,except: :rss
也是。
在動作呈現呼叫中使用不同的佈局
若大部分動作使用相同的佈局,將如上所述定義控制器範圍的佈局很有意義。有時您會有例外狀況,其中一個動作想要使用不同的佈局而不是其他控制器。您可以透過傳遞 :layout
選項給 render
呼叫來執行此操作。例如
class WeblogController < ActionController::Base
layout "weblog_standard"
def help
render action: "help", layout: "help"
end
end
這將覆寫控制器範圍的「weblog_standard」佈局,並會以「help」佈局呈現「help」動作。
實例公開方法
action_has_layout?() 連結
控制是否應使用佈局呈現動作。若要停用目前動作的任何 layout
設定,使其可在沒有佈局的情況下呈現,則請在控制器中覆寫此方法,使其傳回 false,或在呈現前將 action_has_layout
屬性設定為 false。
原始碼:顯示 | 在 GitHub 上
# File actionview/lib/action_view/layouts.rb, line 372 def action_has_layout? @_action_has_layout end