Hexo_Fluid主题增加点赞、赞善按钮

参考资料

leancloud相关

Netlify

为以下企业服务点赞😘

前言

前言废话文学,想看具体过程可以跳下面的注入器开始读起
实现还是要点时间的,如果时间宝贵,请火速赶往前方~

之前在穿越虫洞的时候,遇到别人博客下面有赞善按钮,就想着去实现

所幸,有跟我一样主题的博主,也有这方面有教程,照着教程的路子,前几天就实现了,具体可参考这篇

然后后面在穿越虫洞的时候,又又又又…发现了别人博客下有点赞按钮,

具体是这篇文章,看了之后很心动,又想要复刻

但这次搜索关键字(Fluid、点赞)没有找到相关的教程

没有办法,小白尝试下自己复刻,记录下实现过程(磨难过程)
所幸的是,磨出来了,有成果意味着成功,如果投入时间却没有成果出来,你会感觉付出不值得,那确实很打击人🤔

另外,我在这篇不建议大家折腾,要注重工具价值,好家伙,才过没两天,疯狂打自己脸,自己先折腾起来了😅

另外的另外,要感谢ChatGPT的大力支持,虽然有时候问东答西,要自己琢磨,但提供整体框架和代码还是非常舒服
如果自己纯手撸,要到哪时候🙃

接下来,小白跟着走,大佬看个乐~

配置

先写下配置,打开_config.yml,注意是根目录下的站点配置文件,而非主题配置文件_config.yml

将以下配置写入,剩下的信息,后面边配置,边填写

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
# 底部按钮组

bottom_btn:
enable: true
reward_btn:
# 打赏按钮
reward_btn_enable: true
reward_btn_icon:
reward_btn_text: 打赏
reward_btn_comment: "如果觉得本文对你有所帮助,请打赏——1元就足够感动我😘"
qrcodes:
- src: /images/wechatpay.jpg
caption: 微信
title: 微信赞赏码
- src: /images/zhifubaopay.jpg
caption: 支付宝
title: 支付宝收款码
like_btn:
# 点赞按钮
like_btn_enable: true
like_btn_icon:
like_hover_btn_icon:
like_btn_text: 点赞
leancloud_id:
leancloud_key:
serverUrl:

  • reward_btn:打赏按钮配置
    • reward_btn_enable:是否开启打赏按钮
    • reward_btn_icon:打赏图标
    • reward_btn_comment:打赏用语
    • qrcodes:图片,照着上面设置即可,然后将二维码放在根目录\source\images即可
  • like_btn:点赞按钮配置
    • like_btn_enable:是否开启点赞按钮
    • like_btn_icon:点赞图标
    • like_hover_btn_icon:点赞后的图标
    • like_btn_text:点赞按钮默认显示的文本
    • leancloud_id:leancloud的应用ID
    • leancloud_key:leancloud的应用key
    • serverUrl:请求云函数的地址

注入器

Hexo注入器
Hexo 注入器 (opens new window) 是 Hexo 5 版本自身加入的一项新功能,所以在所有 Hexo 主题都是支持这个功能的。

先在根目录下新建个scripts,写一个JavaScript文件bottom-button-injector.js

