在 Icarus 中部署 Twikoo 并添加其 Widget

在 Icarus 中部署 Twikoo 并添加其 Widget

本文部分内容转载自 这篇文章,作者:异次元 de 机智君。

为什么选择 Twikoo?

其实 iMaeGoo大佬在 Twikoo 中文文档 里就把理由说的非常清楚了:

一个简洁、安全、免费的静态网站评论系统,基于腾讯云开发。

「简洁」、「安全」、「免费」、基于国内的云服务,对于一个主体语言是中文的博客来说,还需要更多理由吗?目前的评论系统现状是:「简洁」的,不够安全;「安全」的不一定免费;「免费」的不一定在国内网络环境能很好的访问。

Twikoo 的特性

作为一款「纯国产」的评论系统,Twikoo 很多特性对于国内博主真的很方便:

  1. 采用免费的腾讯云开发,免去二次备案的时间成本;
  2. 通过云函数控制敏感信息,防止泄漏;
  3. 微信、QQ、邮件…… 多种提醒方式可选;
  4. 基于 Akismet 的反垃圾支持;
  5. 方便好用的评论管理系统和配置台,直接在博客评论区管理评论和配置其他信息;
  6. 博主标识、User Agent 显示、点赞系统、多级评论、支持图片、markdown、Katex 公式……;
  7. 活跃、友善的开发者和社区;

除此之外,你还需要明白 Twikoo 是个正在成长中的评论系统,且更新频繁,你可以在这里浏览开发计划。另外,它已被腾讯云官方选为云开发优秀应用。

部署 Twikoo 评论系统

搭建 Twikoo 分两步:

  1. 在本地的博客主题中配置 Twikoo;
  2. 在腾讯云配置环境和云函数;

本文基于原版 Icarus 4.1.2。

在本地的博客主题中配置 Twikoo

第一步

在主题目录下 layout/comment 中创建 twikoo.jsx 并键入:

twikoo.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const { Component, Fragment } = require('inferno');
const { cacheComponent } = require('hexo-component-inferno/lib/util/cache');

class Twikoo extends Component {
render() {
const {
envId,
jsUrl,
} = this.props;
const js = `twikoo.init({
envId: '${envId}'
});`;
return (
<Fragment>
<div id="twikoo" class="content twikoo"></div>
<script src={jsUrl}></script>
<script dangerouslySetInnerHTML={{ __html: js }}></script>
</Fragment>
);
}
}

Twikoo.Cacheable = cacheComponent(Twikoo, 'comment.twikoo', (props) => {
const { comment } = props;
return {
envId: comment.envId,
jsUrl: 'https://cdn.jsdelivr.net/npm/twikoo/dist/twikoo.all.min.js',
};
});

module.exports = Twikoo;

第二步

include/shema/comment中创建 twikoo.json ,并键入:

twikoo.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "/comment/twikoo.json",
"description": "Twikoo comment plugin configurations",
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "twikoo"
},
"envId": {
"type": "string",
"description": "envId from Tencent CloudBase"
}
},
"required": ["type", "envId"]
}

第三步

include/schema/common/comment.json 中添加 twikoo.json$ref

comment.json
1
2
3
4
5
6
7
8
9
        },
{
"$ref": "/comment/valine.json"
+ },
+ {
+ "$ref": "/comment/twikoo.json"
}
]
}

第四步

现在你只需要在 _config.yml 文件中 comment 部分添加 Twikoo 即可,在 envId 后面请填写你自己的腾讯云环境 ID,这个 ID 你会在下一个板块了解如何获取,现在可以空着:

_config.yml
1
2
3
4
comment:
type: twikoo
envId: xxxxxxxxxxxxxxx # 腾讯云环境 ID
jsUrl: https://cdn.jsdelivr.net/npm/twikoo@x.x.x/dist/twikoo.all.min.js

这里需要注意的是最后的 jsUrl ,你会发现 twikoo 后面有 @ 版本号。这个版本号应该与云函数版本号保持一致。保险起见,目前 twikoo 是需要你手动去更新这个版本号的。

同样,更新版本也很简单,后台更新云函数后,改版本号即可。(这里有个坑,建议每次更新版本先删除 node_modules 再点击保存并安装依赖)

第五步(可选)

给博客换上 Twikoo 访客计数。在 layout/common/article.jsx 中修改{/* Visitor counter */} 部分:

