利用 Gitbook 生成文檔中心站點(diǎn)
經(jīng)過(guò)一個(gè)多月,Bugtags 最近上線了自己的文檔站點(diǎn)(docs.bugtags.com),在這里你可以找到 Bugtags 集成、使用相關(guān)的絕大部分問(wèn)題。
在這之前我們使用的是第三方提供的幫助中心產(chǎn)品服務(wù),在他們網(wǎng)站后臺(tái)上面編輯文檔內(nèi)容,建立自己的文檔體系的;但是用久了發(fā)現(xiàn)還是用很多不爽的地方,起碼是不符合我們的習(xí)慣;
比如:該產(chǎn)品文檔是使用富文本形式編輯和存儲(chǔ)在數(shù)據(jù)庫(kù)的;而我們自己都非常喜歡于用 Markdown 格式編寫文檔;而數(shù)據(jù)庫(kù)保存也注定無(wú)法使用 git 來(lái)進(jìn)行文檔的版本管理和控制;
幫助中心頁(yè)面的樣式只有默認(rèn)的幾套,盡管提供了模板設(shè)計(jì)功能,但其實(shí)也非常雞肋,完全無(wú)法滿足我們的自定制需求。基于此我們嘗試尋找其他的方案解決這個(gè)問(wèn)題。
我們的需求
我們首先想明白我們需要什么樣的文檔管理系統(tǒng);
1、 使用 Markdown 來(lái)撰寫文檔,所謂「無(wú) Markdown,不文檔」;我們工程師都習(xí)慣于使用 Markdown 來(lái)撰寫文檔,甚至我司唯一不會(huì)技術(shù)的美女靜靜都表示:「文檔怎么可以不是 Markdown 的呢!」就剛剛催稿時(shí)她還說(shuō):「必須是 Markdown 啊,不然我不收的」。
2、 生成的網(wǎng)站純靜態(tài),這樣才會(huì)速度快。在起初我們也想過(guò)兩種方案,一是把 Markdown 文件下載到前端,在前端渲染成 HTML;另一種方案是在后端把所有 Markdown 生成 HTML,前端瀏覽時(shí)直接加載 HTML。經(jīng)過(guò)考慮,還是得采取后一種。如果前一種,讓每一個(gè)終端用戶都要耗費(fèi)資源來(lái)渲染 Markdown,實(shí)在浪費(fèi);而且速度無(wú)法保障。而后一種思路就很清晰了:首先寫Markdown文檔,文檔寫完后全部生成靜態(tài)網(wǎng)站,這樣終端用戶訪問(wèn)的全部都是靜態(tài)的 HTML 頁(yè)面了。
3、 git 管理。這個(gè)應(yīng)該無(wú)需多言了吧。文檔的更新升級(jí),必須要有一個(gè)強(qiáng)大的版本管理系統(tǒng),這個(gè)非 git 莫屬了。
在一系列嘗試之后,我們開(kāi)始采用 Gitbook 并對(duì)他進(jìn)行改寫,來(lái)生成起自己的文檔中心站點(diǎn)。
Gitbook 簡(jiǎn)介
Gitbook 是一個(gè)電子書制作程序;它把組織起來(lái)的 Markdown 文件按照層次生成電子書;這個(gè)電子書的格式可以是 epub、mobi、pdf,甚至還可以是一個(gè)網(wǎng)站;
它的使用也是非常簡(jiǎn)單,基本上只有兩步:
使用
gitbook init命令,會(huì)根據(jù)文件SUMMARY.md中的內(nèi)容來(lái)生成書籍目錄結(jié)構(gòu);使用
gitbook build把書籍生成你需要的格式。
然后所有的書籍配置都可以通過(guò)根目錄下的 book.json 文件來(lái)定義。
關(guān)于 Gitbook 較詳細(xì)的使用方法,可以參考 Gitbook 簡(jiǎn)明教程,這個(gè)網(wǎng)站本身也是由 Gitbook 來(lái)生成的。
采用 Gitbook 的原因
Gitbook 與我們的需要匹配較強(qiáng),有以下幾點(diǎn):
開(kāi)源。作為一個(gè)初創(chuàng)小企業(yè),我們的很多項(xiàng)目受益于開(kāi)源產(chǎn)品。有很多第三方的插件來(lái)推動(dòng)這個(gè)產(chǎn)品發(fā)展;
Markdown 格式撰寫文檔;
目錄結(jié)構(gòu)清晰;我們可以把所有的 Markdown 文檔按照不同的主題歸集到不同的目錄層次下;
生成的網(wǎng)頁(yè)純靜態(tài)。Gitbook 是可以把所有的 Markdown 文檔生成靜態(tài)的 HTML 頁(yè)面;
由于所有的內(nèi)容都是 Markdown 文件,所以就可以使用 git 來(lái)進(jìn)行版本管理和控制了;
在服務(wù)器上安裝 Gitbook 后,定制一個(gè)
git hook腳本,就可以在每次文檔更新提交后自動(dòng)生成網(wǎng)站;
Gitbook 不適應(yīng)我們需求的地方
Gitbook 本身的理念是把 Markdown 文件組織成一本書的概念;這與我們需要做的一個(gè)網(wǎng)站還是有些不太一樣的;所以會(huì)有很多需要改變的地方。
你看我們的網(wǎng)站跟任意一個(gè) Gitbook 默認(rèn)生成的站點(diǎn)對(duì)比,比如 Gitbook 官方的幫助文檔站點(diǎn) ,會(huì)發(fā)現(xiàn)很多不一樣;具體來(lái)說(shuō),我們修改下面這些東西:
- 目錄生成邏輯;
- 插件使用;
- 搜索;
- 模板樣式。
目錄生成邏輯
我們?cè)贕itbook 的模板中添加了頁(yè)頭、頁(yè)腳。頁(yè)面目錄的樣式也不一樣:這個(gè)可不只是展現(xiàn)形式不一樣了。細(xì)心翻閱會(huì)發(fā)現(xiàn),在我們的文檔網(wǎng)站中,有一些文檔并沒(méi)有出現(xiàn)在目錄里。比如有很多繁瑣的常見(jiàn)問(wèn)題;如果每一篇都要放到目錄里,目錄會(huì)變得很冗長(zhǎng)。這些就得改變 Gitbook 默認(rèn)的目錄菜單的生成邏輯了。
我們是這么做的:在 SUMMARY.md 文件(這個(gè)文件中的內(nèi)容來(lái)定義目錄結(jié)構(gòu))中專門定義一個(gè)層次,這個(gè)層次名稱叫做 hide-docs,類似于這個(gè)樣子:
- [hide-docs]()
- [集成 iOS SDK 看不到懸浮球?](faq/ios/icon-not-found.md)
- [用 CocoaPods 集成無(wú)法獲取最新版的 SDK?](faq/ios/cocoapods-sdk-update.md)
- [手動(dòng)集成 SDK 添加 -ObjC 導(dǎo)致編譯出錯(cuò)?](faq/ios/integrate-manual-build-error.md)
- [集成 SDK 后,編譯產(chǎn)生了很多警告?](faq/ios/integrate-build-warning.md)
這個(gè)層級(jí)下的所有文檔都是不需要出現(xiàn)在目錄下的!然而,Gitbook 照樣會(huì)讀取這個(gè)層次下的文檔,所以我們要在生成目錄的邏輯中,稍微改寫:判斷如果是 hide-docs 這個(gè)層級(jí)下的文檔,就不生成目錄。
這個(gè)就得改寫 Gitbook 程序中的 website.js 文件中的 _writeTemplate 方法,我們的代碼是這樣:
if( !this.replacedSummary){
this.replacedSummary = {chapters:[]};
if( that.book.summary && that.book.summary.chapters && that.book.summary.chapters.length ){
var chapters = that.book.summary.chapters;
for(var i =0; i < chapters.length;i++){
var cur = chapters[i];
if(/hide-docs/.test(cur.title)){
continue;
}
this.replacedSummary.chapters.push(cur);
}
}
}
然后將該方法返回對(duì)象的 summary 屬性指定為我們篩選過(guò)的 replacedSummary 變量。這樣再運(yùn)行gitbook build,就會(huì)發(fā)現(xiàn)所有的 Markdown 都被生成了 HTML,然而生成的 HTML 頁(yè)面中的目錄不包含這些我們需要隱藏的文檔。
插件禁用
Gitbook 默認(rèn)啟用了搜索,字體調(diào)整等 5 個(gè)插件,但是我們是不需要這些;所以需要通過(guò)在 book.json 中指定 plugins 屬性為如下:
{
"plugins":["-sharing","-livereload","-search","-fontsettings"]
}
用減號(hào)表示不啟用這些插件(這種配置方法官方幫助文檔居然沒(méi)提)。
搜索
接下來(lái)重點(diǎn)的部分就是搜索了,因?yàn)?Gitbook 官方的搜索根本不支持中文搜索,所以我們禁用了它,盡管有開(kāi)源的支持中文的搜索插件,但是搜索結(jié)果的展示都是非常不直觀;這些都需要從模板以及搜索引擎兩方面來(lái)改進(jìn)。
文檔搜索我們最后采用的是強(qiáng)大 elasticsearch 來(lái)提供全文搜索服務(wù),并且配合修改模板來(lái)顯示搜索結(jié)果。關(guān)于 elasticsearch,這是個(gè)更復(fù)雜的話題了;這里不單說(shuō),有興趣的朋友可以搜索相關(guān)教程。
模板
由于 Gitbook 是把 Markdown 組織成一本書的概念;對(duì)一本書來(lái)說(shuō),除了封面就是目錄以及目錄組織起來(lái)的正文。
而我們需要的是一個(gè)文檔網(wǎng)站,不僅需要文檔內(nèi)容頁(yè)面,還需要其他的頁(yè)面, 比如首頁(yè),搜索頁(yè)面, 404 頁(yè)面,可能還需要其他的頁(yè)面。這時(shí)候我不禁非常懷念 jekyll 這個(gè)靜態(tài)博客生成工具,它會(huì)把根目錄所有的 HTML 文件找到其對(duì)應(yīng)模板嵌套生成 HTML 頁(yè)面。
然而 jekyll(以及我另外嘗試過(guò)的 hexo)的缺陷是組織 Markdown 文檔的方式都比較扁平;是通過(guò)在每一個(gè) Markdown 文檔的首部定義目錄、標(biāo)簽來(lái)定義其邏輯層次,而其生成的物理層次則是通過(guò)文件名中的日期來(lái)定義的。這是個(gè)最大缺陷。
目前我是用了比較野蠻的方式來(lái)解決這個(gè)問(wèn)題:
- 首頁(yè):Gitbook 支持多語(yǔ)言,并且如果定義了多語(yǔ)言會(huì)有一個(gè)模板頁(yè)面來(lái)生成一個(gè)首頁(yè),來(lái)選擇語(yǔ)言入口;所以我就把這個(gè)本應(yīng)作為語(yǔ)言選擇入口的頁(yè)面當(dāng)成我們的首頁(yè);恩,就是你現(xiàn)在進(jìn)去看到的那個(gè)頁(yè)面。
- 404 頁(yè)面:自己寫了一個(gè) 404,在每次重新生成網(wǎng)站的時(shí)候單獨(dú)把這個(gè)文件拷到根目錄下;感覺(jué)很傻呢……
- 搜索頁(yè)面:每一個(gè)內(nèi)容頁(yè)都可以是搜索頁(yè);因?yàn)槲沂前阉阉鹘Y(jié)果顯示在當(dāng)前頁(yè)面的內(nèi)容區(qū)域;這樣就可以局部刷新來(lái)展示頁(yè)面結(jié)果;而不需要單獨(dú)做一個(gè)模板頁(yè)面了。
成果
最后,我們采用了 Gitbook 符合我們需求的部分,把不適應(yīng)的上面幾點(diǎn)想方設(shè)法解決了之后,就形成了我們現(xiàn)在的文檔中心站點(diǎn)。
平時(shí)發(fā)布也是非常方便;直接編寫 Markdown 文件,寫完提交到服務(wù)器。在服務(wù)器端設(shè)置了 git hook 鉤子,每次有文檔更新時(shí),都會(huì)自動(dòng)重新生成靜態(tài)網(wǎng)站,重新生成搜索索引。你有什么關(guān)于 Bugtags 使用方面的問(wèn)題,都可以先去這里查閱一下,歡迎訪問(wèn)哦。