作用:用于将两个按钮注入到Hexo页面中去

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
hexo.extend.injector.register('body_end', function () {

// 打赏按钮变量,解包操作
const {
reward_btn_icon,
reward_btn_text,
reward_btn_comment,
qrcodes,
reward_btn_enable
} = hexo.config.bottom_btn.reward_btn || {};

// 点赞按钮变量,解包操作
const {
like_btn_icon,
like_hover_btn_icon,
like_btn_text,
like_btn_enable,
serverUrl
} = hexo.config.bottom_btn.like_btn || {};

const enable = hexo.config.bottom_btn.enable

if (!enable) {
return null;
}

// 打赏按钮
const rewardButtonScript = reward_btn_enable
? `<script src="/js/reward-button.js"></script>
<script>
new RewardButton({
btnIcon: ${reward_btn_icon ? `"${reward_btn_icon}"` : "null"},
btnText: "${reward_btn_text}",
comment: "${reward_btn_comment}",
qrcodes: ${JSON.stringify(qrcodes)}
}).init();
</script>`
: "";


// 点赞按钮
const likeButtonScript = like_btn_enable
? `<script src="/js/like-button.js"></script>
<script>
new LikeButton({
btnIcon: "${like_btn_icon}",
btnHoverIcon: "${like_hover_btn_icon}",
btnText: "${like_btn_text}",
serverURL:"${serverUrl}"
}).init();
</script>`
: "";

return `
<link defer rel="stylesheet" href="/css/ButtomBtn.css"/>
${rewardButtonScript}
${likeButtonScript}
`;

}, "post");

至此,注入器配置完毕

JavaScript

分别写两个JavaScript文件来实现点赞按钮和赞赏按钮的业务功能

赞赏按钮

打开目录themes\fluid\source\js,在下面创建个reward-button.js,将下面代码粘贴进去

注意,如果是采用npm install,即模块安装主题,那要在这个位置node_modules\hexo-theme-fluid\source\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
// 赞赏按钮功能

function RewardButton(config) {
this.btnIcon = config.btnIcon;
this.btnText = config.btnText;
this.comment = config.comment;
this.qrcodes = config.qrcodes;
}

RewardButton.prototype = {
init: function () {
let btnId = "reward-btn";
let qrcodesId = "reward-qrcodes";

// 赞赏按钮
var btn = document.createElement("button");
btn.id = btnId;
btn.type = "button";
btn.innerHTML = `<i class="iconfont ${this.btnIcon}"></i><span>${this.btnText}</span>`;


// 二维码容器
var qrcodes = document.createElement("div");
qrcodes.id = qrcodesId;

// 按钮容器
var div = document.createElement("div");
div.id = "bottomBtn";
div.style.textAlign = "center";
div.appendChild(btn);
div.innerHTML += `<br><br><span class="image-caption">${this.comment}</span>`;
div.appendChild(qrcodes);

// 将按钮容器插入在文章后面
var postNav = document.querySelector(".post-prevnext");
postNav.parentNode.insertBefore(div, postNav);

// 按钮点击事件
document.getElementById(btnId).onclick = function () {
var container = document.getElementById(qrcodesId);

if (container.childNodes.length == 0) {
for (var i = 0; i < this.qrcodes.length; i++) {
var qrcode = document.createElement("p");
qrcode.className = "reward-qrcode";

var img = document.createElement("img");
img.src = this.qrcodes[i].src;
img.title = this.qrcodes[i].title;
img.alt = this.qrcodes[i].title;

var caption = document.createElement("p");
caption.className = "image-caption";
caption.innerText = this.qrcodes[i].caption;

qrcode.appendChild(img);
qrcode.appendChild(caption);
container.appendChild(qrcode);
}
} else if (container.style.display == "none") {
container.style.removeProperty("display");
} else {
container.style.display = "none";
}
}.bind(this);


},

};

点赞按钮

定位到位置themes\fluid\source\js,创建个JavaScript文件like-button.js,将下面代码粘贴进去

同上,如果是采用模块安装,那要放在这个位置node_modules\hexo-theme-fluid\source\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
138
139
140
141
142
143
function LikeButton(config) {
this.btnIcon = config.btnIcon;
this.btnHoverIcon = config.btnHoverIcon
this.btnText = config.btnText;
this.server_url = config.serverURL;
}

