能動手絕不多說:開源評論系統remark42上手指南

李國寶發表於2020-08-06

能動手絕不多說:開源評論系統 remark42 上手指南

前言

寫部落格嘛,

誰不喜歡自己倒騰一下呢。

從自建系統到 Github Page,

JekyllHexo

年輕的時候誰不喜歡多折騰折騰呢。

年紀稍稍長了一下之後, 最後我自己還是選了 Hexo 直接做靜態部落格生成,

結合一下 Gitlab CI 推程式碼之後自動構建之後更新到自己的伺服器了。

後來又基於“多說”直接支援了部落格內容評論,

再後來,多說倒下了,評論功能就一直沒有維護了。

前陣子因為某些需求,對市面上部分評論系統做了一次調研,

這時候發現其實大家都做了好多輪子了,近期空出來了終於可以再玩玩了。

開源評論系統調研

調研前提:

  • 開源,協議友好,可商用
  • 專案程式碼“正常”(實在不太想看 Ruby/PHP),維護積極
  • 部署簡單,二開方便

下面直接扔了上次的調研結果出來。

vkuznecovas/mouthful

  • Mouthful is a self-hosted alternative to Disqus https://mouthful.dizzy.zone/
  • Golang 編寫,支援 MySQL、PG、SQLIte,支援評論稽核
  • 維護狀態:2018 年之後沒看到更新了
    Features
  • Multiple database support(sqlite, mysql, postgres, dynamodb)
  • Moderation with an administration panel
  • Server side caching to prevent excessive database calls
  • Rate limiting
  • Honeypot feature, to prevent bots from posting comments
  • Migrations from existing commenting engines(isso, disqus)
  • Configuration - most of the features can be turned on or off, as well as customized to your preferences.
  • Admin login through third parties such as facebook and twitter, and 35 more.
  • Dumping comments out, and importing an old dump.

schn4ck/schnack

  • Simple self-hosted node app for Disqus-like drop-in commenting on static websites https://schnack.cool/
  • Node js 編寫, SQLite, 沒看到其他資料庫的支援
  • 維護狀態:最後一次更新是 15 個月前
    Features
  • Tiny! It takes only ~8 KB!!! to embed Schnack.
  • Open source and self-hosted.
  • Ad-free and Tracking-free. Schnack will not disturb your users.
  • It's simpy to moderate, with a minimal and slick UI to allow/reject comments or trust/block users.
  • webpush protocol to notify the site owner about new comments awaiting for moderation.
  • Third party providers for authentication like Github, Twitter, Google and Facebook. Users are not required to register a new account on your system and you don't need to manage a user management system.

adtac/commento

  • A fast, bloat-free comments platform (Github mirror) https://commento.io
  • golang 編寫,支援 PG
  • 維護狀態:兩個月還在更新,支援本地部署
  • https://docs.commento.io/
    What features does Commento have?
    Commento comes with a lot of useful features out-of-the-box: rich text support, upvotes and downvotes, automatic spam detection, moderation tools, sticky comments, thread locking, OAuth login, email notifications, and more!

posativ/isso

  • a Disqus alternative https://posativ.org/isso/
  • Python,SQLIte,引入了 ORM 元件但是暫時沒看到其他資料庫的支援
  • Admin panel to moderate comments
  • 維護狀態:活躍,幾天前還在更新

Isso – Ich schrei sonst – is a lightweight commenting server written in Python and JavaScript. It aims to be a drop-in replacement for Disqus.

