如何解決小網站內容管理問題

okbeng03發表於2019-03-27

文章篇幅較長,慎入

隨著網路應用的豐富和發展,網站往往不能迅速跟進大量資訊衍生及業務模式變革的腳步,常常需要花費許多時間、人力和物力來處理資訊更新和維護工作。 ——引自「百科」

小公司、小網站因人員、技術問題,在內容管理處理上處於「食之無味棄之可惜」的一種情況:內容維護會經常打亂開發人員節奏,但是又沒有精力去思考投入統一去解決類似問題。

有哪些運營內容需要維護

開始之前,我們先看下小網站一般會存在哪些內容需要維護配置:

  • 頁面靜態內容,一般用於導流或者介紹:如輪播圖,特色、功能、產品介紹等;
  • 全站統一內容:如導航、友情連結等;
  • 站點新聞公告:包含列表、詳情;
  • 其他類似的靜態文件,用來展示或者介紹公司相關:如幫助、關於我們等;
  • 其餘無業務功能邏輯,需要人工維護的內容

現狀

遇到這些內容維護,好的小公司可能會一開始就同步建立一個配置釋出管理功能,其他的可能因為工期趕就程式碼寫死,通過釋出解決,釋出頻繁了才去做配置釋出管理功能。

  • 頁面程式碼寫死,調整即釋出 抓狂
  • 每類內容都配套「配置釋出管理功能」,需要處理以下內容
    • 抽象資料,建立表
    • 前端開發相關管理頁面,包含「列表」、「新增編輯」、「表單」功能
  • 因為是後臺管理頁面,一般情況這個配置頁面都比較簡單,甚至缺少校驗,只能人肉線上檢視效果來決定是否配置正確

作為一個有追求的攻城獅,這樣的重複性工作應該主動拒絕,通過工具或者流程去改善生活

CMS是什麼

在很早以前,內容管理就成為一個重要的應用領域,並且伴隨著時間、技術的推移,CMS的功能也變得越來越強大。

CMS簡單來說就是內容管理系統(Content Management System),主要解決使用者網站建設與資訊釋出中常見的問題和需求,運營同學可以通過它進行網站內容新增、修改、稽核釋出,提高資訊釋出效率和準確性;其技術核心思想是分離內容的管理和設計。

業界CMS系統

篇幅原因,這裡並不想去對比和介紹業界相關的系統,只是想大概介紹下相關型別

  • 傳統CMS系統
    • 簡單的小至類似上面提到的「配置釋出管理功能」,如公告發布模組
  • 視覺化建站,如
    • 雲鳳蝶:可以基於元件視覺化搭建頁面,站點託管在雲鳳蝶提供的服務。
    • 阿里內部CMS系統:也是基於元件視覺化搭建頁面,天貓、淘寶成千上萬的活動頁面都是基於此運營自己選擇相關元件搭建並投放的;不對外

從小公司的訴求和運營的專業水平來看,類似雲鳳蝶這樣的基於元件化搭建頁面的CMS平臺,其操作成本高,另外元件開發、維護成本也很高,小公司也很難有業務發展需求,可以沉澱出自己的元件模組。所以除非一開始就不打算投入網站服務建設,只是簡單得搭個網站門面,才會使用類似視覺化建站服務。

下面的篇幅我們還是以實現「傳統CMS系統」為目標,去考慮如何做得更好

訴求

那麼小網站對內容管理又有哪些訴求呢?

  • 有一套通用解決方案可以為任意運營內容快速生成「配置釋出管理頁面」
  • 表單頁面強化校驗,增加體驗
  • 儘可能保證內容填寫的正確性,避免線上出現問題
  • 統一的資料獲取API,避免重複開發
  • 上篇文章提到的jsonschema-form-vue - 自動生成表單庫,就能快速生成體驗一致的表單;
  • 通過抽象將內容表設計成一套統一結構,一方面避免每種配置都建表,另一方面也容易提供統一API;
  • 關於正確性保障,可以通過 預覽 -> 稽核釋出流程 提前保障;