LikeButton.prototype = {
init: function () {
var likeBtn = this;
var btn = document.createElement("button");
btn.id = "like-btn";
btn.type = "button";
btn.innerHTML = `<i class="iconfont ${this.btnIcon}"></i><span>${this.btnText}</span>`;
var objid = null;
editSpan();

btn.addEventListener("click", function () {
// 检查是否已经点过赞,点过忽略
// var likeStatus = getCookie("likeStatus");
// if (likeStatus === "liked") {
// console.log("您已经点过赞了!");
// return;
// }

// id 不为空的话,直接修改文本,否则创建对象
var spanObj = document.querySelector("#like-btn span")
if (objid) {
spanObj.innerText = Number(spanObj.innerText) + 1;
updatePost(objid, spanObj.innerText)
} else {
spanObj.innerText = 1;
createPost()
}
// 设置1天cookie
// setCookie("likeStatus", "liked", 1);

//修改点赞状态
try {
var love_icon = document.querySelector("#like-btn i");
if (love_icon) {
love_icon.classList.remove(likeBtn.btnIcon);
love_icon.classList.add(likeBtn.btnHoverIcon);
}
} catch (TypeError) {
console.error("发生异常:", error);
}
})

// 设置 cookie
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
expires = "; expires=" + date.toGMTString();
}
// 设置cookie的path为当前页面路径
var path = window.location.pathname.replace(/\/[^\/]*$/, '');
document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + expires + "; path=" + path;
}


// 获取 cookie
function getCookie(name) {
var nameEQ = encodeURIComponent(name) + "=";
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i];
while (cookie.charAt(0) == ' ') cookie = cookie.substring(1, cookie.length);
if (cookie.indexOf(nameEQ) == 0) return decodeURIComponent(cookie.substring(nameEQ.length, cookie.length));
}
return null;
}

function editSpan() {
/*
检测对应网址是否有点赞对象
有的话显示数量,拿取对应的objid,方便后续点赞操作
没有的话显示配置文本
*/

var url = `${likeBtn.server_url}/.netlify/functions/like_count/?action=check`;
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = JSON.parse(xhr.responseText);
var targetObj = null;
// 检查所有target是否匹配当前页面
for (var i = 0; i < data.results.length; i++) {
var result = data.results[i];

// 数据库采用中文,这里也要解码成中文对比
if (result.target === decodeURIComponent(window.location.pathname)) {
targetObj = result;
break;
}
}
// 如果找到对应对象,显示对应数量;否则使用配置文本
if (targetObj) {
btn.querySelector("span").innerText = targetObj.count;
objid = targetObj.objectId
}
}
};
xhr.send();
}

function createPost() {
/* 创建对象 */
var url = `${likeBtn.server_url}/.netlify/functions/like_count?action=create&pathname=${window.location.pathname}`;
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
objid = JSON.parse(xhr.responseText).objectId
console.log(`点赞对象创建成功,${objid}`);
}
};
xhr.send();
}

function updatePost(objectId, count) {
/* 更新对象 */
var url = `${likeBtn.server_url}/.netlify/functions/like_count?action=update&objectId=${objectId}&count=${count}`

var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log('点赞+1');
// console.log(xhr.responseText)
}
};
xhr.send();
}

// 插入在赞赏按钮后面
var div = document.querySelector("#reward-btn");
div.insertAdjacentElement("afterend", btn);
},
};

至此,JavaScript文件配置完毕

CSS

定位路径themes\fluid\source\css,新建一个Css文件ButtomBtn.css

同上,如果是模块安装,那要放在这个位置node_modules\hexo-theme-fluid\source\css

代码的具体作用均有注释,可以根据实际需求更改

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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* 按钮样式 */
#reward-btn,
#like-btn {
border-radius: 30px;
padding: 8px 16px;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
border: none;
cursor: pointer;
/* 设置个固定宽度,防止点赞后文本变化,导致按钮自适应缩短 */
width: 100px;

}

/* 调整两个按钮间距 */
#like-btn {
margin-left: 15px;
}

/* 按钮图标与文字间隔 */
#like-btn span,
#reward-btn span{
padding-left: 5px;
font-size: 15px;
}


