Fire.app 機能應用教學

Partial 的應用與指定 Layout

在瀏覽器中點選主選單的 "Home" 部分切換到首頁,可以看到目前首頁的版面和先前預定不同,是有包含側欄的,這是因為目前整個網站的頁面都套用了同一個含有側欄的 Layout。為了要讓首頁能夠不要有側欄,我們必須讓首頁套用另一份 Layout。

要達成目的,最簡單的方法似乎是複製一份 Layout 內容至首頁用的 Layout 中再把側欄部分的程式碼刪除,但是這樣一來兩個 Layout 中又包含了重複的程式碼,當必須修改時仍然必須改兩份,並未確實達到程式碼精簡的效果:

為了避免上述狀況,需要使用 Partial 搭配 Layout 來解決問題。

Partial 的主要功能是將 Layout 與 Layout 之間共通的部分再抽出成獨立檔案,可以有效避免程式碼重複的問題:

Partial 檔案和 Layout 檔案一樣並未要在 Build Project 時輸出成獨立檔案,故檔名首字也使用底線。其他詳細說明可以參考文件: Templates, Layouts & Partials

接下來要將全站 Layout 和首頁 Layout 共通的 Header 、 Footer 、 主選單等部分抽出為 Partial,首先在專案根目錄建立一個 _header.html.erb 檔案,之後找到 _layout.html.erb<div class="header-wrapper"> 的部份,將整段 HTML 剪下貼至 _header.html.erb 內容,存檔後便完成 Header 部分的 Partial 檔案:

<div class="header-wrapper">
    <div class="header">
        <h1 class="logo"><a href="index.html">Fire.app</a></h1>
        <h2><%= lorem_sentence %></h2>
    </div>
</div>

至於 _layout.html.erb 內則需要在剛才剪下的程式碼位置補上:

<%= render :partial => "header" %>

才能把已抽出的檔案讀入,維持原來的頁面呈現。

由於課程教材檔中已經準備好其他要抽出的 Partial 檔案,故只要把 _layout.html.erb 中對應的部分換成 render 出 Partial 的語法即可,全部需要更換的部分如下:

完成後 _layout.html.erb 的內容如下:

<!DOCTYPE html>
<html>
<head>
    <%= render :partial => "head" %>
</head>
<body>
    <%= render :partial => "header" %>
    <%= render :partial => "main_menu" %>
    <div class="main-block">
        <div class="main">
            <%= yield %>
        </div>
        <div class="side">
            <div class="ad">
                Ad Words
            </div>
            <div class="links">
                <h2>Information Links</h2>
                <ul>
                    <% 8.times do %>
                        <li><a href="#"><%= lorem_words (4+rand(3)) %></a></li>
                    <% end %>
                </ul>  
            </div>
        </div>
    </div>
    <%= render :partial => "footer" %>
    <%= livereload_js %>
</body>
</html>

從程式碼中我們可以看到側欄的部份並沒有抽出成 Partial ,這是因為首頁的 Layout 並沒有用到側欄的部份,因此目前沒有需要特別將側欄也抽出成 Partial 檔案。

完成專案共用的 Layout 改造後即可著手處理首頁的 Layout 部分,先在專案根目錄建立一個名稱為 _sp_layout.html.erb 的檔案,並將 _layout.html.erb 的全部內容複製貼到 _sp_layout.html.erb 檔案中,然後刪除整個 <div class="side"> 部分,這樣就完成了要給首頁使用的無側欄 Layout _sp_layout.html.erb ,內容如下:

<!DOCTYPE html>
<html>
<head>
    <%= render :partial => "head" %>
</head>
<body>
    <%= render :partial => "header" %>
    <%= render :partial => "main_menu" %>
    <div class="main-block">
        <div class="main">
            <%= yield %>
        </div>
    </div>
    <%= render :partial => "footer" %>
    <%= livereload_js %>
</body>
</html>

雖然已經準備好給首頁用的 Layout 內容,不過目前首頁檔案 index.html.erb 並未使用我們做好的 _sp_layout.html.erb 做為 Layout。
為達成需求,我們必須使用一個特殊檔案來指定首頁要用的 Layout,其檔名必須和要套用 Layout 的頁面名稱對應且副檔名的最後一段為 .layout。以目前的專案為例,需要指定 Layout 的檔案是首頁 index.html.erb ,用來指定 Layout 的檔案名稱必須和首頁相同但更改副檔名最後的 erb 部分,變成 index.html.layout 。建立 index.html.layout 後只需要在內容中寫入欲指定的 Layout 檔案即可。也就是 index.html.layout 之內容為:

_sp_layout.html.erb

如此一來 index.html.erb 就會使用 _sp_layout.html.erb 而不是預設的 Layout 來呈現內容,切換至瀏覽器便可看見首頁的部份已經成為我們預期中沒有側欄的版面。網站目前的 Layout 架構如下: