Hexo是和WordPress一样的完善的博客系统,但是好多辅助功能/插件需要是访问谷歌的服务器的,在我大天朝就只能看看了。可是我们勤劳的程序猿们不甘心不那么完美,所以大神们写了各种教程,通过其他的方法解决了因为谷歌而不能使用的功能,
今天就来说说为Hexo博客网站加上的浏览量功能

原理就是使用leancloud作为数据库托管,使用leancloud的API进行操作数据的读取和写入。

leancloud上注册一个账号,然后参考官方文档

html页面引入js

1
2
<!-- 存储服务 -->
<script src="//cdn1.lncld.net/static/js/2.5.0/av-min.js"></script>

在后台管理中新建一个应用
img
初始化,APP_ID和APP_KEY在应用的设置-应用key中查找

1
2
3
4
5
6
7
var APP_ID = 'fasdfaICadjaklsdbaskd-gasdasfz';
var APP_KEY = 'gfdgsArfgsdg';
AV.init({
appId: APP_ID,
appKey: APP_KEY
});
var Todo = AV.Object.extend('test');

你的hexo站的链接地址可能是这样子的img
就是文章的标题作为链接地址,所以用文章的标题来查找和创建数据的唯一标识,用content字段来存储浏览次数;
新增一条数据的方法

1
2
3
4
5
6
7
8
9
10
// 保存
function saveToLeancloud(title){
var newData = new Todo();
newData.save({
title: title,
content: '0'
}).then(function (data) {
console.log(data);
})
}

新增以后要实现浏览/刷新后点击量每次+1,就要更新数据

1
2
3
4
5
6
7
8
9
10
// 更新一条 文章浏览量数据
var _update = function(obj){
// 第一个参数是 className,第二个参数是 objectId
var todo = AV.Object.createWithoutData(className, obj.id);
var count = parseInt(obj.get('content'))+1;
// 修改属性
todo.set('content', count.toString());
// 保存到云端
todo.save();
}

html中加入类名为‘.leancloud_visitors’的元素用来往其中填充数据

1
2
3
<!--我用的是jade模板引擎,#{}就是赋值,ejs、swig等模板请参考对应文档的写法 -->
span(id="#{item.title}", class="leancloud_visitors", data-pageNum="#{page.current}")
// page.current是系统变量直接调用,这个值用来记录列表页的当前页码

获取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var pageCounts = 2;  // 每页返回条数
if($('.leancloud_visitors').attr('data-pageNum')!= 'undefined'){ // 判断是否为列表页
var pageNum = parseInt($('.leancloud_visitors').attr('data-pageNum'))-1; // 当前页码
}
// 获取详情页的访问次数数据
var _getDetailTime = function(title) {
var query = new AV.Query(className);
query.equalTo("title", title);
return query.find();
}

// 获取列表页的访问次数数据
var _getListTime = function(){
var query = new AV.Query(className);
query.limit(pageCounts); // 查询数据时返回的数量-每页返回的条数
query.skip(pageCounts*pageNum); // 查询数据时跳过的数量-当前页码*每页返回的条数
query.descending('createdAt'); // 按新建的时间降序排列
return query.find();
}

然后是填充浏览量数据

1
2
3
4
5
6
7
8
9
10
11
12
// 填充访问次数
var _writeCount = function(data){
if($('.post-page').length == 0){ // 判断是在列表页还是详情页
$('.leancloud_visitors').each(function(i,e){
$(e).text(parseInt(data[i].get('content')));
})
}else{
$('.leancloud_visitors').each(function(i,e){
$(e).text(parseInt(data[i].get('content'))+1);
})
}
}

判断当前在列表页还是详情页

1
2
3
4
5
6
// 判断列表页or详情页
var _isList = function(){
if($('.post-page').length == 0){
return true;
}
}