/* 图标颜色 */
#like-btn i {
color: #b24950;
}
#reward-btn i {
color: #dfc38c;

}

/* 调整图标 */
#like-btn i,
#reward-btn i {
display: inline-block;
width: 1.5em;
height: 20px;
/* vertical-align: middle; */
}

/* 震动动画效果 */
#like-btn:hover i,
#reward-btn:hover i {
animation: shake 0.5s;
/* animation-iteration-count: infinite; */
}


@keyframes shake {

10%,
90% {
transform: translate(-1px, 0);
}

20%,
80% {
transform: translate(2px, 0);
}

30%,
50%,
70% {
transform: translate(-4px, 0);
}

40%,
60% {
transform: translate(4px, 0);
}
}


/* 赞赏按钮大小与动画效果等 */
.reward-qrcode {
display: inline-block;
margin: 1.5rem !important;
width: 10rem;
height: 10rem;
-webkit-animation: show_qrcodes .3s .1s ease both;
-moz-animation: show_qrcodes .3s .1s ease both;
-o-animation: show_qrcodes .3s .1s ease both;
-ms-animation: show_qrcodes .3s .1s ease both;
animation: show_qrcodes .3s .1s ease both;
}

.reward-qrcode img {
margin-top: 0 !important;
}

@-moz-keyframes show_qrcodes {
0% {
opacity: 0;
-webkit-transform: translateY(-10px);
-moz-transform: translateY(-10px);
-o-transform: translateY(-10px);
-ms-transform: translateY(-10px);
transform: translateY(-10px);
}

100% {
opacity: 1;
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-o-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
}
}

@-webkit-keyframes show_qrcodes {
0% {
opacity: 0;
-webkit-transform: translateY(-10px);
-moz-transform: translateY(-10px);
-o-transform: translateY(-10px);
-ms-transform: translateY(-10px);
transform: translateY(-10px);
}

100% {
opacity: 1;
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-o-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
}
}

@-o-keyframes show_qrcodes {
0% {
opacity: 0;
-webkit-transform: translateY(-10px);
-moz-transform: translateY(-10px);
-o-transform: translateY(-10px);
-ms-transform: translateY(-10px);
transform: translateY(-10px);
}

100% {
opacity: 1;
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-o-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
}
}

@keyframes show_qrcodes {
0% {
opacity: 0;
-webkit-transform: translateY(-10px);
-moz-transform: translateY(-10px);
-o-transform: translateY(-10px);
-ms-transform: translateY(-10px);
transform: translateY(-10px);
}

100% {
opacity: 1;
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-o-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
}
}

至此,按钮样式配置完毕

图标

图标个人采用的是阿里的图标库

先说下怎么添加自定义图标,下面也会提供个人在用的图标

两个方式选择一种即可

自定义图标

先搜索自己要的图标

image-20230415220540996

选择一款中意的加入购物车

image-20230415220627628

挑选完后,点击上方的购物车

image-20230415220707712

点击添加至项目

image-20230415220746477

点击这里,生成一个CDN链接

这里也可以直接使用CDN来使用图标,但因为提示仅供体验和调试

所以下载到自己的项目会比较保险一点,防止404加载不出来

image-20230415220929393

之后点击链接

image-20230415221005439

会打开一个页面,将这里的css代码都复制下来

image-20230415221138991

打开你hexo的站点文件夹,定位到themes\fluid\source\css

如果是使用模块安装的fluid主题,定位到node_modules\hexo-theme-fluid\source\css

新建个travelling.css,或者要可以自己命名

之后返回刚才的页面,选择下载至本地,是一个压缩包,下载后解压出来

image-20230415221528075

打开download文件夹,将里面的文件夹重新命名为icont-font

将这个文件夹放到themes\fluid\source\css位置,如图所示

image-20230415221738335

之后修改下travelling.css,将前面三行url修改下,原先是采用网络,现在改成引用自己项目的资源