article.jsx
1
2
3
4
+ {!index ? <span id={url_for(page.link || page.path)} class="level-item twikoo_visitors" data-flag-title={page.title} dangerouslySetInnerHTML={{
- {!index && plugins && plugins.busuanzi === true ? <span class="level-item" id="busuanzi_container_page_pv" dangerouslySetInnerHTML={{ __html: _p('plugin.visit_count', '<span id="busuanzi_value_page_pv">0</span>')
+ __html: '<i class="far fa-eye"></i>' + _p('plugin.visit_count', '&nbsp;&nbsp;<span id="twikoo_visitors"><i class="fa fa-spinner fa-spin"></i></span>')
}}></span> : null}

本地需要修改的部分完成。

在腾讯云配置环境和云函数

使用云开发作为评论后台,每个云开发用户均长期享受 1 个免费的标准型基础版 1 资源套餐,换句话说对于大部分博主来说是免费的。

以下引用自Twikoo 中文文档

  1. 进入 云开发 CloudBase活动页面,滚动到 “新用户专享” 部分,选择适合的套餐(一般 0 元套餐即可),点击 “立即购买”,按提示创建好环境。
    • 提示
      1. 推荐创建上海环境。如选择广州环境,需要在 twikoo.init() 时额外指定环境 region: "ap-guangzhou"
      2. 环境名称自由填写
      3. 推荐选择计费方式 包年包月 ,套餐版本 基础版 1,超出免费额度不会收费
      4. 如果提示选择 “应用模板”,请选择 “空模板”
  2. 进入 云开发控制台
  3. 复制环境 ID,在上一板块中的第四步填写。
  4. 进入 环境 - 登陆授权,启用 “匿名登录”
  5. 进入 环境 - 安全配置,将网站域名添加到 “WEB 安全域名”
  6. 进入 环境 - 云函数,点击 “新建云函数”
  7. 函数名称请填写:twikoo,创建方式请选择:空白函数,运行环境请选择:Nodejs 10.15,函数内存请选择:128MB,点击 “下一步”
  8. 清空输入框中的示例代码,复制以下代码、粘贴到 “函数代码” 输入框中,点击 “确定”
1
exports.main = require('twikoo-func').main
  1. 创建完成后,点击 “twikoo“进入云函数详情页,进入 “函数代码” 标签,点击 “文件 - 新建文件”,输入 package.json,回车
  2. 复制以下代码、粘贴到代码框中,点击 “保存并安装依赖”(下面的版本号请自行参照文档更新)
1
{ "dependencies": { "twikoo-func": "1.2.0" } }

成功了!你给自己的 Icarus 博客换上了崭崭新的 Twikoo 评论,接下来看看如何管理和配置。

配置、管理你的 Twikoo 评论系统

  1. 进入 环境 - 登陆授权,点击 “自定义登录” 右边的 “私钥下载”,下载私钥文件
  2. 用文本编辑器打开私钥文件,复制全部内容
  3. 你只需要来到最下面的评论区,点击小齿轮即可配置更多设置,当然博主是需要登录的,初次进入需要粘贴私钥文件内容,并设置管理员密码。

添加“最新评论”Widget

本部分参考了 支持显示 Twikoo 最新评论 · imaegoo/hexo-theme-icarus@39d5093 · GitHub,在此向作者表示感谢。

第一步

include/schema/common/widgets.json中做如下修改:

widgets.json
1
2
3
4
5
6
7
8
9
            {
"$ref": "/widget/subscribe_email.json"
},
+ {
+ "$ref": "/widget/twikoo_new.json"
+ },
{
"$ref": "/widget/adsense.json"
}

第二步

include/schema/widget目录新建 twikoo_new.json 文件,内容为:

twikoo_new.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "/widget/twikoo_new.json",
"description": "Twikoo new comment widget configurations",
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "twikoo_new"
},
"envId": {
"type": "string",
"description": "envId from Tencent CloudBase"
}
},
"required": ["type", "envId"]
}

第三步

layout/widget目录新建 twikoo_new.jsx 文件,内容为:

twikoo_new.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const { Component } = require(‘inferno’);
const { cacheComponent } = require(‘hexo-component-inferno/lib/util/cache’);

class TwikooNew extends Component {
render() {
const { envId } = this.props;
const js = `window.twikooEnvId = '${envId}';`;
return (
<div class=“card widget” id=“twikoo-new”>
<div class=“card-content”>
<div class=“menu”>
<h3 class=“menu-label”> 最新评论 </h3>
<script dangerouslySetInnerHTML={{ __html: js }}></script>
<div class=“twikoo-new-container”></div>
</div>
</div>
</div>
);
}
}

TwikooNew.Cacheable = cacheComponent(TwikooNew, ‘widget.twikoonew’, (props) => {
const { widget } = props;
const { envId } = widget;

return {
envId: 'xxxxxxxxxxxxxxxxx',
};
});

module.exports = TwikooNew;

注意把 xxxxxxxxxxxxxxxxx 替换为自己的腾讯云环境 ID。

第四步

include/style中的任意一个 .styl 中添加如下内容:

1
2
3
4
5
.twikoo-new-content
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;

第五步

layout/common/scripts.jsx中做如下修改:

scripts.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
return <Fragment>
<script src={cdn('jquery', '3.3.1', 'dist/jquery.min.js')}></script>
<script src={cdn('moment', '2.22.2', 'min/moment-with-locales.min.js')}></script>
+ {config.comment.jsUrl && <script src={config.comment.jsUrl}></script>}
{clipboard && <script src={cdn('clipboard', '2.0.4', 'dist/clipboard.min.js')} defer></script>}
<script dangerouslySetInnerHTML={{ __html: `moment.locale("${language}");` }}></script>
<script dangerouslySetInnerHTML={{ __html: embeddedConfig }}></script>
<script src={url_for('/js/column.js')}></script>
<Plugins site={site} config={config} page={page} helper={helper} head={false} />
<script src={url_for('/js/main.js')} defer></script>
</Fragment>;
}
};

第六步

修改source/js/main.js,添加如下内容:

main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
function loadTwikooNewComment() {
var twikooOrgPaths = ['/', '/api.html', '/cms.html', '/configuration.html', '/faq.html', '/link.html', '/quick-start.html'];
var twikooNewEl = document.getElementsByClassName('twikoo-new-container');
if (twikooNewEl.length === 0) return;
twikoo.getRecentComments({
envId: window.twikooEnvId,
pageSize: 5,
includeReply: true
}).then(function (res) {
var innerHTML = '';
for (var idx1 = 0; idx1 < res.length; idx1++) {
var item = res[idx1];
if (!item.commentText.trim()) continue
if (twikooOrgPaths.indexOf(item.url) !== -1) item.url = 'https://twikoo.js.org' + item.url;
innerHTML += '<article class="media"><div class="media-content">'
+ '<p class="title twikoo-new-content"><a href="' + item.url + '#' + item.id + '">' + changeContent(item.commentText) + '</a></p>'
+ '<p class="date">' + item.nick + ' / ' + item.relativeTime + '</p>'
+ '</div></article>';
}
for (var idx2 = 0; idx2 < twikooNewEl.length; idx2++) {
twikooNewEl[idx2].innerHTML = innerHTML;
}
}).catch(function (err) {
console.error(err);
twikooNewEl.innerHTML = ' 加载失败 ';
});
}

// 从 butterfly 主题借鉴
// https://github.com/jerryc127/hexo-theme-butterfly/blob/dev/layout/includes/third-party/newest-comments/twikoo-comment.pug
function changeContent (content) {
if (content === '') return content;
content = content.replace(/<[^>]+>/g, ''); // remove html tag
if (content.length > 150) {
content = content.substring(0, 150) + '...';
}
return content;
}

loadTwikooNewComment();

第七步

在 Icarus 的 _config.yml 中增加一个名为 twikoo_new 的 Widget 并进行配置,如:

_config.yml
1
2
3
4
5
6
# Recent comments widget configurations
-
# Where should the widget be placed, left sidebar or right sidebar
position: right
type: twikoo_new
envId: xxxxxxxxxxxxxxxxx # 腾讯云环境 ID

上面的代码就是本站“最新评论”Widget 的配置。

在 Icarus 中部署 Twikoo 并添加其 Widget

https://seobinggo.gq/articles/4293378149/

作者

Goblet

发布于

2021-02-24

更新于

2021-02-24

许可协议

CC BY-NC 4.0

评论