在 Icarus 中部署 Twikoo 并添加其 Widget
Goblet / 2021-02-24
为什么选择 Twikoo?
其实 iMaeGoo 大佬在Twikoo 中文文档里就把理由说的非常清楚了:
一个简洁、安全、免费的静态网站评论系统,基于腾讯云开发。
「简洁」、「安全」、「免费」、基于国内的云服务,对于一个主体语言是中文的博客来说,还需要更多理由吗?目前的评论系统现状是:「简洁」的,不够安全;「安全」的不一定免费;「免费」的不一定在国内网络环境能很好的访问。
Twikoo 的特性
作为一款「纯国产」的评论系统,Twikoo 很多特性对于国内博主真的很方便:
- 采用免费的腾讯云开发,免去二次备案的时间成本;
- 通过云函数控制敏感信息,防止泄漏;
- 微信、QQ、邮件…… 多种提醒方式可选;
- 基于 Akismet 的反垃圾支持;
- 方便好用的评论管理系统和配置台,直接在博客评论区管理评论和配置其他信息;
- 博主标识、User Agent 显示、点赞系统、多级评论、支持图片、markdown、Katex 公式……;
- 活跃、友善的开发者和社区;
除此之外,你还需要明白 Twikoo 是个正在成长中的评论系统,且更新频繁,你可以在这里浏览开发计划。另外,它已被腾讯云官方选为云开发优秀应用。
部署Twikoo评论系统
搭建 Twikoo 分两步:
- 在本地的博客主题中配置 Twikoo;
- 在腾讯云配置环境和云函数;
本文基于原版Icarus 4.1.2。
在本地的博客主题中配置 Twikoo
第一步
在主题目录下 layout/comment 中创建twikoo.jsx并键入:
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 ,并键入:
{
"$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:
},
{
"$ref": "/comment/valine.json"
+ },
+ {
+ "$ref": "/comment/twikoo.json"
}
]
}
第四步
现在你只需要在 _config.yml 文件中 comment 部分添加 Twikoo 即可,在 envId 后面请填写你自己的腾讯云环境 ID,这个 ID 你会在下一个板块了解如何获取,现在可以空着:
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 */} 部分:
+ {!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', ' <span id="twikoo_visitors"><i class="fa fa-spinner fa-spin"></i></span>')
}}></span> : null}
本地需要修改的部分完成。
在腾讯云配置环境和云函数
使用云开发作为评论后台,每个云开发用户均长期享受 1 个免费的标准型基础版 1 资源套餐,换句话说对于大部分博主来说是免费的。
以下引用自Twikoo 中文文档。
- 进入云开发 CloudBase活动页面,滚动到 “新用户专享” 部分,选择适合的套餐(一般 0 元套餐即可),点击 “立即购买”,按提示创建好环境。
- 提示
- 推荐创建上海环境。如选择广州环境,需要在
twikoo.init()时额外指定环境region: "ap-guangzhou" - 环境名称自由填写
- 推荐选择计费方式
包年包月,套餐版本基础版 1,超出免费额度不会收费 - 如果提示选择 “应用模板”,请选择 “空模板”
- 推荐创建上海环境。如选择广州环境,需要在
- 提示
- 进入云开发控制台
- 复制环境 ID,在上一板块中的第四步填写。
- 进入环境-登陆授权,启用 “匿名登录”
- 进入环境-安全配置,将网站域名添加到 “WEB 安全域名”
- 进入环境-云函数,点击 “新建云函数”
- 函数名称请填写:
twikoo,创建方式请选择:空白函数,运行环境请选择:Nodejs 10.15,函数内存请选择:128MB,点击 “下一步” - 清空输入框中的示例代码,复制以下代码、粘贴到 “函数代码” 输入框中,点击 “确定”
exports.main = require('twikoo-func').main
- 创建完成后,点击 “twikoo“进入云函数详情页,进入 “函数代码” 标签,点击 “文件 - 新建文件”,输入
package.json,回车 - 复制以下代码、粘贴到代码框中,点击 “保存并安装依赖”(下面的版本号请自行参照文档更新)
{ "dependencies": { "twikoo-func": "1.2.0" } }
成功了!你给自己的 Icarus 博客换上了崭崭新的 Twikoo 评论,接下来看看如何管理和配置。
配置、管理你的 Twikoo 评论系统
- 进入环境-登陆授权,点击 “自定义登录” 右边的 “私钥下载”,下载私钥文件
- 用文本编辑器打开私钥文件,复制全部内容
- 你只需要来到最下面的评论区,点击小齿轮即可配置更多设置,当然博主是需要登录的,初次进入需要粘贴私钥文件内容,并设置管理员密码。
添加“最新评论”Widget
本部分参考了支持显示Twikoo最新评论 · imaegoo/hexo-theme-icarus@39d5093 · GitHub,在此向作者表示感谢。
第一步
在include/schema/common/widgets.json中做如下修改:
{
"$ref": "/widget/subscribe_email.json"
},
+ {
+ "$ref": "/widget/twikoo_new.json"
+ },
{
"$ref": "/widget/adsense.json"
}
第二步
在include/schema/widget目录新建twikoo_new.json文件,内容为:
{
"$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文件,内容为:
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中添加如下内容:
.twikoo-new-content
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
第五步
在layout/common/scripts.jsx中做如下修改:
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,添加如下内容:
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并进行配置,如:
# Recent comments widget configurations
-
# Where should the widget be placed, left sidebar or right sidebar
position: right
type: twikoo_new
envId: xxxxxxxxxxxxxxxxx # 腾讯云环境ID
上面的代码就是本站“最新评论”Widget的配置。