原先

1
2
3
4
5
6
@font-face {
font-family: "iconfont"; /* Project id 4012526 */
src: url('//at.alicdn.com/t/c/font_4012526_9quof0837i.woff2?t=1681567787526') format('woff2'),
url('//at.alicdn.com/t/c/font_4012526_9quof0837i.woff?t=1681567787526') format('woff'),
url('//at.alicdn.com/t/c/font_4012526_9quof0837i.ttf?t=1681567787526') format('truetype');
}

修改后

1
2
3
4
5
6
7
@font-face {
font-family: "iconfont";
/* Project id 4012526 */
src: url('icont-font/iconfont.woff2') format('woff2'),
url('icont-font/iconfont.woff') format('woff'),
url('icont-font/iconfont.ttf') format('truetype');
}

博主使用

如果不自定义,也可以通过这个阿里云链接下载到目前个人在用的点赞和赞赏图标

直接放在themes\fluid\source\css位置下

然后创建个travelling.css,将下面代码粘贴进去保存即可

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
@font-face {
font-family: "iconfont";
/* Project id 4012526 */
src: url('icont-font/iconfont.woff2') format('woff2'),
url('icont-font/iconfont.woff') format('woff'),
url('icont-font/iconfont.ttf') format('truetype');
}

.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

.icon-yue1:before {
content: "\e665";
}

.icon-money:before {
content: "\e62e";
}

.icon-l-money:before {
content: "\e79c";
}

.icon-uf_money:before {
content: "\e62f";
}

.icon-money1:before {
content: "\e612";
}

.icon-moneycollect:before {
content: "\e7cd";
}

.icon-icon_love_hover:before {
content: "\e69c";
}

.icon-icon_love:before {
content: "\e69d";
}

.icon-money-funds:before {
content: "\e831";
}

.icon-huochecheci:before {
content: "\e685";
}

配置

下载完文件后,接下来要配置下配置文件

打开站点配置文件config.yml

将点赞和赞赏的图标类名分别写入like_btn_iconreward_btn_icon

例如:

image-20230415222521700

  • 点赞的图标名字是icon-icon_love,那就在like_btn_icon填入iconfont reward_btn_icon
  • 点赞后的图标名字是icon-icon_love_hover,那就在like_hover_btn_icon填入icon-icon_love_hover
  • 赞赏的图标名字是reward_btn_icon,那就在reward_btn_icon填写:iconfont reward_btn_icon

自定义图标的,填写自己挑选的图标的名字即可,参照博主的,使用我的文件的,直接使用下面的名字即可

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
bottom_btn:
enable: true
reward_btn:
# 打赏按钮
reward_btn_enable: true
reward_btn_icon: iconfont icon-money
reward_btn_text: 打赏
reward_btn_comment: "如果觉得本文对你有所帮助,请打赏——1元就足够感动我😘"
qrcodes:
- src: /images/wechatpay.jpg
caption: 微信
title: 微信赞赏码
- src: /images/zhifubaopay.jpg
caption: 支付宝
title: 支付宝收款码
like_btn:
# 点赞按钮
like_btn_enable: true
like_btn_icon: icon-icon_love
like_hover_btn_icon: icon-icon_love_hover
like_btn_text: 点赞
leancloud_id:
leancloud_key:
serverUrl:

至此,图标配置完毕

数据库

这里使用国际版或者国内版都可以

创建应用

已有应用可以忽略这一步

登录,点击左上角按钮,进入应用页面

image-20230415214956207

点击按钮,创建个leancloud的应用

image-20230415215029608

随便起个名字,确定即可

image-20230415215117429

点击新建应用的数据存储,进入应用

image-20230415215235956

新建类

新建个Like

image-20230415215341146

image-20230415215531291

密钥

接下里要获取下密钥信息,用于config配置文件

点击按钮,打开侧边栏

