2012年11月6日 星期二

[宅] 宅男臥軌日記(8) - 關於layout & style



依不同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。

沒有留言:

張貼留言