Rails 小知識 — layout 公用版

Mino chen
CodeForMyself
Published in
3 min readFeb 26, 2021

不知道大家有沒有想過,為什麼 views 裡的檔案都不用寫 header 跟 body 直接就可以開始做畫面?

原因就藏在於 app/views/layouts 這個資料夾!打開之後你會發現裡面有 mail 跟 application 的 html.erb 檔,關鍵就在於這個 application.html.erb!

點開來之後,會發現它中間有這個:
<%= yield %> 靠這句把畫面讓給其他 action 對應的 view

我完全沒有在 controller 裡指定要哪個 layout , 為什麼他知道要去找 application.html.erb?

因為 rails 裡套用公版的順序如下:

  1. 先找 controller 同名的版型
  2. 再找父層版型 ⇒ application.html.erb

如果我們沒有幫他建一個同名版型,就會去抓父層的公版版型!

想要不同版型怎麼辦?

假設你想要幫後台也開一個版型套用,那你要先建一個和 application.html.erb 類似的檔案

#在 app/views/layouts 裡多開一個檔案假設叫 backend.html.erb
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我是後台</title>
</head>
<body>
<h1>後台畫面</h1>
</body>
</html>

套用的方式有幾種:

整個 controller 都用同一個版型,在 controller 裡設定 layout

class YourController < ApplicationController
layout "backend"
end

只有某個 action 用這個版型,在某個 action 裡設定 layout

class YourController < ApplicationController
def index
@book = Book.all
render layout: "backend"
end
end

我不想要套版型怎麼辦?

class YourController < ApplicationController
def index
@book = Book.all
render layout: false
end

難道我只能靠它提供的 嗎 <%= yield %>

不對,你可以自己做!把玩具玩得淋漓盡致就是要自己亂做(不對)

你可以幫這個讓出取名字

#可以在版面上寫下這個
<title><%= yield :my_title %></title>

然後接下來有兩種方式可以塞資料

第一種 provide:直接塞爆字

<% provide :my_title, "你好,這裡是 new 頁面" %>

第二種 content_for:塞爆字

<% content_for :my_title do %>
你好,這裡是 new 頁面
<% end %>

兩種差在哪裡呢?
provide 會在渲染畫面時首先執行,content_for 則是會照順序執行,也就是如果畫面找到一個 provide 就不會再找了,但是會把所有的 content_for 都找完才執行。

祝大家塞爆畫面順利!

--

--