image-20230415215629375

选择设置-应用凭证

image-20230415215727865

将这里的信息填入config.yml对应的位置

这里说下,我这个是Demo应用,过后就删除了,所以不用特意去记我的密钥,没用

image-20230415215824397

配置

打开config.yml文件,将上面得到的信息填入

  • AppID填入leancloud_key
  • MasterKey填入leancloud_key

注:这里的leancloud_key必须采用MasterKey,而不是AppKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
bottom_btn:
enable: true
reward_btn:
# 打赏按钮
reward_btn_enable: true
reward_btn_icon: iconfont icon-money
reward_btn_text: 打赏
reward_btn_comment: "如果觉得本文对你有所帮助,请打赏——1元就足够感动我😘"
qrcodes:
- src: /images/wechatpay.jpg
caption: 微信
title: 微信赞赏码
- src: /images/zhifubaopay.jpg
caption: 支付宝
title: 支付宝收款码
like_btn:
# 点赞按钮
like_btn_enable: true
like_btn_icon: iconfont icon-icon_love
like_btn_text: 点赞
leancloud_id: RQMd3w90p14fUiKvMsLEjUdk-gzGzoHsz
leancloud_key: NHKmK8zO9lZaMLHWmoJuGRNc
serverUrl:

至此,数据库配置完毕

云函数

这里讲下,因为我们要使用到leancloud作为数据库,要使用到API

KEYID是不能直接写在客户端(JavaScript),否则人家调试,可以直接拿到KEYID,能间接操作你的数据库

所以要将KEYID或者说API相关的操作放在服务端

由于个人只有本地服务器,没有云服务器,所以只能白嫖Netlify的云函数来跑

如果有云服务器,可以专门放个端口专门跑这个代码,给外部提供个接口

由于我没有云服务器可以实践,所以给不了具体的指导,想使用自己云服务器的也可以自己琢磨下

Netlify云函数这块其实也不懂,参考文档,琢磨文档

只能说能用,但不懂🙃,也就刚好能运行云函数,能跑就行~

安装模块

具体来说,先创建个文件夹Netlify_func,命名随意不影响

cmd进入这个文件,安装下NetlifyCLI模块

1
npm install netlify-cli -g

登录授权

运行以下命令,进行身份验证和获取访问令牌

image-20230415211145924

1
netlify login

杀毒软件有通知的话,放行下

image-20230415211130975

这将打开一个浏览器窗口,要求您使用 Netlify 登录并授予对Netlify CLI 的访问权限,直接选择同意即可

image-20230415211214825

点击后,如图所示,提示已经授权,关闭页面即可

image-20230415211237652

获得授权后,Netlify CLI 会将您的访问令牌存储在config.json全局配置文件中。

具体的位置:

  • 苹果系统:Library/Preferences/netlify/config.json
  • Linux:.config/netlify/config.json
  • window:AppData\Roaming\netlify\Config\config.json

建立站点

运行命令

1
netlify init

会询问你是要绑定仓库,还是建立一个没有的git的站点,这里个人暂时没有使用git

所以先选择第一个,yes

这里的步骤,也可以先写本地云函数脚本,然后git推送到远程仓库

然后使用第二个绑定远程的仓库,都行,看个人具体操作

image-20230415210933396

英文翻译过来的意思

1
2
3
4
5
6
7
8
9
10
11
No git remote was found, would you like to set one up?
It is recommended that you initialize a site that has a remote repository in GitHub.
This will allow for Netlify Continuous deployment to build branch & PR previews.
For more details on Netlify CI checkout the docs: http://bit.ly/2N0Jhy5
? Do you want to create a Netlify site without a git repository? (Use arrow keys)

找不到git遥控器,你想设置一个吗?
建议您初始化在GitHub中具有远程存储库的站点。
这将允许Netlify连续部署来构建分支机构和PR预览。
有关Netlify CI签出文档的更多详细信息:http://bit.ly/2N0Jhy5
? 您想创建一个没有git存储库的Netlify网站吗?(使用箭头键)

