Hexo折腾记之科学使用Disqus与Next的集成
本文首发于kmac007.me
我可能就是个爱折腾的人吧。博客最早的时候部署在Github Pages,然而Github Pages实在太慢,而后迁到了Coding Pages。说实话,Coding Pages的访问速度非常快,实在是国内部署静态博客的利器。当然,你得在网站首页任意位置放置「Hosted by Coding Pages」的文字版或图片版来去除Pages跳转页。
目前,我个人的博客kmac007.me已从Coding Pages迁移至个人租用的虚拟主机中。原因后面再说。
Next主题的自定义
Next这个主题真的是相当的棒,官方文档中有详细的说明,有多种主题可供选择,还集成了大量的第三方插件。
而这个主题最吸引我的是简洁、优秀的代码高亮和显而易见的文章目录。但是原本的主题并不能并不能满足我的想法,因此我在Mist的基础上做了一些修改。(网上有很多Next主题的自定义教程,在此就不赘述了)
预览地址:kmac007.me
Github地址: https://github.com/kmac007/next-mist-kmac007
科学使用Disqus
如果不搭梯子disqus根本无法加载,一直处于加载中的状态,让人十分恼火。既然不搭梯子不能使用disqus,那么为什么还有用它呢?
为什么使用disqus
就当前的第三方评论工具中, 我对比了一下畅言、gitment、来必力。畅言需要备案才能使用,当然也可以用一些小技巧不备案也能使用畅言,畅言
的问题是,不支持非登录用户评论,印象中评论期间好像还要关注公众号什么的,特别繁琐。gitment
是一个基于GitHub Issues
的评论系统,同样的不支持非登录用户评论,并且只支持github登录,还有一个问题是必须要初始化其他用户才可以发表评论。来必力
,个人感觉并不好用,加载速度也不快,虽说支持github登录,但同样的并不支持非登录用户评论。
而disqus支持未注册用户评论,但是头疼的是被墙的问题。直到我看到了这篇文章科学使用 Disqus,该文作者写了一个disqus-php-api,利用 PHP cURL 转发 Disqus API 请求。
解决disqus被墙的问题
具体简单的流程如下
//伪代码
if( Disqus正常访问 ) {
客户端请求XHR -> Disqus响应 -> 结束
}else if( Disqus被墙 ) {
客户端请求XHR -> 服务端请求(cURL) -> Disqus响应 -> 服务端响应 -> 结束
}
具体实现细节请移步:科学使用 Disqus、disqus-php-api
这个方案可以很好的解决Disqus被墙的问题,开始加载页面时,做一个判断,如果Disqus正常访问,则使用原生的Disqus评论;如果被墙则使用自制的评论框,使用Disqus API。
因此要实现这个过程,我需要一个支持PHP的虚拟主机,这是我博客从Coding Pages迁出的原因。当然,其他方式也是可以的,这里我就不做深究了。
disqus-php-api的配置
搭建评论系统后端
我的虚拟主机只支持FTP上传,而Hexo自动部署会报错,实在无法解决,只能通过FTP手动上传文件。
获取disqus-php-api
执行如下命令,将disqus-php-api
拷贝到本地并重命名为disqus
git clone https://github.com/fooleap/disqus-php-api disqus
修改api
目录下的config.php
define('DISQUS_PUBKEY', 'E8Uh5l5fHZ6gD8U3KycjAIAk46f68Zw7C6eW8WSjZvCLXebZ7p0r1yrYDrLilk2F');
define('DISQUS_USERNAME', 'your-username');
define('DISQUS_EMAIL', 'your-email@qq.com');
define('DISQUS_PASSWORD', 'your-disqus-password');
define('DISQUS_WEBSITE', 'your-website');
define('DISQUS_SHORTNAME', 'your-disqus-shortname');
define('DISQUS_APPROVED', true);
-
DISQUS_PUBKEY
Disqus 公钥,无需修改 -
DISQUS_USERNAME
Disqus 用户名 -
DISQUS_EMAIL
Disqus 注册邮箱,重要 -
DISQUS_PASSWORD
Disqus 密码,重要 -
DISQUS_WEBSITE
网站域名,如:'http://blog.fooleap.org' -
DISQUS_SHORTNAME
网站在 Disqus 对应的 Shortname -
DISQUS_APPROVED
评论是否免审核,true 即跳过评论预审核,false 则按后台设置
这里要注意的是,DISQUS_PASSWORD
选项中,域名不能
这样写:‘https://kmac007.me/,域名后不能以'/'结尾,否则会出现一直创建Thread
的情况
上传到服务器
由于我是FTP上传,直接通过FTP工具将整个disqus
目录上传到网站的根目录中。
disqus-php-api集成至hexo next
修改Next的主题配置文件
在主题配置
文件_config.yml
中添加disqusapi相关参数
如:
# Disqus
disqus:
enable: false
shortname: your-short-name
count: false
# Disqus APi
disqusapi:
enable: true
forum: 'your-forum'
site: 'your-site'
api: 'https://yoursite.com/disqus/api'
mode: 2
badge: '博主'
timeout: 3000
-
forum
:DIsqus form的shortname -
site
:网站域名 -
api
:PHP代码部署的网址:https://yoursite.com/disqus/api
-
mode
:-
1
检测能否访问 Disqus,若能则加载 Disqus 原生评论框,超时则加载简易评论框 -
2
仅加载简易评论框 -
3
同时加载两种评论框,先显示简易评论框,Disqus 加载完成则切换至 Disqus 评论框
-
-
badge
:管理员徽章文本 -
timeout
:当mode为1时的超时时间
添加disqusapi模块
找到目录
your-site/themes/next/layout/_third-party/comments/
在其中新建名为disqusapi.swig
文件,内容为:
{% if theme.disqusapi.enable %}
<link rel="stylesheet" href="/disqus/dist/iDisqus.min.css" />
<script src="/disqus/dist/iDisqus.min.js"></script>
<script>
var emojiList = [{
code:'smile',
title:'笑脸',
unicode:'1f604'
},{
code:'mask',
title:'生病',
unicode:'1f637'
},{
code:'joy',
title:'破涕为笑',
unicode:'1f602'
},{
code:'stuck_out_tongue_closed_eyes',
title:'吐舌',
unicode:'1f61d'
},{
code:'flushed',
title:'脸红',
unicode:'1f633'
},{
code:'scream',
title:'恐惧',
unicode:'1f631'
},{
code:'pensive',
title:'失望',
unicode:'1f614'
},{
code:'unamused',
title:'无语',
unicode:'1f612'
},{
code:'grin',
title:'露齿笑',
unicode:'1f601'
},{
code:'heart_eyes',
title:'色',
unicode:'1f60d'
},{
code:'sweat',
title:'汗',
unicode:'1f613'
},{
code:'smirk',
title:'得意',
unicode:'1f60f'
}];
var disq = new iDisqus('comments', {
forum: '{{ theme.disqusapi.forum }}',
site: '{{ theme.disqusapi.site }}',
api: '{{ theme.disqusapi.api }}',
mode: {{ theme.disqusapi.mode }},
badge: '{{ theme.disqusapi.badge }}',
timeout: {{ theme.disqusapi.timeout }},
init: true,
emoji_list: emojiList
});
disq.count();
</script>
{% endif %}
引入index.swig
在当前目录下的index.swig
文件中添加:
{% include 'disqusapi.swig' %}
重新hexo g
生成,再上传到服务器中即可看到disqus了。
问题
跨域
你可能在控制台中出现这种问题。
No 'Access-Control-Allow-Origin' header is present on the requested resource.
将init.php
文件中设置Access-Control-Allow-Origin
部分:
namespace Emojione;
require_once('config.php');
require_once('emojione/autoload.php');
header('Content-type:text/json');
$origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
if(preg_match('(localhost|127\.0\.0\.1|'.DISQUS_WEBSITE.')', $origin)){
header('Access-Control-Allow-Origin: '.$origin);
}
$client = new Client(new Ruleset());
删除原本设置 Access-Control-Allow-Origin 的代码,替换以下的代码:
(其中,变量 allow_origin 是你要允许可以调用你后端的域名网址)
namespace Emojione;
require_once('config.php');
require_once('emojione/autoload.php');
header('Content-type:text/json');
//跨域访问的时候才会存在此字段
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
$allow_origin = array(
'http://smk17.cn',
'http://www.smk17.cn'
);
if(in_array($origin, $allow_origin)){
header('Access-Control-Allow-Origin:'.$origin);
}
$client = new Client(new Ruleset());
创建thread
如果出现创建thread
的问题,那么可以通过 mode
选择1
,再翻墙访问你的文章页面,这时候加载原生Disqus评论系统,thread
就创建成功了。
特别要注意的是:如果你的文章标题中带有中文,会无法创建thread
,所以不要使用中文命名文章。
本文参考了fooleap和SengMitnick的工作,非常感谢两位的工作。