umputun/remark42

  • comment engine https://remark42.com
  • Golang + SQLIte + 支援 Admin
  • 維護狀態:活躍,幾天前還在更新
    Remark42 is a self-hosted, lightweight, and simple (yet functional) comment engine, which doesn't spy on users. It can be embedded into blogs, articles or any other place where readers add comments.
  • Social login via Google, Twitter, Facebook, GitHub and Yandex
  • Login via email
  • Optional anonymous access
  • Multi-level nested comments with both tree and plain presentations
  • Import from Disqus and WordPress
  • Markdown support with friendly formatter toolbar
  • Moderator can remove comments and block users
  • Voting, pinning and verification system
  • Sortable comments
  • Images upload with drag-and-drop
  • Extractor for recent comments, cross-post
  • RSS for all comments and each post
  • Telegram and email notifications
  • Export data to json with automatic backups
  • No external databases, everything embedded in a single data file
  • Fully dockerized and can be deployed in a single command
  • Self-contained executable can be deployed directly to Linux, Windows and MacOS
  • Clean, lightweight and customizable UI with white and dark themes
  • Multi-site mode from a single instance
  • Integration with automatic ssl (direct and via nginx-le)
  • Privacy focused

jacobwb/hashover

開始實踐

調研搞完之後,停了一陣子,最近把專案扔給同事做進一步 demo 搭建,

同事花了點時候搭了一下 demo 和看了程式碼,最後在 commento 和 remark42 中“猶豫了”

最後比較了程式碼結構和二次開發成本, 選擇了 remark42

所以,我這邊最後也使用 remark42 直接搭了自己的評論系統。

開始“搞事”

remark42

由於文件寫得實在太好了,部署也沒遇到什麼奇怪問題,

部署服務端這一步真的跳過了,有奇怪的問題需要的朋友自行提問吧。

Hexo next 整合 remark42

這一段是需要寫寫的。

看完了文件的朋友應該知道,

在某個頁面整合評論只需要加下面這些程式碼。

頁面插入 script

<script>
  var remark_config = {
    host: "REMARK_URL", // hostname of remark server, same as REMARK_URL in backend config, e.g. "https://demo.remark42.com"
    site_id: "YOUR_SITE_ID",
    components: ["embed"], // optional param; which components to load. default to ["embed"]
    // to load all components define components as ['embed', 'last-comments', 'counter']
    // available component are:
    //     - 'embed': basic comments widget
    //     - 'last-comments': last comments widget, see `Last Comments` section below
    //     - 'counter': counter widget, see `Counter` section below
    url: "PAGE_URL", // optional param; if it isn't defined
    // `window.location.origin + window.location.pathname` will be used,
    //
    // Note that if you use query parameters as significant part of url
    // (the one that actually changes content on page)
    // you will have to configure url manually to keep query params, as
    // `window.location.origin + window.location.pathname` doesn't contain query params and
    // hash. For example default url for `https://example/com/example-post?id=1#hash`
    // would be `https://example/com/example-post`.
    //
    // The problem with query params is that they often contain useless params added by
    // various trackers (utm params) and doesn't have defined order, so Remark treats differently
    // all this examples:
    // https://example.com/?postid=1&date=2007-02-11
    // https://example.com/?date=2007-02-11&postid=1
    // https://example.com/?date=2007-02-11&postid=1&utm_source=google
    //
    // If you deal with query parameters make sure you pass only significant part of it
    // in well defined order
    max_shown_comments: 10, // optional param; if it isn't defined default value (15) will be used
    theme: "dark", // optional param; if it isn't defined default value ('light') will be used
    page_title: "Moving to Remark42", // optional param; if it isn't defined `document.title` will be used
    locale: "en", // set up locale and language, if it isn't defined default value ('en') will be used
  };

  (function (c) {
    for (var i = 0; i < c.length; i++) {
      var d = document,
        s = d.createElement("script");
      s.src = remark_config.host + "/web/" + c[i] + ".js";
      s.defer = true;
      (d.head || d.body).appendChild(s);
    }
  })(remark_config.components || ["embed"]);
</script>

頁面插入評論框

<div id="remark42"></div>

那麼問題來了,在 hexo 的 next 主題裡面怎麼做呢?

答案是: 肯定是抄程式碼啊!!!

hexo next 主題

首先知道(鬼知道啊),next 主題一般在專案 themes/next 路徑,

themes/next/layout 這個資料夾存放了佈局檔案,其中_layout.swig 是一個重要的全域性佈局檔案。