不過雖然保證了內容配置管理,但是文章一開始提到的「新聞公共」、「幫助」、「關於我們」這些內容相似、欄位一致的頁面,難道每次都要建立類似的配置管理,然後在web應用建立相關頁面,再發布應用嗎?

  • 需要提供一套頁面模板機制,通過複製頁面模板,快速複製同型別頁面以及跟它關聯的內容配置;通過這種關聯關係,應用只要通過路由pageId去查詢頁面相關的內容,即可避免釋出

目標

基於訴求,先明確解決小網站內容管理需要完成的目標

  • 內容管理:減少內容運營成本
    • 減少內容的維護成本
    • 減少應用釋出成本
  • 通過配置化自動生成「配置表單」,減少開發投入成本
  • 保證釋出質量、體驗
    • 支援預覽、稽核釋出、回滾
    • 支援視覺化編輯
  • 成本小
    • 能容易和現有系統結合
    • 考慮投入產出比

分層關係和表設計

通過內容,對資料模型進行抽象,主要分成以下三層:

如何解決小網站內容管理問題

元件

最底層元件,它包含了基於 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的功能

如何解決小網站內容管理問題

  1. 建立元件配置 前端在本地開發完靜態頁面後,先mock內容,完成資料模板分離;然後可以藉助JSON2JSONSchema工具快速生成JSONSchema結構,根據 jsonschema-form-vue文件,生成元件配置

如何解決小網站內容管理問題

  1. 建立內容模組,引用相應的元件配置(內容模組才是運營內容維護單元);如果有初始資料,可以幫運營填入;複製moduleId到web應用中呼叫相應方法獲取CMS資料;然後,釋出web應用後,開發的工作就完成了,以後的內容維護都交由運營同學。

  2. 運營同學維護模組內容,有兩種方式: 3.1 通過模組名查詢模組進行編輯 3.2 通過頁面編輯進行視覺化編輯,見下面

  3. 內容編輯確認無誤後,進行儲存預覽

  4. 預覽確認沒有問題後,稽核釋出,內容上線

到這裡,CMS最基本的功能已經完成了;再也不用因為文案內容改動,需要進行應用釋出重啟了

MORE

接下來的篇幅最後介紹「頁面複製」和「視覺化編輯」功能

關於頁面複製

上文提到的新聞公告、關於我們,或者一些風格類似的活動頁面,需要提供快捷複製建立新頁面,然後修改頁面內容即可。

主要思考如下:

  • 模組才是內容編輯單元,頁面維護著模組對映關係,複製頁面的同時複製相應模組,並更新對應的對映關係即可;
  • 提供通過pageId獲取資料介面,這樣類似頁面可以通過路由規則params或query來獲取對應頁面資料渲染;

視覺化編輯

最後必須來點看起來科技感滿滿的功能來個收尾,以提供該CMS系統的檔次,直接跟前沿接軌。

在具備了模組編輯功能後,視覺化編輯就是如何獲取編輯的資料並實時渲染頁面預覽,同時預覽頁面可識別可編輯模組,並表現出自己能被編輯,引起運營點選修改的慾望:

  • 關於實時預覽 上文我們已經提到預覽功能,實時預覽問題不攻而破
  • 關於可編輯模組 要想識別模組並編輯,必須在HTML Template上標識上moduleId,然後通過規則識別在CMS系統中引入「視覺化編輯.js」,CMS在編輯時通過iframe引入線上頁面,做以下事情:
    • 識別頁面可編輯模組,在上面遮上一層編輯DIV,表現出可編輯樣子
    • 點選編輯DIV時,iframe通訊,告知CMS編輯模組,彈出模組配置
    • 編輯儲存後,更新iframe時間戳,重新請求頁面,獲取新資料

就這樣,馬上提供一個檔次

到這裡,文章就結束了,在工作過程中,多去發現工作流程中,重複性的、自己不喜歡去處理但又不得不去處理的活兒,去思考如何通過工具、流程化去處理它們;讓事情變得簡單、可複製;這個思考和實現的過程,不僅能提升你的設計和技術能力,同時也能增加公司對你的依賴性,走向升職加薪的路上。

相關文章