歡迎來到「精通 Grails」系列的第二年。延續上一年的 Trip Planner,這次我們將打造一個名為 Blogito 的部落格發布系統。Blogito 在西班牙語意為「小部落格」,也向笛卡兒的「我思故我在」致敬。完整應用程式可從 blogito.org 下載,接下來幾篇文章將逐步建構核心功能。
本文基於 Grails 1.1(撰寫時為 beta 版)。Grails 最佳運行於 Java 1.5 或 1.6。安裝步驟簡單:下載 grails.zip、解壓縮、設定 GRAILS_HOME 環境變數並加入 PATH。若需在同一機器管理多版本 Grails,Unix/Linux/Mac 可用符號連結切換 GRAILS_HOME 指向的目錄;Windows 則直接修改 %GRAILS_HOME% 並重啟命令提示字元。執行 grails -version 驗證安裝。
執行 grails create-app blogito 產生目錄結構,再以 grails create-domain-class Entry 建立部落格文章的領域類別。在 grails-app/domain/Entry.groovy 定義標題、摘要、建立時間與更新時間欄位,並設定 summary 最大長度 1000 字元,自動在表單產生文字區域。dateCreated 和 lastUpdated 是 Grails 魔法欄位,會自動記錄時間戳記,非常適合部落格排序。
建立 EntryController 並加入 def scaffold = Entry,Grails 即會自動產生列表、新增、編輯、刪除等完整 CRUD 功能。執行 grails run-app 並瀏覽 https://localhost:8080/blogito 即可見到運作中的應用程式。但預設產生的表單包含時間戳記欄位,使用者不應手動編輯,需調整模板排除這些欄位。
執行 grails install-templates 將預設模板複製到專案。編輯 src/templates/scaffolding/create.gsp 與 edit.gsp,在 excludedProps 陣列加入 'dateCreated' 和 'lastUpdated'。重啟應用程式後,表單不再顯示這兩個欄位。
部落格通常以最新文章優先顯示。Grails 1.1 引入靜態映射區塊的 sort 屬性,直接在 Entry.groovy 加入 static mapping = { sort "lastUpdated":"desc" } 即可,無需修改控制器,保持 def scaffold 的簡潔性。
開發模式下每次重啟資料庫會重建,資料會遺失。編輯 grails-app/conf/BootStrap.groovy,在 init 閉包中判斷環境為 development 時建立範例文章。重啟後列表即會出現預設資料,方便開發測試。
執行 grails generate-views Entry 產生 GSP 檔案。修改 list.gsp,移除預設表格改用垂直卡片式佈局:每篇文章以 <div class="entry"> 包裹,日期、標題、摘要分別置於 <span class="entry-date">、<h2>、<p> 中。在 web-app/css/main.css 加入簡單樣式(.entry 間距、.entry-date 灰色),介面立刻煥然一新。
為了讓日期更易讀,建立 DateTagLib 提供 <g:longDate> 標籤,支援自訂格式(預設「EEEE, MMM d, yyyy」)。在 list.gsp 套用此標籤,日期即以「Wednesday, Jan 14, 2009」等友善格式顯示。
將文章顯示邏輯抽離為 _entry.gsp 局部模板,在 list.gsp 與 show.gsp 中以 <g:render template="entry" bean="${entryInstance}" /> 引用,確保一致性並減少重複程式碼。
Grails 使用 SiteMesh 佈局,編輯 grails-app/views/layouts/main.gsp 引入 _header.gsp 局部模板,取代預設 Grails Logo。_header.gsp 包含連結回首頁的「Blogito」標題與副標題,並以 CSS 設定深藍背景、白色大字體。為了安全,導航列(新增、首頁按鈕)以 <g:if test="${session.user}"> 包裹,僅登入使用者可見。分頁按鈕移至 <div class="paginateButtons"> 並加上 clear: left 固定於底部。
編輯 grails-app/conf/UrlMappings.groovy 加入 "/"(controller:"entry"),將根路徑導向 EntryController,完成部落格首頁設定。
本文展示如何以 CSS、局部模板、TagLib、Scaffold 模板調整、靜態映射排序、BootStrap 測試資料等技術,快速打造擁有專屬外觀的 Grails 應用程式。下一篇將加入使用者驗證、多使用者發文、Grails 編解碼器與進階 URL 映射,敬請期待。