所以,明顯是修改_layout.swig 引入上面的 script 程式碼啦。

看了一眼_layout.swig 的程式碼, 底部基本是 include 引入同級的 swig 檔案。

  {% include '_scripts/boostrap.swig' %}

  {% include 'remark42.swig' %}

  {% include '_third-party/comments/index.swig' %}
  {% include '_third-party/search/index.swig' %}

明顯,我們也可以加一個 swig,然後在上面引入一下。

新建 remark42.swig,貼入 script 程式碼


<script>
  var remark_config = {
    host: "你部署的remark42 服務", // hostname of remark server, same as REMARK_URL in backend config, e.g. "https://demo.remark42.com"
    site_id: '你的站點Id,部署的時候指定的',
    components: ['embed'], // optional param; which components to load. default to ["embed"]
                           // to load all components define components as ['embed', 'last-comments', 'counter']
                           // available component are:
                           //     - 'embed': basic comments widget
                           //     - 'last-comments': last comments widget, see `Last Comments` section below
                           //     - 'counter': counter widget, see `Counter` section below
    url: window.location.origin + window.location.pathname, // optional param; if it isn't defined
                     // `window.location.origin + window.location.pathname` will be used,
                     //
                     // Note that if you use query parameters as significant part of url
                     // (the one that actually changes content on page)
                     // you will have to configure url manually to keep query params, as
                     // `window.location.origin + window.location.pathname` doesn't contain query params and
                     // hash. For example default url for `https://example/com/example-post?id=1#hash`
                     // would be `https://example/com/example-post`.
                     //
                     // The problem with query params is that they often contain useless params added by
                     // various trackers (utm params) and doesn't have defined order, so Remark treats differently
                     // all this examples:
                     // https://example.com/?postid=1&date=2007-02-11
                     // https://example.com/?date=2007-02-11&postid=1
                     // https://example.com/?date=2007-02-11&postid=1&utm_source=google
                     //
                     // If you deal with query parameters make sure you pass only significant part of it
                     // in well defined order
    max_shown_comments: 10, // optional param; if it isn't defined default value (15) will be used
    theme: 'dark', // optional param; if it isn't defined default value ('light') will be used
    page_title: 'Moving to Remark42', // optional param; if it isn't defined `document.title` will be used
    locale: 'en' // set up locale and language, if it isn't defined default value ('en') will be used
  };

  (function(c) {
    for(var i = 0; i < c.length; i++){
      var d = document, s = d.createElement('script');
      s.src = remark_config.host + '/web/' +c[i] +'.js';
      s.defer = true;
      (d.head || d.body).appendChild(s);
    }
  })(remark_config.components || ['embed']);
</script>

layout.swig 新增 remark42.swig 引用

  {% include '_scripts/boostrap.swig' %}

  {% include 'remark42.swig' %}

  {% include '_third-party/comments/index.swig' %}
  {% include '_third-party/search/index.swig' %}

搞完這個,全域性指令碼引用已經搞掂了。

下面就是每個文章頁面需要新增 remark42 評論框了

明顯,應該是 post.swig

觀察一下 themes/next/layout 目錄不難發現,

每個文章的的樣式模板都在 post.swig,

明顯評論框也應該直接在 post.swig。

開啟一看,感覺應該加在

下面

於是:

<div id="posts" class="posts-expand">
  {{ post_template.render(page) }}

  <div class="post-spread">
    {% if theme.jiathis %} {% include '_partials/share/jiathis.swig' %} {%
    elseif theme.baidushare %} {% include '_partials/share/baidushare.swig' %}
    {% elseif theme.add_this_id %} {% include '_partials/share/add-this.swig' %}
    {% elseif theme.duoshuo_shortname and theme.duoshuo_share %} {% include
    '_partials/share/duoshuo_share.swig' %} {% endif %}
  </div>
  <div id="remark42"></div>
</div>

完事...

最後效果

remark42

歡迎評論來玩!!

相關文章