最终完整的方法写在了一个js文件中,例如leancloudConfig.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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
var leanCloud = (function(){
var APP_ID = 'fasdfaICadjaklsdbaskd-gasdasfz';
var APP_KEY = 'gfdgsArfgsdg';
var className,Todo;
var pageCounts = 2; // 每页返回条数
if($('.leancloud_visitors').attr('data-pageNum')!= 'undefined'){
var pageNum = parseInt($('.leancloud_visitors').attr('data-pageNum'))-1; // 当前页码
}

// 初始化
AV.init({
appId: APP_ID,
appKey: APP_KEY
});

// 新增一条 文章统计数据【仅限一条】
var _addCount = function() {
// 监听 新增按钮 被点击
function addListenButton(){
setTimeout(function(){
console.log('start listen...');
$('.new-post_button').click(function(){addListenInput();})
},5000) //考虑到服务器的带宽仅有1M,网速较慢所以将此方法延迟执行
}
// 监听 回车/点击确定按钮 后 执行保存
function addListenInput(){
var inputTitle;
setTimeout(function(){
$('.new-post_input').blur(function(){
inputTitle = $(this).val();
})
$('.new-post_ok').mousedown(function(){
var title = $('.new-post_input').val();
saveToLeancloud(title);
addListenButton();
})
$(document).keypress(function(e){
if(e.which == 13){
var title = inputTitle;
saveToLeancloud(title);
addListenButton();
}
})
},500)
}

// 保存
function saveToLeancloud(title){
var newData = new Todo();
newData.save({
title: title,
content: '0'
}).then(function (data) {
console.log(data);
})
}
addListenButton();
}

// 获取详情页的访问次数数据
var _getDetailTime = function(title) {
var query = new AV.Query(className);
query.equalTo("title", title);
return query.find();
}

// 获取列表页的访问次数数据
var _getListTime = function(){
var query = new AV.Query(className);
query.limit(pageCounts); // 查询数据时返回的数量-每页返回的条数
query.skip(pageCounts*pageNum); // 查询数据时跳过的数量-当前页码*每页返回的条数
query.descending('createdAt'); // 按新建的时间降序排列
return query.find();
}

// 更新一条 文章浏览量数据
var _update = function(obj){
// 第一个参数是 className,第二个参数是 objectId
var todo = AV.Object.createWithoutData(className, obj.id);
var count = parseInt(obj.get('content'))+1;
// 修改属性
todo.set('content', count.toString());
// 保存到云端
todo.save();
}
// 填充访问次数
var _writeCount = function(data){
if($('.post-page').length == 0){
$('.leancloud_visitors').each(function(i,e){
$(e).text(parseInt(data[i].get('content')));
})
}else{
$('.leancloud_visitors').each(function(i,e){
$(e).text(parseInt(data[i].get('content'))+1);
})
}
}

// 判断列表页or详情页
var _isList = function(){
if($('.post-page').length == 0){
return true;
}
}

var constructor = function(config){}

// 获取浏览量数据
constructor.prototype._getTime = function(clsName){
className = clsName;
Todo = AV.Object.extend(className);
if(_isList()){
_getListTime().then(function(data) {
_writeCount(data);
}, function (error) {
// error is an instance of AVError.
console.log(error);
});
}else{
var title = $('.leancloud_visitors').attr('id');
_getDetailTime(title).then(function(data){
_writeCount(data);
_update(data[0]);
})
}
return this;
}
constructor.prototype._addCount = function(clsName){
className = clsName;
Todo = AV.Object.extend(className);
_addCount();
return this;
}

//返回构造函数
return constructor;
})()

因为我使用的是hexo-admin做后台管理,安装和使用方法见https://github.com/jaredly/hexo-admin
要在hexo-admin的后台中新增文章时自动添加一条数据,就要对其改造:
在根目录的node_modules中搜索hexo-admin,在其文件夹中找到www文件夹下的index.html,在其中引入leancloudConfig.js:

1
2
3
4
5
6
7
8
9
<script src="http://cdn1.lncld.net/static/js/2.5.0/av-min.js"></script>
<script src="/js/leancloudConfig.js"></script>
// 调用方法
<script>
// 创建新blog成功时,访问leancloud新建一条浏览量数据
$(function () {
var todo = new leanCloud()._addCount('test');
});
</script>

在前台页面的layout.jade中同样引入和调用:

1
2
3
4
5
6
7
8
9
script(src= '//cdn1.lncld.net/static/js/2.5.0/av-min.js')
script(src= '/js/leancloudConfig.js')
script.
$(function () {
var todo = new leanCloud()._getTime('test');

// tag添加active
tags.run();
});

这样就实现了浏览量的功能