会询问你选择哪个团队Team,如果只有一个,回车就是

image-20230415211931269

再接着,让你给站点项目起个名字,直接回车的话随机命名,随意,个人直接回车

image-20230415211959564

创建后的提示(该站点总结完笔记个人会删除,所以不用测试链接了)

image-20230415212057305

这里第二个地址,就是我们配置文件要填写的云函数地址serverUrl

当然现在只是建立了站点,云函数功能还没实现

打开Netlify的站点,也可以发现创建了一个站点

Netlify网址:官网,方便打开

image-20230415212351061

不过,点进去,可以发现暂时是没有云函数的

image-20230415212551978

创建函数

接下来就是创建云函数和部署到站点

在这个云函数文件夹根目录(也就是我上面创建的Netlify_func),使用cmd进入

运行命令:netlify functions:create

先让Netlify创建个示例文件,等下直接修改就行

第1步问你,采用什么云函数,选择第二个Serverless即可

image-20230415213203903

第2步问你,采用什么语言,选择JavaScript

image-20230415213301129

第3步问题,采用什么模板文件,选择auth-fetch即可(无关紧要,后面要修改)

image-20230415213348196

第4步,给项目起个名字,这里输入一个项目名字即可,我这里输入like_count

image-20230415213526778

创建后的文件结构,如图所示

1
2
3
4
5
6
7
8
9
10
11
Demo
├── .gitignore
├── .netlify
│ └── state.json
└── netlify
└── functions
└── like_count
├── like_count.js
├── node_modules
├── package-lock.json
└── package.json

先在functions文件夹下新建一个config.js用于存储我们的KeyID
将自己leancloudIDKey填写进去

注:这里的IDKEY个人仅做Demo演示,后续会删除应用

1
2
3
4
module.exports = {
LC_APP_ID: 'RQMd3w90p14fUiKvMsLEjUdk-gzGzoHsz',
LC_APP_KEY: 'NHKmK8zO9lZaMLHWmoJuGRNc',
};

打开like_count.js文件,将代码全部清空,将以下全部代码复制粘贴进去,不用进行任何修改

这里主要是3个函数,对leancloud数据库的操作(更新对象、查询对象、创建对象)

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
138
139
140
const fetch = require('node-fetch');
const config = require('./config');

const responseHeaders = {
'Access-Control-Allow-Origin': 'http://localhost:4000',
'Access-Control-Allow-Methods': 'GET',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Headers': 'Content-Type',
};

const checkLikeCount = async function () {
const url = 'https://bfrlyu2d.lc-cn-n1-shared.com/1.1/classes/Like';
const headers = {
'Content-Type': 'application/json',
'X-LC-Id': config.LC_APP_ID,
'X-LC-Key': config.LC_APP_KEY,
};
try {
const response = await fetch(url, { headers });
if (!response.ok) {
// NOT res.status >= 200 && res.status < 300
return { statusCode: response.status, body: response.statusText };
}
const data = await response.json();

return {
statusCode: 200,
headers: responseHeaders,
body: JSON.stringify(data),
};
} catch (error) {
console.log(error);
return {
statusCode: 500,
headers: responseHeaders,
body: JSON.stringify({ msg: error.message }),
};
}
};

const createLikeCount = async function (pathname) {
console.log('run create')
const url = 'https://bfrlyu2d.lc-cn-n1-shared.com/1.1/classes/Like'
const headers = {
'Content-Type': 'application/json',
'X-LC-Id': config.LC_APP_ID,
'X-LC-Key': config.LC_APP_KEY,
}
try {
const response = await fetch(url, {
headers,
method: 'POST',
body: JSON.stringify({
count: 1,
target: pathname,
}),
})
if (!response.ok) {
// NOT res.status >= 200 && res.status < 300
return { statusCode: response.status, body: response.statusText }
}
const data = await response.json()

return {
statusCode: 200,
headers: responseHeaders,
body: JSON.stringify(data),
}
} catch (error) {
console.log(error)
return {
statusCode: 500,
headers: responseHeaders,
body: JSON.stringify({ msg: error.message }),
}
}
}

