Page, Regions and Blocks
網頁、區域和區塊是 coServ 用來解決網頁設計繁複又容易出錯的方法。將一個完整的網頁解構成區域和區塊,讓開發者能專注於較小的面積。 「區域」像是一個容器,可以在裡面放置子區域或是區塊。以 MVC 架構來說,區域只有 view 的部份。
「區塊」也是網頁中一個較小的區域,但與區域不同的是區塊還具有 MVC 架構中資料內容(model)與互動控制(control)的部份。 一個典型的區塊可能會從資料庫或檔案、或是COIMOTION API service中讀取資料,然後將結果以 HTML 的格式輸出。
所以一個網頁可以把它當作有如這樣的結構: page --> regions --> blocks
組合網頁
在 coServ 上,網頁是組合起來的,開發者不需要自己用程式去把網頁的每個部分串起來。建議的作法是先建立頁型,把網頁區分成幾個主要的區域。 在每個區域中,再填入所需要的內容(區塊)。這裡舉個例來說明。假設你要建置一個「最新消息」的網頁,網頁的左邊有最新消息的列表,網頁的主文區則是某篇消息的詳細內容。 在 coServ 上,你可以這麼處理:
+----------------------------------+
| +------------------------------+ |
| | Head Region | |
| +------------------------------+ |
| +---+ +-----------------------+ |
| | L | | | |
| | e | | | |
| | f | | | |
| | t | | Main | |
| | | | | |
| | R | | Region | |
| | e | | | |
| | g | | | |
| | i | | | |
| | o | | | |
| | n | | | |
| +---+ +-----------------------+ |
+----------------------------------+
也就是設計一個頁型,把網頁切成三個主要的區域。接著假設你已有二個區塊 'news/list' 和 'news/view'。 'news/list' 區塊會從資料來源(資料庫、COIMOTION)讀取最新消息的清單,並以 HTML 製作成列表的形式。 'news/view' 區塊則能夠將某一則最新消息的詳細內容取出並加以顯示。那麼利用上面展示的頁型,把 'news/list' 區塊放到左邊的區域(left region), 把 'news/view' 放進主區域(main region)中,你就已產生一個最新消息的頁面了。
這個模式有趣的地方在於你可以重複利用相同的方法,去產生內容完全不同的網頁,而你完全不需要再去處理網頁編排的問題。 例如你可以將部落格清單放在左區域,部落格本文放在主區域中,你就生成了一個部落格的網頁。把產品清單放在左區域,產品內容說明放在主區域,你又可以生成一個產品網頁。 如此一來你只需專注於方塊內容的產製,而不需為不同的內容一再的去處理網頁版面編排的問題。
這種「重複使用」的模式也可以套用在區域和區塊上,讓你的網站設計工作更進一步的簡化。以下讓我們來說明如何做到這點。
來一段程式碼吧
讓我們用 coServ 下載套件中所附的範例來說明。先找到位於 'www/themes/index/layout/default/page.html' 的預設頁型檔。 這個頁型檔建構了示範網站中所有網頁的基本框架。我們將預設頁型中有關 body 的部份印出來以方便討論:
<body>
<div id="pgContainer">
<div id="pgHead"><% region('./head'); %></div>
<div id="pgLeft"><% region('./left'); %></div>
<div id="pgContent"><% block(); %></div>
<div id="pgFooter"></div>
</div>
</body>
從上面的 HTML 碼可以看出預設頁型是將網頁切割成四個區域:頁首區(#pgHead)、左邊欄(#pgLeft)、主文區(#pgContent)和頁尾區(#pgFooter)。 而頁首區是這麼實作的:
<% region('./head'); %>
這表示我們不想每個頁面都要重做一次頁首的程式碼(HTML 和 CSS),所以我們是引用 './head' 這個區域。而這個頁首區域的定義是在 './head' 這個目錄中(www/themes/index/layout/default/head)。
同樣的,區塊也可以用類似的方法引用進來:
<% block(); %>
上面引用區塊的例子中,我們並未給輸入參數。一般來說,引用區塊是需要輸入參數的,以便 coServ 知道要引用哪一個區塊。 如果沒給參數,則表示要引用使用者輸入的網址所指向的區塊。
定義區域和區塊
看到這裡可能大家已經慢慢了解在 coServ 上建置網站的工作已被簡化到區域和區塊的建置(定義)。 區域其實就是一個 HTML 的片段,所以你可以用一個 HTML 檔再加上一個 CSS檔 (CSS 不一定需要)來實作出一個區域。 不過這裡要指出的是,這二個檔(HTML, CSS)並不是單純的檔案,而是使用 EJS 語法的樣板。 如此一來,開發者在實作時有更大的空間和彈性。
以 MVC 的架構來看,區域只有 view 的部份,然而區域卻有 model, view, control 三個完整的結構。也因此在實作區塊時, 會需要更多的設計檔:HTML, CSS, Javascript, 引用檔、以及多語設定套件。有時候你會用到五個檔欄實作一個區塊,不過多數的時候只需其中的二到三個檔案就足夠了。
更進一步解釋這五個檔案:HTML 和 CSS 樣板是用來實作區塊中 view 的部份,而 Javascript 的樣板則是實作了 control 的功能。 至於引用檔是用來引用額外的 CSS 檔案或是 Javascript 程式庫。這些額外引用的 CSS 或 js 檔會被整合到網頁的 <head> 中。 以下是引用檔的一個範例:
http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css
/shared/js/lib/jquery-1.10.2.min.js
http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js
/shared/js/wFront.js
至於區塊的 Javascript 檔,其實會被 coServ 在外圍做一層包裝,而變成一個物件。此外,這個物件會給予 'ctrl' 的名稱。 在實作區塊的 controller 時,你幾乎可以把它當作 node.js 的模組一般來寫。以下是一個區塊 controller 的範例:
ctrl.startup = function() {
// this function will be called when the block is loaded and rendered
// you can take the chance to initialize the block.
};
ctrl.foo = function() {
// this is a customized function. You can make as many customized functions as you need.
};
// unlike node.js, exports is not needed here.
你可以從 HTML 中用以下的方式來呼叫區塊 controller 中的函式:
<a href="..." onclick="<%=ctrl%>.foo();">Hello There<a>
看到這裡你已經對 coServ 的網頁組合語開發模式有相當的認識了。建議大家可以參考下載檔案所附的 'index' 和 'demoApp' 二個示範網站,去找到更多的範例。