本文部分内容转载自
这篇文章 ,作者:异次元 de 机智君。
为什么选择 Twikoo? 其实 iMaeGoo 大佬在 Twikoo 中文文档 里就把理由说的非常清楚了:
一个简洁、安全、免费的静态网站评论系统,基于腾讯云开发。
「简洁」、「安全」、「免费」、基于国内的云服务,对于一个主体语言是中文的博客来说,还需要更多理由吗?目前的评论系统现状是:「简洁」的,不够安全;「安全」的不一定免费;「免费」的不一定在国内网络环境能很好的访问。
Twikoo 的特性 作为一款「纯国产」的评论系统,Twikoo 很多特性对于国内博主真的很方便:
采用免费的腾讯云开发,免去二次备案的时间成本;
通过云函数控制敏感信息,防止泄漏;
微信、QQ、邮件…… 多种提醒方式可选;
基于 Akismet 的反垃圾支持;
方便好用的评论管理系统和配置台,直接在博客评论区管理评论和配置其他信息;
博主标识、User Agent 显示、点赞系统、多级评论、支持图片、markdown、Katex 公式……;
活跃、友善的开发者和社区;
除此之外,你还需要明白 Twikoo 是个正在成长中的评论系统,且更新频繁,你可以在这里浏览开发计划。另外,它已被腾讯云官方选为云开发优秀应用。
部署 Twikoo 评论系统 搭建 Twikoo 分两步:
在本地的博客主题中配置 Twikoo;
在腾讯云配置环境和云函数;
本文基于原版 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 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', ' <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
,点击 “下一步”
清空输入框中的示例代码,复制以下代码、粘贴到 “函数代码” 输入框中,点击 “确定”
1 exports .main = require ('twikoo-func' ).main
创建完成后,点击 “twikoo“进入云函数详情页,进入 “函数代码” 标签,点击 “文件 - 新建文件”,输入 package.json
,回车
复制以下代码、粘贴到代码框中,点击 “保存并安装依赖”(下面的版本号请自行参照文档更新)
1 { "dependencies" : { "twikoo-func" : "1.2.0" } }
成功了!你给自己的 Icarus 博客换上了崭崭新的 Twikoo 评论,接下来看看如何管理和配置。
配置、管理你的 Twikoo 评论系统
进入 环境 - 登陆授权 ,点击 “自定义登录” 右边的 “私钥下载”,下载私钥文件
用文本编辑器打开私钥文件,复制全部内容
你只需要来到最下面的评论区,点击小齿轮即可配置更多设置,当然博主是需要登录的,初次进入需要粘贴私钥文件内容,并设置管理员密码。
本部分参考了 支持显示 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 = ' 加载失败 ' ; }); } function changeContent (content ) { if (content === '' ) return content; content = content.replace(/<[^>]+>/g , '' ); 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 - position: right type: twikoo_new envId: xxxxxxxxxxxxxxxxx
上面的代码就是本站“最新评论”Widget 的配置。