const updateLikeCount = async function (objectId, count) {
const url = `https://bfrlyu2d.lc-cn-n1-shared.com/1.1/classes/Like/${objectId}`;
const headers = {
'Content-Type': 'application/json',
'X-LC-Id': config.LC_APP_ID,
'X-LC-Key': config.LC_APP_KEY,
};
try {
const response = await fetch(url, {
headers,
method: 'PUT',
body: JSON.stringify({ count: Number(count) }),
});
if (!response.ok) {
// NOT res.status >= 200 && res.status < 300
return { statusCode: response.status, body: response.statusText };
}
const data = await response.json();

return {
statusCode: 200,
headers: responseHeaders,
body: JSON.stringify(data),
};
} catch (error) {
console.log(error);
return {
statusCode: 500,
headers: responseHeaders,
body: JSON.stringify({ msg: error.message }),
};
}
};

const myFunction = async function (event, context) {
if (event && event.queryStringParameters && event.queryStringParameters.action === 'check') {
return await checkLikeCount();
} else if (
event &&
event.queryStringParameters &&
event.queryStringParameters.action === 'update' &&
event.queryStringParameters.objectId &&
event.queryStringParameters.count
) {
const objectId = event.queryStringParameters.objectId;
const count = event.queryStringParameters.count;
return await updateLikeCount(objectId, count);
} else if (
event &&
event.queryStringParameters &&
event.queryStringParameters.action === 'create' &&
event.queryStringParameters.pathname
) {
const target = event.queryStringParameters.pathname;
return await createLikeCount(target);
}
};


exports.handler = async (event, context) => {
return await myFunction(event, context);
};

部署

在根目录下运行cmd,执行部署命令:netlify deploy --prod

如果是只在文件夹局部安装模块,采用npx netlify deploy --prod

如果上面跟我一致的话,就直接运行netlify deploy --prod即可

会询问你发布的目录,这里直接回车即可(也就是将当前目录都发布到站点上去)

image-20230415214547498

稍微等一下,会部署到站点,部署后如图所示

image-20230415214702581

配置

将上面部署后,得到的提示信息中的Website URL填入config.yml即可

打开config.yml,将网址填入serverUrl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
bottom_btn:
enable: true
reward_btn:
# 打赏按钮
reward_btn_enable: true
reward_btn_icon: iconfont icon-money
reward_btn_text: 打赏
reward_btn_comment: "如果觉得本文对你有所帮助,请打赏——1元就足够感动我😘"
qrcodes:
- src: /images/wechatpay.jpg
caption: 微信
title: 微信赞赏码
- src: /images/zhifubaopay.jpg
caption: 支付宝
title: 支付宝收款码
like_btn:
# 点赞按钮
like_btn_enable: true
like_btn_icon: iconfont icon-icon_love
like_btn_text: 点赞
leancloud_id: RQMd3w90p14fUiKvMsLEjUdk-gzGzoHsz
leancloud_key: NHKmK8zO9lZaMLHWmoJuGRNc
serverUrl: https://delightful-marshmallow-761733.netlify.app

至此,云函数部署完成

后话

至此,全部config.yml均已配置完成

之后Hexo运行三件套,应该就能看到效果了

  • hexo clean
  • hexo g
  • hexo s

如果期间有遇到问题,也欢迎给我留言咨询~


Hexo_Fluid主题增加点赞、赞善按钮
https://linguoguang.com/2023/04/15/Hexo_Fluid主题增加点赞、赞善按钮/
作者
linguoguang
发布于
2023年4月15日
许可协议