Go-Pages
========
熟悉 [GitHub Pages][1] 的讀者, 看到 Go-Pages 已經想到 **靜態博客** 這個詞了. TypePress 從靜態博客起步, 一點點邁進帶數據庫的博客系統. Github 的 Pages 功能已經提出了實用簡潔的靜態博客方案, [jekyllrb][2] 引擎為其提供強勁動力. Jekyll 給出了很好的文檔規范, 可以直接借鑒其目錄結構. Liquid 模板也有 Go 實現 [Liquid Template Engine for Go][3]. Go-Pages 盡可能兼容 Jekyll, 不能兼容的部分以后制作轉換工具進行處理. 為此需要準備一些 package.
## RootPath
[rootpath][4] 為多域名服務器綁定目錄的 package. 效果上有點像 URLRewrite 的一個子集. 僅對 `http.Request.Host` 進行分析, 匹配成功設定相應的靜態文件目錄, 內容目錄, 模板目錄. 匹配失敗拒絕訪問或者不做任何操作.
RootPath 讓 Go-Pages 博客支持子域名(站群)或者 CNAME (綁定域名)支持.
## static
[static][5] 在設定好的靜態文件目錄下, 響應 `URL.Path` 請求的靜態文件, 嘗試發送對應的 Gzip 預壓縮文件 `pathto/URL.Path.gz`. 如果沒有找到 static 不產生 404 , 它什么都不做.
不產生 404 有很多好處. 基于 Martini 的 Handler 一旦產生輸出就會結束響應過程, 不產生 404 就可以繼續進行處理, 比如自定義 404 頁面, 比如進行動態 Gzip 壓縮, 然后再交給 static 進行輸出, 又或者那根本就不是個靜態頁面, 交給后續的 Handler 處理, 如果最終無法匹配, Martini 會執行 `http.NotFound`.
## Liquid
[Liquid][6] 包提供了基本 Liquid 模板支持. Jekyll 對 liquid 其進行了一些擴展, 如果要完全兼容 Jekyll 是個龐大的工程. 但是, 有必要實現一些如 [Global Variables][7] 之類的. 用到的時候再分析.
特別的, Liquid 中的 `include` tag 需要使用者自己實現 `IncludeHandler`, 參見 `liquid.Configuration`的接口.
## MarkDown
輕量文本標記語言可以讓書寫者專注文章內容, 而不是為版式費神, 很適合書寫博客. 有多種格式可選. Go-Pages 暫時支持最簡單的 MarkDown 格式, 在前后端都要有所支持.
前端支持 MarkDown 的編輯器很多, [markdown-editor][8] 是比較簡單的一個. [blackfriday][9] 是 Go 語言下的 MarkDown 解析器. 前端的博客文章編輯和提交這里不討論了.
## JingYes
前端 CSS 框架更是有太多選擇, 當前比較受歡迎的當屬 BootStrap 和 PureCSS. Go-Pages 使用 [JingYes][10]. 這里不再列舉可能用到的其他前端庫.
JingYes只支持現代的瀏覽器, 不過 html 源代碼非常簡潔, 可以很方便的改寫成其它 CSS 框架.
## TOML
配置文件采用 TOML 格式, 這里分析幾個 `table`.
**defalut**
[defalut]
# 安全密匙, 請妥善保管, 切勿外泄.
# 受密匙的具體使用影響, 更改密匙可能會造成不可預計的破壞.
secret = ""
# 主站頂級域名
domain = ""
# 本地監聽地址
laddr = ":80"
# 共享靜態文件目錄
static = "pages/defalut"
# 內容目錄是獨立的, 需要在 [[rootpath]] 中設置
content =""
# 共享模板文件目錄
template = "pages/defalut/_layouts"
作為多域名博客系統有些 css,js,image 資源文件是可以共享的, static 目錄起到這個作用. 但是, 可以預計, 很可能會把 MarkDown 文章源文件預渲染成 html 文件, 它也是靜態文件, 他們所屬的 base 目錄是不同的. `static` package 不產生 404 的方式很好的解決了這個問題. Go-Pages 可以這樣做(m 是 Martini 對象):
```go
// 設定 defalut.static dir
m.Map(http.Dir(core.Conf["defalut.static"].String()))
m.Use(staticDefalutHandler) // defalut static 優先
m.Use(rootPathHandlerForDomain) // 這個一旦執行 root 就改變了
m.Use(staticHandlerForDomain) // 現在訪問的靜態文件就是站點的了
```
**rootpath**
[[rootpath]]
Flag = 1 # 1 == FStatic, 每個域名都可以獨立有靜態文件
Root = "pages/domain"
Pattern = "*"
Domain = "localhost"
CategoryName = ["_site"] # Jekyll 的習慣用 _site 目錄, 下述同理
[[rootpath]]
Flag = 2 # 2 == FContent, 每個域名都有獨立的 content
Root = "pages/domain"
Pattern = "*"
Domain = "localhost"
CategoryName = ["", "_posts"]
[[rootpath]]
Flag = 4 # 4 == FTemplate, 嘗試獨立的 _layouts
Root = "pages/domain"
Pattern = "?"
Domain = "localhost"
CategoryName = ["", "", "_layouts"]
上述幾個 package 給 Go-Pages 提供了最基礎的動力. 流程也基本確定, coding...
[1]: https://pages.github.com/
[2]: http://jekyllrb.com/docs/structure/
[3]: https://github.com/karlseguin/liquid
[4]: https://github.com/typepress/rootpath
[5]: https://github.com/typepress/static
[6]: https://github.com/karlseguin/liquid
[7]: http://jekyllrb.com/docs/variables/
[8]: https://github.com/jbt/markdown-editor
[9]: https://github.com/russross/blackfriday
[10]: https://github.com/achun/JingYes