文章篇幅較長,慎入
隨著網絡應用的豐富和發展,網站往往不能迅速跟進大量信息衍生及業務模式變革的腳步,常常需要花費許多時間、人力和物力來處理信息更新和維護工作。 ——引自「百科」
小公司、小網站因人員、技術問題,在內容管理處理上處于「食之無味棄之可惜」的一種情況:內容維護會經常打亂開發人員節奏,但是又沒有精力去思考投入統一去解決類似問題。
有哪些運營內容需要維護
開始之前,我們先看下小網站一般會存在哪些內容需要維護配置:
- 頁面靜態內容,一般用于導流或者介紹:如輪播圖,特色、功能、產品介紹等;
- 全站統一內容:如導航、友情鏈接等;
- 站點新聞公告:包含列表、詳情;
- 其他類似的靜態文檔,用來展示或者介紹公司相關:如幫助、關于我們等;
- 其余無業務功能邏輯,需要人工維護的內容
現狀
遇到這些內容維護,好的小公司可能會一開始就同步建立一個配置發布管理功能,其他的可能因為工期趕就代碼寫死,通過發布解決,發布頻繁了才去做配置發布管理功能。
- 頁面代碼寫死,調整即發布
抓狂
- 每類內容都配套「配置發布管理功能」,需要處理以下內容
- 抽象數據,創建表
- 前端開發相關管理頁面,包含「列表」、「新增編輯」、「表單」功能
- 因為是后臺管理頁面,一般情況這個配置頁面都比較簡單,甚至缺少校驗,只能人肉在線查看效果來決定是否配置正確
作為一個有追求的攻城獅,這樣的重復性工作應該主動拒絕,通過工具或者流程去改善生活
CMS是什么
在很早以前,內容管理就成為一個重要的應用領域,并且伴隨著時間、技術的推移,CMS的功能也變得越來越強大。
CMS簡單來說就是內容管理系統(Content Management System),主要解決用戶網站建設與信息發布中常見的問題和需求,運營同學可以通過它進行網站內容新增、修改、審核發布,提高信息發布效率和準確性;其技術核心思想是分離內容的管理和設計。
業界CMS系統
篇幅原因,這里并不想去對比和介紹業界相關的系統,只是想大概介紹下相關類型
- 傳統CMS系統
- 簡單的小至類似上面提到的「配置發布管理功能」,如公告發布模塊
- 可視化建站,如
- 云鳳蝶:可以基于組件可視化搭建頁面,站點托管在云鳳蝶提供的服務。
- 阿里內部CMS系統:也是基于組件可視化搭建頁面,天貓、淘寶成千上萬的活動頁面都是基于此運營自己選擇相關組件搭建并投放的;
不對外
從小公司的訴求和運營的專業水平來看,類似云鳳蝶這樣的基于組件化搭建頁面的CMS平臺,其操作成本高,另外組件開發、維護成本也很高,小公司也很難有業務發展需求,可以沉淀出自己的組件模塊。所以除非一開始就不打算投入網站服務建設,只是簡單得搭個網站門面,才會使用類似可視化建站服務。
下面的篇幅我們還是以實現「傳統CMS系統」為目標,去考慮如何做得更好
訴求
那么小網站對內容管理又有哪些訴求呢?
- 有一套通用解決方案可以為任意運營內容快速生成「配置發布管理頁面」
- 表單頁面強化校驗,增加體驗
- 盡可能保證內容填寫的正確性,避免線上出現問題
- 統一的數據獲取API,避免重復開發
- 上篇文章提到的jsonschema-form-vue - 自動生成表單庫,就能快速生成體驗一致的表單;
- 通過抽象將內容表設計成一套統一結構,一方面避免每種配置都建表,另一方面也容易提供統一API;
- 關于正確性保障,可以通過 預覽 -> 審核發布流程 提前保障;
不過雖然保證了內容配置管理,但是文章一開始提到的「新聞公共」、「幫助」、「關于我們」這些內容相似、字段一致的頁面,難道每次都要創建類似的配置管理,然后在web應用創建相關頁面,再發布應用嗎?
- 需要提供一套頁面模板機制,通過復制頁面模板,快速復制同類型頁面以及跟它關聯的內容配置;通過這種關聯關系,應用只要通過路由
pageId
去查詢頁面相關的內容,即可避免發布
目標
基于訴求,先明確解決小網站內容管理需要完成的目標
- 內容管理:減少內容運營成本
- 減少內容的維護成本
- 減少應用發布成本
- 通過配置化自動生成「配置表單」,減少開發投入成本
- jsonschema-form-vue
- 可基于頁面模板快速復制、新增頁面
- 保證發布質量、體驗
- 支持預覽、審核發布、回滾
- 支持可視化編輯
- 成本小
- 能容易和現有系統結合
- 考慮投入產出比
分層關系和表設計
通過內容,對數據模型進行抽象,主要分成以下三層:
組件
最底層組件,它包含了基于 jsonschema-form-vue的表單相關配置,可以使用版本管理,讓配置升級更安全。
{
id: Schema.Types.ObjectId,
name: String, // 配置名稱
version: String, // 版本號
jsonSchema: String, // JSONSchema
definition: String, // Form Definition
histories: Array, // 歷史記錄
author: String, // 用戶
createdAt: Date, // 創建時間
modifiedAt: Date // 修改時間
}
模塊
模塊是運營內容編輯單元,基于組件表單配置去生成表單,可以保存草稿和發布數據,用于預覽和線上內容
{
id: Schema.Types.ObjectId,
name: String, // 模塊名稱
title: String, // 模塊標題
siteId: Schema.Types.ObjectId, // 所屬站點ID
pageId: Schema.Types.ObjectId, // 頁面ID
componentId: Schema.Types.ObjectId, // 組件ID
componentVersion: String, // 組件版本號
model: {}, // 配置數據
draft: {}, // 配置草稿
status: Number, // 狀態 0: 配置更新, 1: 內容更新, 2: 發布審核
online: Boolean,
histories: Array, // 歷史記錄
author: String, // 用戶
createdAt: Date, // 創建時間
modifiedAt: Date // 修改時間
}
為什么不把表單配置直接放模塊,而是增加組件這一層? 這主要是因為模塊和組件是「多對一」的關系,一個表單配置可能會被用到多個模塊;另外上面提到的相似頁面,會復制出相似模塊,如果將表單配置放在模塊表中,會存在重復數據,后續也很難同步配置升級
頁面
頁面就是瀏覽器中看到頁面,主要用來保存模塊的關聯關系,一個頁面可能存在多個獨立模塊
{
id: Schema.Types.ObjectId,
name: String, // 頁面名稱
url: String, // 頁面url
realUrl: String, // 頁面實際url
useRoute: Boolean, // 是否啟用路由規則
router: String, // 路由規則
siteId: Schema.Types.ObjectId, // 所屬站點ID
modules: String, // 模塊
owner: String, // 用戶
createdAt: Date, // 創建時間
modifiedAt: Date // 修改時間
}
為什么有url又有實際url?這主要考慮后面的「可視化編輯」功能,需要去請求真實頁面,所以在頁面復制發布時,需要基于「頁面路由」生成實際url
因為數據模型的核心是配置和內容,所以選用了文檔型數據庫
MongoDB
整體設計
抽象了數據模型,先通過設計看下CMS需要提供哪些功能
設計上,CMS遵循以下幾點原則:
- 對現有web應用侵入性、影響最小,方便接入
- 操作簡單,盡量設計簡單,功能明確
- CMS只提供數據服務,不允許用戶流量直接進入,導致需要跟web應用同步擴容
所以:
- 提供組件、模塊、頁面管理功能;
- 提供API讓接入方可以方便獲取數據,但是接入方需要對數據進行緩存,減小對CMS服務的壓力;
- 支持獲取草稿數據,讓web應用支持預覽功能;
- 提供可視化編輯功能,頁面編輯可以可視化預覽編輯線上頁面,實時查看效果,方面查找模塊;
Web應用接入只要改動以下幾點:
- 如果之前沒有數據、結構分離,要先分離,數據源替換成CMS數據;
- 線上數據要進行緩存,減少CMS服務壓力;在服務啟動時讀取CMS內容數據,進行緩存;
- 提供方法讓Controller可以獲取CMS數據;
- 可選擇支持預覽功能,如定義url規則
?preview=true
則實時請求CMS草稿數據; - 提供緩存更新API,在CMS內容審核發布更新時,能更新緩存,不用重啟應用;
- 可選擇接入「可視化編輯腳本」,在使用CMS數據的html模塊進行
moduleId
標識
流程
通過流程可以更清楚了解CMS的功能
- 創建組件配置
前端在本地開發完靜態頁面后,先mock內容,完成數據模板分離;然后可以借助JSON2JSONSchema工具快速生成JSONSchema結構,根據 jsonschema-form-vue文檔,生成組件配置
創建內容模塊,引用相應的組件配置(內容模塊才是運營內容維護單元);如果有初始數據,可以幫運營填入;復制
moduleId
到web應用中調用相應方法獲取CMS數據;然后,發布web應用后,開發的工作就完成了,以后的內容維護都交由運營同學。運營同學維護模塊內容,有兩種方式:
3.1 通過模塊名查找模塊進行編輯
3.2 通過頁面編輯進行可視化編輯,見下面內容編輯確認無誤后,進行保存預覽
預覽確認沒有問題后,審核發布,內容上線
到這里,CMS最基本的功能已經完成了;再也不用因為文案內容改動,需要進行應用發布重啟了
MORE
接下來的篇幅最后介紹「頁面復制」和「可視化編輯」功能
關于頁面復制
上文提到的新聞公告、關于我們,或者一些風格類似的活動頁面,需要提供快捷復制創建新頁面,然后修改頁面內容即可。
主要思考如下:
- 模塊才是內容編輯單元,頁面維護著模塊映射關系,復制頁面的同時復制相應模塊,并更新對應的映射關系即可;
- 提供通過
pageId
獲取數據接口,這樣類似頁面可以通過路由規則params或query
來獲取對應頁面數據渲染;
可視化編輯
最后必須來點看起來科技感滿滿的功能來個收尾,以提供該CMS系統的檔次,直接跟前沿接軌。
在具備了模塊編輯功能后,可視化編輯就是如何獲取編輯的數據并實時渲染頁面預覽,同時預覽頁面可識別可編輯模塊,并表現出自己能被編輯,引起運營點擊修改的欲望:
- 關于實時預覽
上文我們已經提到預覽功能,實時預覽問題不攻而破 - 關于可編輯模塊
要想識別模塊并編輯,必須在HTML Template上標識上moduleId
,然后通過規則識別在CMS系統中引入「可視化編輯.js」,CMS在編輯時通過iframe引入線上頁面,做以下事情:- 識別頁面可編輯模塊,在上面遮上一層編輯DIV,表現出可編輯樣子
- 點擊編輯DIV時,iframe通信,告知CMS編輯模塊,彈出模塊配置
- 編輯保存后,更新iframe時間戳,重新請求頁面,獲取新數據
就這樣,馬上提供一個檔次
到這里,文章就結束了,在工作過程中,多去發現工作流程中,重復性的、自己不喜歡去處理但又不得不去處理的活兒,去思考如何通過工具、流程化去處理它們;讓事情變得簡單、可復制;這個思考和實現的過程,不僅能提升你的設計和技術能力,同時也能增加公司對你的依賴性,走向升職加薪的路上。