Comment.js:一個純JS實現的靜態站點評論系統
前言
我的博客最早是使用 Disqus 來實現評論功能的。Disqus 被牆了之後,改成了多說。今年年初,多說也正式關閉了,於是我被逼著又開始尋找其他的替代評論系統。
我先是試用了網易雲跟貼、暢言等幾種類似的社會化評論系統。暢言要求站點必須備案,而我實在沒有為了評論去申請備案的動力。網易雲跟貼的管理後台上有很多不明覺厲的功能,但好像都沒多大用處。最致命的問題是我不小心把我的站點綁定到了另一個網易賬戶,而不是我常用的微博賬戶。這樣的話,我每次回貼就得退登到微博賬戶,要管理貼子的時候又得切回管理員賬戶,非常不方便。然而網易雲跟貼並沒有提供解綁的功能。於是我給他們提了需求,然而一直到現在都沒有回復。再加上有了多說作為前車之鑒,我對國內的免費評論服務已經失去了信心。今天把A換成B,難以保證日後B也關閉了,被逼著又換到C,實在是懶得折騰下去啊。於是,我放棄了換用類似的評論系統的念頭。
之後我找到了isso項目,它是一個 Python 實現的開源評論服務。這個服務需要搭建在自己的伺服器上。官方的簡介簡明扼要:「a Disqus alternative」。出於對 Python 的好感,我把站點的評論功能遷移到了 isso 。然而,我對 isso 也並不是很滿意。首先它的功能其實也非常弱,不支持 Markdown 語法,不支持 Gravatar 頭像,也沒有一個像樣的管理後台,搭建和配置的過程也比較費時,遠達不到開箱即用的程度。再加上 isso 需要伺服器運營,為了一個評論系統而去購買伺服器確實太奢侈了。用了幾個月後,我又萌生了換掉它的念頭。
項目介紹
我的想法來源於一些基於 Github issue 的博客。其實 Github 的 issue 本身就是一個非常完善的評論系統,有完善的管理後台,靈活的通知設置,而且 Github 是開放 API 的。只要我能把 Github 的 issue 與博客的頁面打通,把 issue 上的內容顯示在我的博客上,然後在需要評論的時候點擊跳轉到 Github 的 issue 頁,就實現了一個基本可用的評論系統了。
comment.js 就是基於這個想法實現的一個評論系統,它的核心代碼只有 400 行左右,卻能夠用來實現評論會話和最新評論列表的兩個功能。比起已有的社會化評論系統,它有如下幾個優點:
完善的評論管理系統。基於 issue 的評論,支持 Markdown ,支持 Gravatar。
開箱即用的郵件通知功能。Github 的郵件通知功能非常完善,不像 isso 那樣還得配置郵件通知服務。
無需搭建後台。直接用現成的 issue 作為後端,不像 isso 那樣還需要自己搭個後台,搞定資料庫。
接入簡單。獲取評論會話和獲取最新列表各自對應一個函數。
代碼簡單。這意味著你也可以很快上手腳本代碼,對這個腳本進行定製。
除了 Github issue 之外,comment.js 也支持使用 OSChina issue 作為後端,,即使 Github 被牆,也能通過修改參數迅速切換到其他備選站點,比起說關閉就關閉的評論服務可靠多了。
項目主頁:https://github.com/wzpan/comment.js
Demo
評論會話Demo
最新評論列表Demo
接入方法
comment.js 依賴幾個 JS 前端庫:
jQuery - 用於 Ajax 請求以及將評論內容插入到頁面中。
markdown-js - Markdown 支持。
timeago.js - 時間文本格式化。
spin - 用於在載入評論數據前先繪製一個 loading 動畫(可選)。
0. 添加靜態資源文件
在頁面中添加這些資源:
1. 註冊 OAuth App
為了避免 API 被惡意濫用,Github API (以及 OSChina API)設定了一個API調用頻率限制。為了提高頻率限額,建議 [註冊一個 Oauth App](Register a OAuth application](https://github.com/settings/applications/new)。
完成註冊後,你將得到一個 以及一個 ,先將這兩個值記下來,後面我們會用到。
(提示:註冊 App 的時候你可能會對 這一項目感到困惑,一般填寫你的站點地址即可。例如http://hahack.com )
2. 獲取評論會話
第一步,在頁面中添加一個 DIV ,用於展示評論會話內容。
第二步(可選),如果希望在載入完數據前先展示一個loading動畫,還可以添加一個用於動畫的 DIV :
最後,調用 方法,獲取該頁面對應的 issue 包含的所有評論,然後展示到我們指定的 DIV 中:
參數說明:
: 要作為後端的站點。目前支持 和 。
: 您的 Github 用戶名。
: 您用作評論後端的倉庫名。
: 當沒有評論時,展示的提示消息。
: 「去留言」 按鈕的按鈕文本。
: 您當前頁面對應的 issue 標題。也可以使用 ,二者只選其一。
: 您當前頁面對應的 issue id。也可以使用 ,二者只選其一。
: 「去留言」按鈕的 CSS 樣式名。
: 用於展示評論內容的容器。例如我們上面所寫的 DIV 。
(可選):用於展示 loading 動畫的容器。例如我們上面所寫的 DIV 。
(可選但建議):您註冊的 OAuth App 的 client id。
(可選但建議):您註冊的 OAuth App 的 client secret。
效果參見本頁面下方的留言區。
3. 獲取最新評論列表
評論列表用於獲取你最近的若干條評論,效果可以參見站點首頁 右側的最新留言區。
要獲取最新評論列表的方法也大同小異。首先寫一個 DIV 用於載入獲取得到的評論列表數據:
之後可以調用 方法,獲取最近評論列表並展示到指定的 DIV 中。
: 用於展示最新評論列表的容器。例如我們上面所寫的 DIV 。
: 列表的最大長度。
開發心得
下面照例總結下項目的開發心得。雖然整個項目只有幾百行的代碼,但這個過程中還是不可避免的遇到一些困難。
關於選型和項目命名
一開始的想法只是給 Hexo 寫一個插件,讓其能夠實現評論功能。最理想的情況是類似hexo-generator-search那樣,npm install 一下,然後 _config.yml 里添加下配置就完事。通過閱讀 Hexo 的文檔後我發現helper似乎比較適合用作這個目的:把核心功能寫成一個 helper ,然後在模板文件里直接執行這個 helper ,得到的數據還能進一步再模板中調諸如markdown等其他現成的 helper, 這樣還能實現 Markdown 支持。於是我最初的項目倉庫名叫做 hexo-helper-github-comment 。
等我實現了 方法後,我發現我的想法是錯誤的:helper 只適用於同步執行的操作,不適合網路請求這種非同步操作。這帶來的問題就是模板文件里已經成功執行了 helper 了,也返回了數據,但此時 renderer 早已經完成了模板的渲染了,而非同步返回的評論數據卻不再能夠被渲染。
之後我想在 NodeJS 中加入 jQuery,用 jQuery 來操縱 DOM ,而不再依賴 renderer 。但這個方案似乎也不可行。因為在模板文件中,DOM 還沒有創建,jQuery 拿不到實際的 DOM 。
所以最終我改成了純 JS 的方案,把請求的方式也從 request-promise 改成了 AJAX ,然後在模板文件中直接跑 JS ,讓 JS 完成請求,此時的 DOM 是已創建的,可以使用 jQuery 來操縱頁面。雖然這樣做就不能直接用 Hexo 現成的 markdown helper 了,但由於是純 JS 實現,這個庫也就可以在任何靜態站點中使用,變得更加通用了。於是我把倉庫名改成了 github-comment 。
又後來,我準備開源的前一天,在微博上先公開了關於這個項目的信息。有些人也表示了 Github 將來也可能被牆的質疑。於是我花了幾分鐘時間,也加入了對 OSChina 的支持。這個倉庫名似乎也不只是基於 Github 了,於是我又把倉庫名改成了 comment.js 。
關於取捨
我最糾結的部分,在於要不要把評論框也寫進來。
直接在頁面中寫評論,減少了頁面的跳數,當然是一大收益。但這樣做也有幾個問題:
功能可用性和項目的複雜度的取捨。Github 的編輯框其實包含了非常多的功能,例如支持拖拽的附件添加、表情、預覽、快捷鍵等等,如果不把這些功能加進來,編輯框的功能就顯得很雞肋,遠不如在 Github 中評論有趣;如果加進來,整個項目的代碼就遠不止 400 行這麼簡單了。
通用性和專用程度的取捨。為了避免 Github 單點問題,comment.js 還支持 OSChina 作為備選評論系統。加入 Github 的這些編輯功能,是否會影響對其他站點後端的兼容性又是個問題。
界面美觀程度和版權的取捨。現在的評論會話界面幾乎照搬了 Github 的樣式,因為點擊「去留言」按鈕實際上直接跳到了 Github ,相當於為 Github 做了引流,給了一個大大的版權說明,也就沒有了侵權的擔憂。如果界面完全隔離了 Github,也隱藏了 Github 的版權信息,反而有點濫用平台的感覺在。
有意思的是,當我剛發布 comment.js 的時候,我才發現幾個月前已經有人做了一個類似的項目:gitment,真是心有靈犀啊。這個項目與我的項目的最大區別就在於它實現了內置的編輯框,並且目前只支持 Github 。如果你認為評論框必不可少,那麼建議使用 gitment;反之如果你覺得點擊按鈕跳到 Github 頁面似乎也還能接受,擔心 Github 單點問題,而且覺得保證代碼的簡單和通用性更重要的話,那麼不妨使用 comment.js 。
※以CockroachDB為例,深入了解CAP定理
※哪些東西不打廣告也能讓你忍不住買買買?
※需求二三事:需求分析方法分類闡述
※iOS 11 相機和照片應用中的 8 個新變化
※Kotlin在Android 開發中的 16 個建議
TAG:推酷 |
※靜態站點生成器:makesite.py
※建站初學者必知的wordpress在Nginx/Apache/IIS中的偽靜態規則
※php7在FreeBSD靜態編譯iconv,導致BUS ERROR (core dump)解決
※Pelican 入門:一個 Python 靜態網站生成器
※塑料感嚴重 Asics DS Light Acros靜態賞析
※iOS靜態庫實戰之Framework
※go web template css js 靜態資源引用
※Google出品的Python代碼靜態類型分析器:Pytype
※使用SonarCloud為.NET/.NET Core項目集成靜態檢查
※Less與TypeScript的簡單理解與應用,並使用WebPack打包靜態頁面
※pyt:檢測 Python Web 應用安全漏洞的靜態掃描工具;DoxyCannon:ip隱藏
※Pyright:微軟提供的Python靜態類型檢查器
※基於Gatsby的React靜態化實踐
※靜態分析工具之-AXMLPrinter2.jar的使用方法
※An Archive of Making靜態展覽 以檔案室概念呈現HAIZHENWANG 18AW系列服裝
※CLOT巴黎時裝周靜態展"Out of This World
※Nassim Haramein全息分形宇宙九——靜態真空幾何結構
※AJ1 Pass The Torch靜態開箱 AJ1電鍍銀細節鑒賞
※SpringBoot應用不能訪問項目靜態頁面html問題處理
※使用Nunjucks構建包含組件的靜態站點