在上篇文章所描述的基礎功能,本章采用MVC實現一個輕量的內容發布。
基本原理
文章發布的三要素如下圖所示:
- 欄目——也稱網站頻道可以視為一個樹狀的網站內容逐層分類。一個欄目下包含很多文章,通常一個欄目下的文章采用相同的模版發布,以保持相同的展示形式和風格。
- 文章——包括:題名、內容、作者等元數據的結構化內容。文章可以發布到一個或者多個欄目下。一篇文章綁定一個模版之后會形成一個唯一的URL。如果一篇文章綁定了多個模版,應當會形成多個URL。
-
模版——負責內容的展示形式,綁定文章(本例中為數據庫表Article中的一條記錄),render出最終的頁面效果。
內容發布三要素
Model:數據庫表及對應的Entity
- article表用于文章;
- tag表用于文章分類標簽;
- attach表用于上傳圖片或者附件;
View:管理界面提供結構化數據維護,模版實現內容展示
網站欄目的管理
欄目信息非常適合用json樹描述,用json的好處是維護方便,而且可以直接提供給后臺界面用于發布欄目的多選。
用戶選擇發布的欄目之后,直接以簡單的格式分隔存到一個文本字段即完成了文章發布,用戶體驗是不是夠簡單?
當然如果業務要求對發布內容進行審查,默認的狀態可以是預覽,后期也可通過置頂設置調整文章在頻道首頁的位置。
-
同時json定義也供后臺java邏輯解析,以獲得指定欄目對應的模版。
網站欄目 如果在該json中通過
tpl
指定了欄目模版,發布到該欄目的文章將使用指定模版,否則使用默認模版。
網站欄目json可指定欄目模版
模版
模版采用JSP EL或JSTL,只負責將傳入的model在頁面中進行展示,不含其他邏輯。
此處也曾猶豫是否引入模版組件,最終SpringSide作者的見解影響了我,模版引擎怎么說相對jsp來說也是小眾,
JSP完全勝任模版引擎任務,如果不考慮前端工程師的偏好,沒必要再引入其他模版引擎,增加程序員的麻煩和系統復雜度。
以下為模版中顯示文章相關圖片的代碼片段:
<c:forEach items="${robjs}" var="ro">
<c:choose>
<c:when test="${ro.suffix =='jpg' || ro.suffix =='png' || ro.suffix =='jpeg' }">
<figure class="figure">

<figcaption style="text-align:center;color:rgb(153, 153, 153);">${ro.title}</figcaption>
</figure>
<p><br></p>
<p>${ro.content}</p>
</c:when>
</c:choose>
</c:forEach>
Controller:三個java類
- CMSController用于將發布生成的url 映射為模版+數據;
- SecNode.java用于加載json節點到后端;
- CMSService.java封裝具體的實現邏輯。
CMSController.java
采用SpringMVC的映射注解可以輕松將上述URL匹配到負責綁定模版和數據的處理邏輯。
@RequestMapping(value = PATH_ARTICLE + "{id_tpl}", method = RequestMethod.GET)
public String showDetailByTpl(@PathVariable("id_tpl") String id_tpl, Model model) {
try {
String[] prs = id_tpl.split("_");
long id = Long.parseLong(prs[0]);
Article obj = cmsService.getArticle(id);
// TODO 檢查status 狀態, 只允許管理員預覽
model.addAttribute("obj", obj);
String tpl;
if (prs.length == 1) {
tpl = TPL_DEFAULT;
} else {
tpl = prs[1];
}
// 根據頻道綁定多個文章模版
return "tpl" + PATH_ARTICLE + tpl;
} catch (Exception e) {
e.printStackTrace();
return "error/404";
}
}
CMSService.java + SecNode.java 實現預覽
java中解析json文件,獲得指定欄目的文章模版。
基本思路如下:
- 定義與json節點對應的java類SecNode
- 利用ObjectMapper讀取json文件并解析為SecNode[]
- 遍歷SecNode[],建立欄目全路徑名稱對應的模版文件名,
例如:用戶中心#辦理流程-> 1.jsp ; 政策法規->default.jsp - 前臺Ajax請求主鍵值1的文章,發布對應的URL
- 后臺根據主鍵值從數據庫提取Article對象,得到其發布欄目為:政策法規;用戶中心#辦理流程 兩個欄目
- 根據欄目獲得對應的模版,如果欄目在json節點通過tpl定義了模版,則采用指定模版,否則沿用父節點模版。
- 根據模版和文章id 按URL定義規則拼接出URL數組,返回前端
- 前端拿到URL數組之后,采用tab窗口打開對應的兩個頁面預覽。
內容管理界面
支持點擊修改附件名
內容管理界面
發布結果
由于模版也符合decorators.xml
定義的layout規則,所以最終呈現的詳細頁包含了網站的header和footer。
發布結果(局部截圖)