依不同controller來assign Layout
要依不同controller來指定對應Layout(template),可以用layout選項來指定。就拿開發中所遇到的問題來舉例:在還沒登入或登入錯誤時,我想指定一個特別的layout來呈現,因為會這些頁面都會經過devise的controller,基於這樣的前提我們可以在application controller下做以下的調整:
class ApplicationController < ActionController::Base protect_from_forgery layout :layout_by_resource protected def layout_by_resource if devise_controller? "guest" else "application" end end end
"devise_controller?"是devise所提供的helper,用以判斷所在的controller是否為devise。
其實在一般情況下我們是不用直接修改application controller的,直接修改要呈現不一樣Layout的controller就可以。但是因為我們看不到devise controller,無法對他做修改,所以就寫在他的父類別讓他繼承這個特性。
而指定layout時其實還可以再做一些微調,例如:
layout "special", :only => :index或
layout "special", :except => [:show, :edit, :new]
大家應該可以注意到以上的兩行和一開始的範例寫法有點不一樣,一個是使用symbol、一個是使用字串,這在意義上是不一樣的。使用symbol是call function,而使用字串就是直接去找這個名字的layout了。
Style
在一開始的application.css.erb中,我們可以在comments中找到以下兩行設定*= require_self *= require_tree .雖然這兩行是寫在註解中,但他們還是有功用的(要把他disable掉只要刪掉"="就好了)。
require_self代表最後匯整的內容要包含"這個檔案"
require_tree代表最後匯整的內容要包含"所在資料夾下所有的檔案"
我們也可以很單純的require單一css,ex:
require bootstrap
同一個controller下為不同的view分配style sheet
不同controller對應各別layout在前面已經提過,但是有時候我們想用一樣的layout,但是是不同的style該怎麼辦呢?這時我們可以在template中動態的載入style sheet:在View中:
<%=stylesheet_link_tag @foo %>
在Controller中:
before_filter :get_css_file def get_css_file @foo = defined?(@style_type) ? 'normal' : 'special' end
或是在你自己的邏輯定義@foo。