本文解決兩個問題:
- hexo next 主題(version 5.1.3)怎么設置成點擊按鈕再加載評論
- hexo next 主題怎樣設置才能同時加載 Disqus 和來必力(livere)雙評論系統或更多評論系統
設計思路
我的博客主要是面向墻向用戶,所以只能在墻內評論系統里面選一個。不需要備案、登錄方式相對多的系統就輪到來必力,唯一的缺點是加載的時候有點慢。但 Disqus 評論系統在墻外應用比較廣、功能全,而且顯得格調和水平比較高,于是就想加載兩個系統。還有一種思路是用JavaScript判斷用戶的網絡是否在中國大陸,然后再加載對應的評論系統。還有為Disqus設置代理的方法,不過評論少的時候折騰了收益不高。
在搜索實現方式的過程,發現還可以讓用戶點擊按鈕之后再加載評論系統,這樣可避免緩沖過多的JavaScript腳本,改善讀者的體驗,讓博客頁面簡潔。而且甚至還可以多個評論按鈕,用戶想看哪個評論系統就點哪個。
上面幾種思路就有好幾種排列組合了,我暫定選用了設置一個“加載評論”的按鈕,讀者點擊之后同時加載兩個評論系統,當然墻內用戶看不到Disqus。
研究了hexo next 主題的源文件,發現它把帶個博客拆成各種模塊,再由配置文件里面的開關和JavaScript判斷語句來決定最后生成的博客是什么樣。而且最后生成的靜態博客,還可以通過JavaScript的條件語句來判斷是否加載某些模塊。
以post頁面的評論模塊為例,它牽扯到的源文件有:
-
"\blog\themes\next_config.yml"
這是主題配置文件,里面有開關和參數
# Disqus disqus: enable: true shortname: count: false
?
-
"\blog\themes\next\layout_layout.swig"
layout就是布局,這里面有兩行
{% include '_partials/comments.swig' %}
{% include '_third-party/comments/index.swig' %}
大概就是它分別引用了
comments.swig
和index.swig
兩個模塊
-
"\blog\themes\next\layout_third-party\comments\index.swig"
這個模塊就是一堆include
{% include 'duoshuo.swig' %}
{% include 'disqus.swig' %}
{% include 'hypercomments.swig' %}
{% include 'youyan.swig' %}
{% include 'livere.swig' %}
{% include 'changyan.swig' %}
{% include 'gitment.swig' %}
{% include 'valine.swig' %}
-
"\blog\themes\next\layout_third-party\comments\disqus.swig"
這個就是最最基礎的disqus代碼了,也就是disqus官方的代碼。但是它有一堆if來判斷具體怎么加載。但具體的代碼貌似跟官方的不太一樣。
{% if not (theme.duoshuo and theme.duoshuo.shortname) and not theme.duoshuo_shortname %} ///duoshuo不激活才執行
{% if theme.disqus.enable %} ///前面disqus的開關
{% if theme.disqus.count %} ///disqus commment數目顯示
<script id="dsq-count-scr" src="https://{{theme.disqus.shortname}}.disqus.com/count.js" async></script>
{% endif %}
{% if page.comments %}
<script type="text/javascript"> ///disqus核心代碼,script標簽里面包著JavaScript
var disqus_config = function () {
this.page.url = '{{ page.permalink }}';
this.page.identifier = '{{ page.path }}';
this.page.title = '{{ page.title| addslashes }}';
};
var d = document, s = d.createElement('script');
s.src = 'https://{{theme.disqus.shortname}}.disqus.com/embed.js';
s.setAttribute('data-timestamp', '' + +new Date());
(d.head || d.body).appendChild(s);
</script>
{% endif %}
{% endif %}
{% endif %}
- "\blog\themes\next\layout_partials\comments.swig"
hexo next主題只加載一種評論插件的限定就這個在這里實現的。它用連環if語句來控制只實現一種評論插件(通過控制插件參數賦值的方式)
點擊按鈕加載 Disqus
《Hexo Next 主題點擊加載 Disqus》這篇文章講得很清楚。不過我的next 主題版本和它不一樣,所以有一步還是有點區別,反復研究和測試,得出以下步驟。
1.打開需要更改的文件
"\blog\themes\next\layout_partials\comments.swig"
"\blog\themes\next\layout_third-party\comments\disqus.swig"
我用的是EmEditor來編輯,編輯之前可以先備份一下原文件,當然只要不關閉窗口,始終可以ctrl+Z到原文件的狀態的。
2. 添加按鈕
編輯第一個 comments.swig
文件,在文件內容 <div id="disqus_thread">
前面加入下面內容:
<div style="text-align:center;">
<button class="btn" id="load-disqus" onclick="disqus.load();">加載評論</button>
</div>
按鈕樣式我就直接用默認的btn,懶得改了。這里的開關就是onclick="disqus.load()
3.在Disqus的代碼外面外包一層判斷語句
《Hexo Next 主題點擊加載 Disqus》disqus.swig
的代碼和next 5.1.3里面的disqus.swig
長得不太一樣,直接copy過來不能用。研究了一下,是要在disqus核心代碼外面包一層這樣的判斷語句:
var disqus = {
load : function disqus(){
此處是disqus核心代碼
$('#load-disqus').remove(); ///加載后移除按鈕
}
}
}
這個disqus = { load
就對應onclick="disqus.load()
修改之后disqus.swig
是如下內容:
{% if not (theme.duoshuo and theme.duoshuo.shortname) and not theme.duoshuo_shortname %}
{% if theme.disqus.enable %}
{% if theme.disqus.count %}
<script id="dsq-count-scr" src="https://{{theme.disqus.shortname}}.disqus.com/count.js" async></script>
{% endif %}
{% if page.comments %}
<script type="text/javascript">
var disqus = {
load : function disqus(){
var disqus_config = function () {
this.page.url = '{{ page.permalink }}';
this.page.identifier = '{{ page.path }}';
this.page.title = '{{ page.title| addslashes }}';
};
var d = document, s = d.createElement('script');
s.src = 'https://{{theme.disqus.shortname}}.disqus.com/embed.js';
s.setAttribute('data-timestamp', '' + +new Date());
(d.head || d.body).appendChild(s);
$('#load-disqus').remove(); ///加載后移除按鈕
}
}
</script>
{% endif %}
{% endif %}
{% endif %}
我就不用那個disqus計數了。它其實是在標題的下面顯示評論數,評論全是0的時候好難看。而且它一開始就默認加載,墻內用戶會顯示加載到失敗。
同時加載 Disqus 和來必力雙評論系統
上面談到,hexo next是通過comments.swig
里面的if語句和livere.swig
里面的if語句來限定了加載disqus就不繼續加載來必力。最簡單粗暴的解決方法就是,直接把上述兩個文件里面的來必力對應的分支語句copy到disqus的分支。
1.打開需要更改的文件
"\blog\themes\next\layout_partials\comments.swig"
"\blog\themes\next\layout_third-party\comments\disqus.swig"
"\blog\themes\next\layout_third-party\comments\livere.swig"
2.修改comments.swig
中的disqus部分
在里面分別找到兩個插件對應的語句。來必力的語句就是一行,直接插到disqus里面
<div id="disqus_thread">
<noscript>
Please enable JavaScript to view the
<a >comments powered by Disqus.</a>
</noscript>
</div>
<div id="lv-container" data-id="city" data-uid="{{ theme.livere_uid }}"></div> ///livere行
</div>
3.在disqus.swig
里面直接插入來必力核心代碼
先在livere.swig
里面找出來必力的核心代碼:
?
var d = document, s = d.createElement('script');
s.src = 'https://{{theme.disqus.shortname}}.disqus.com/embed.js';
s.setAttribute('data-timestamp', '' + +new Date());
(d.head || d.body).appendChild(s);
(function(d, s) {
var j, e = d.getElementsByTagName(s)[0];
if (typeof LivereTower === 'function') { return; }
j = d.createElement(s);
j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
j.async = true;
e.parentNode.insertBefore(j, e);
})(document, 'script');
?
插入disqus.swig
里面:
{% if not (theme.duoshuo and theme.duoshuo.shortname) and not theme.duoshuo_shortname %}
{% if theme.disqus.enable %}
{% if theme.disqus.count %}
<script id="dsq-count-scr" src="https://{{theme.disqus.shortname}}.disqus.com/count.js" async></script>
{% endif %}
{% if page.comments %}
<script type="text/javascript">
var disqus = {
load : function disqus(){
var disqus_config = function () {
this.page.url = '{{ page.permalink }}';
this.page.identifier = '{{ page.path }}';
this.page.title = '{{ page.title| addslashes }}';
};
var d = document, s = d.createElement('script');
s.src = 'https://{{theme.disqus.shortname}}.disqus.com/embed.js';
s.setAttribute('data-timestamp', '' + +new Date());
(d.head || d.body).appendChild(s);
(function(d, s) {
var j, e = d.getElementsByTagName(s)[0];
if (typeof LivereTower === 'function') { return; }
j = d.createElement(s);
j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
j.async = true;
e.parentNode.insertBefore(j, e);
})(document, 'script');
$('#load-disqus').remove(); ///加載后移除按鈕
}
}
</script>
{% endif %}
{% endif %}
{% endif %}
測試成功
Markdown中分組標題#與有序列表并用時,#必須寫在有序列表的序號前面。用Typora寫作時,必須先按快捷鍵ctrl+數字指定標題的等級,再寫序號。相反操作,就會變成“序號.###”的代碼,雖然在Typora里面預覽沒有問題,但最終渲染成HTML時序號就亂了。