实时预览编辑

参考自:Hexo 实现实时预览编辑 | 木头的博客 (mutoe.com)

主要在项目目录下安装 hexo-browsersync 插件

1
npm install hexo-browsersync --save

然后运行 hexo server, 看到以下内容就说明启动成功啦.【针对_config.Butterfly.yml需要重启hexo s】

1
2
3
4
5
6
7
8
[Browsersync] Access URLs:
----------------------------------
UI: http://localhost:3001
----------------------------------
UI External: http://localhost:3001
----------------------------------
INFO Start processing
INFO Hexo is running at http://localhost:4000/ . Press Ctrl+C to stop.

图床引入

解决hexo引入图床,手机和web不显示图片的问题

这里以Butterfly主题为例

在butterfly\layout\includes\head.pug中【其中加号为需要添加的】

1
2
3
4
5
meta(name="author" content=pageAuthor)
meta(name="copyright" content=pageCopyright)
meta(name ="format-detection" content="telephone=no")
meta(name="theme-color" content=themeColor)
+ meta(name="referrer" content="no-referrer")

加载进度条

这里就直接上效果比较Nice一种方式咯

css文件

在/themes/butterfly/source/css/`新建一个css文件,名字自定义,这里我就以loading-bar.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
.pace {
-webkit-pointer-events: none;
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
z-index: 2000;
position: fixed;
margin: auto;
top: 4px;
left: 0;
right: 0;
height: 8px;
border-radius: 8px;
width: 4rem;
background: #eaecf2;
border: 1px #e3e8f7;
overflow: hidden
}

.pace-inactive .pace-progress {
opacity: 0;
transition: .3s ease-in
}

.pace .pace-progress {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
max-width: 200px;
position: absolute;
z-index: 2000;
display: block;
top: 0;
right: 100%;
height: 100%;
width: 100%;
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
animation: gradient 1.5s ease infinite;
background-size: 200%
}

.pace.pace-inactive {
opacity: 0;
transition: .3s;
top: -8px
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}

关于进度条的颜色修改主要修改如下即可

1
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);

渐变网站推荐:

Grabient

uiGradients - Beautiful colored gradients

关于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
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
/*!
* pace.js v1.2.4
* https://github.com/CodeByZach/pace/
* Licensed MIT © HubSpot, Inc.
*/
!
function() {
function o(t, e) {
return function() {
return t.apply(e, arguments)
}
}
var u, c, i, s, n, y, t, l, v, r, a, p, e, h, w, b, f, g, d, m, k, S, q, L, x, P, T, R, j, O, E, M, A, C, N, _, F, U, W, X, D, H, I, z, G, B, J = [].slice,
K = {}.hasOwnProperty,
Q = function(t, e) {
for (var n in e) K.call(e, n) && (t[n] = e[n]);
function r() {
this.constructor = t
}
return r.prototype = e.prototype,
t.prototype = new r,
t.__super__ = e.prototype,
t
},
V = [].indexOf ||
function(t) {
for (var e = 0,
n = this.length; e < n; e++) if (e in this && this[e] === t) return e;
return - 1
};
function Y() {}
for (g = {
className: "",
catchupTime: 100,
initialRate: .03,
minTime: 250,
ghostTime: 100,
maxProgressPerFrame: 20,
easeFactor: 1.25,
startOnPageLoad: !0,
restartOnPushState: !0,
restartOnRequestAfter: 500,
target: "body",
elements: {
checkInterval: 100,
selectors: ["body"]
},
eventLag: {
minSamples: 10,
sampleCount: 3,
lagThreshold: 3
},
ajax: {
trackMethods: ["GET"],
trackWebSockets: !0,
ignoreURLs: []
}
},
P = function() {
var t;
return null != (t = "undefined" != typeof performance && null !== performance && "function" == typeof performance.now ? performance.now() : void 0) ? t: +new Date
},
R = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame, f = window.cancelAnimationFrame || window.mozCancelAnimationFrame, p = function(t, e, n) {
if ("function" == typeof t.addEventListener) return t.addEventListener(e, n, !1);
var r;
"function" != typeof t["on" + e] || "object" != typeof t["on" + e].eventListeners ? (r = new s, "function" == typeof t["on" + e] && r.on(e, t["on" + e]), t["on" + e] = function(t) {
return r.trigger(e, t)
},
t["on" + e].eventListeners = r) : r = t["on" + e].eventListeners,
r.on(e, n)
},
null == R && (R = function(t) {
return setTimeout(t, 50)
},
f = function(t) {
return clearTimeout(t)
}), O = function(e) {
var n = P(),
r = function() {
var t = P() - n;
return 33 <= t ? (n = P(), e(t,
function() {
return R(r)
})) : setTimeout(r, 33 - t)
};
return r()
},
j = function() {
var t = arguments[0],
e = arguments[1],
n = 3 <= arguments.length ? J.call(arguments, 2) : [];
return "function" == typeof t[e] ? t[e].apply(t, n) : t[e]
},
d = function() {
for (var t, e, n, r = arguments[0], s = 2 <= arguments.length ? J.call(arguments, 1) : [], o = 0, i = s.length; o < i; o++) if (e = s[o]) for (t in e) K.call(e, t) && (n = e[t], null != r[t] && "object" == typeof r[t] && null != n && "object" == typeof n ? d(r[t], n) : r[t] = n);
return r
},
h = function(t) {
for (var e, n, r = e = 0,
s = 0,
o = t.length; s < o; s++) n = t[s],
r += Math.abs(n),
e++;
return r / e
},
k = function(t, e) {
var n, r;
if (null == t && (t = "options"), null == e && (e = !0), r = document.querySelector("[data-pace-" + t + "]")) {
if (n = r.getAttribute("data-pace-" + t), !e) return n;
try {
return JSON.parse(n)
} catch(t) {
return "undefined" != typeof console && null !== console ? console.error("Error parsing inline pace options", t) : void 0
}
}
},
Y.prototype.on = function(t, e, n, r) {
var s;
return null == r && (r = !1),
null == this.bindings && (this.bindings = {}),
null == (s = this.bindings)[t] && (s[t] = []),
this.bindings[t].push({
handler: e,
ctx: n,
once: r
})
},
Y.prototype.once = function(t, e, n) {
return this.on(t, e, n, !0)
},
Y.prototype.off = function(t, e) {
var n, r, s;
if (null != (null != (r = this.bindings) ? r[t] : void 0)) {
if (null == e) return delete this.bindings[t];
for (n = 0, s = []; n < this.bindings[t].length;) this.bindings[t][n].handler === e ? s.push(this.bindings[t].splice(n, 1)) : s.push(n++);
return s
}
},
Y.prototype.trigger = function() {
var t, e, n, r, s, o, i = arguments[0],
a = 2 <= arguments.length ? J.call(arguments, 1) : [];
if (null != (r = this.bindings) && r[i]) {
for (n = 0, o = []; n < this.bindings[i].length;) e = (s = this.bindings[i][n]).handler,
t = s.ctx,
s = s.once,
e.apply(null != t ? t: this, a),
s ? o.push(this.bindings[i].splice(n, 1)) : o.push(n++);
return o
}
},
B = Y, y = window.Pace || {},
window.Pace = y, d(y, B.prototype), T = y.options = d({},
g, window.paceOptions, k()), X = 0, H = (z = ["ajax", "document", "eventLag", "elements"]).length; X < H; X++) ! 0 === T[C = z[X]] && (T[C] = g[C]);
function Z() {
return Z.__super__.constructor.apply(this, arguments)
}
function $() {
this.progress = 0
}
function tt() {
this.bindings = {}
}
function et() {
var e, o = this;
et.__super__.constructor.apply(this, arguments),
e = function(r) {
var s = r.open;
return r.open = function(t, e, n) {
return A(t) && o.trigger("request", {
type: t,
url: e,
request: r
}),
s.apply(r, arguments)
}
},
window.XMLHttpRequest = function(t) {
t = new W(t);
return e(t),
t
};
try {
m(window.XMLHttpRequest, W)
} catch(t) {}
if (null != U) {
window.XDomainRequest = function() {
var t = new U;
return e(t),
t
};
try {
m(window.XDomainRequest, U)
} catch(t) {}
}
if (null != F && T.ajax.trackWebSockets) {
window.WebSocket = function(t, e) {
var n = null != e ? new F(t, e) : new F(t);
return A("socket") && o.trigger("request", {
type: "socket",
url: t,
protocols: e,
request: n
}),
n
};
try {
m(window.WebSocket, F)
} catch(t) {}
}
}
function nt() {
this.complete = o(this.complete, this);
var t = this;
this.elements = [],
S().on("request",
function() {
return t.watch.apply(t, arguments)
})
}
function rt(t) {
var e, n, r, s;
for (null == t && (t = {}), this.complete = o(this.complete, this), this.elements = [], null == t.selectors && (t.selectors = []), n = 0, r = (s = t.selectors).length; n < r; n++) e = s[n],
this.elements.push(new i(e, this.complete))
}
function st(t, e) {
this.selector = t,
this.completeCallback = e,
this.progress = 0,
this.check()
}
function ot() {
var t, e, n = this;
this.progress = null != (e = this.states[document.readyState]) ? e: 100,
t = document.onreadystatechange,
document.onreadystatechange = function() {
return null != n.states[document.readyState] && (n.progress = n.states[document.readyState]),
"function" == typeof t ? t.apply(null, arguments) : void 0
}
}
function it(t) {
this.source = t,
this.last = this.sinceLastUpdate = 0,
this.rate = T.initialRate,
this.catchup = 0,
this.progress = this.lastProgress = 0,
null != this.source && (this.progress = j(this.source, "progress"))
}
B = Error,
Q(Z, B),
n = Z,
$.prototype.getElement = function() {
var t;
if (null == this.el) {
if (! (t = document.querySelector(T.target))) throw new n;
this.el = document.createElement("div"),
this.el.className = "pace pace-active",
document.body.className = document.body.className.replace(/(pace-done )|/, "pace-running ");
var e = "" !== T.className ? " " + T.className: "";
this.el.innerHTML = '<div class="pace-progress' + e + '">\n <div class="pace-progress-inner"></div>\n</div>\n<div class="pace-activity"></div>',
null != t.firstChild ? t.insertBefore(this.el, t.firstChild) : t.appendChild(this.el)
}
return this.el
},
$.prototype.finish = function() {
var t = this.getElement();
return t.className = t.className.replace("pace-active", "pace-inactive"),
document.body.className = document.body.className.replace("pace-running ", "pace-done ")
},
$.prototype.update = function(t) {
return this.progress = t,
y.trigger("progress", t),
this.render()
},
$.prototype.destroy = function() {
try {
this.getElement().parentNode.removeChild(this.getElement())
} catch(t) {
n = t
}
return this.el = void 0
},
$.prototype.render = function() {
var t, e, n, r, s, o, i;
if (null == document.querySelector(T.target)) return ! 1;
for (t = this.getElement(), r = "translate3d(" + this.progress + "%, 0, 0)", s = 0, o = (i = ["webkitTransform", "msTransform", "transform"]).length; s < o; s++) e = i[s],
t.children[0].style[e] = r;
return (!this.lastRenderedProgress || this.lastRenderedProgress | 0 !== this.progress | 0) && (t.children[0].setAttribute("data-progress-text", (0 | this.progress) + "%"), 100 <= this.progress ? n = "99": (n = this.progress < 10 ? "0": "", n += 0 | this.progress), t.children[0].setAttribute("data-progress", "" + n)),
y.trigger("change", this.progress),
this.lastRenderedProgress = this.progress
},
$.prototype.done = function() {
return 100 <= this.progress
},
c = $,
tt.prototype.trigger = function(t, e) {
var n, r, s, o, i;
if (null != this.bindings[t]) {
for (i = [], r = 0, s = (o = this.bindings[t]).length; r < s; r++) n = o[r],
i.push(n.call(this, e));
return i
}
},
tt.prototype.on = function(t, e) {
var n;
return null == (n = this.bindings)[t] && (n[t] = []),
this.bindings[t].push(e)
},
s = tt,
W = window.XMLHttpRequest,
U = window.XDomainRequest,
F = window.WebSocket,
m = function(t, e) {
var n, r = [];
for (n in e.prototype) try {
null == t[n] && "function" != typeof e[n] ? "function" == typeof Object.defineProperty ? r.push(Object.defineProperty(t, n, {
get: function(t) {
return function() {
return e.prototype[t]
}
} (n),
configurable: !0,
enumerable: !0
})) : r.push(t[n] = e.prototype[n]) : r.push(void 0)
} catch(t) {
0
}
return r
},
L = [],
y.ignore = function() {
var t = arguments[0],
e = 2 <= arguments.length ? J.call(arguments, 1) : [];
return L.unshift("ignore"),
e = t.apply(null, e),
L.shift(),
e
},
y.track = function() {
var t = arguments[0],
e = 2 <= arguments.length ? J.call(arguments, 1) : [];
return L.unshift("track"),
e = t.apply(null, e),
L.shift(),
e
},
A = function(t) {
if (null == t && (t = "GET"), "track" === L[0]) return "force";
if (!L.length && T.ajax) {
if ("socket" === t && T.ajax.trackWebSockets) return ! 0;
if (t = t.toUpperCase(), 0 <= V.call(T.ajax.trackMethods, t)) return ! 0
}
return ! 1
},
Q(et, s),
t = et,
D = null,
M = function(t) {
for (var e, n = T.ajax.ignoreURLs,
r = 0,
s = n.length; r < s; r++) if ("string" == typeof(e = n[r])) {
if ( - 1 !== t.indexOf(e)) return ! 0
} else if (e.test(t)) return ! 0;
return ! 1
},
(S = function() {
return D = null == D ? new t: D
})().on("request",
function(t) {
var o, i = t.type,
a = t.request,
e = t.url;
if (!M(e)) return y.running || !1 === T.restartOnRequestAfter && "force" !== A(i) ? void 0 : (o = arguments, "boolean" == typeof(e = T.restartOnRequestAfter || 0) && (e = 0), setTimeout(function() {
var t, e, n, r, s = "socket" === i ? a.readyState < 1 : 0 < (s = a.readyState) && s < 4;
if (s) {
for (y.restart(), r = [], t = 0, e = (n = y.sources).length; t < e; t++) {
if ((C = n[t]) instanceof u) {
C.watch.apply(C, o);
break
}
r.push(void 0)
}
return r
}
},
e))
}),
nt.prototype.watch = function(t) {
var e = t.type,
n = t.request,
t = t.url;
if (!M(t)) return n = new("socket" === e ? r: a)(n, this.complete),
this.elements.push(n)
},
nt.prototype.complete = function(e) {
return this.elements = this.elements.filter(function(t) {
return t !== e
})
},
u = nt,
a = function(e, n) {
var t, r, s, o, i = this;
if (this.progress = 0, null != window.ProgressEvent) for (p(e, "progress",
function(t) {
return t.lengthComputable ? i.progress = 100 * t.loaded / t.total: i.progress = i.progress + (100 - i.progress) / 2
}), t = 0, r = (o = ["load", "abort", "timeout", "error"]).length; t < r; t++) p(e, o[t],
function() {
return n(i),
i.progress = 100
});
else s = e.onreadystatechange,
e.onreadystatechange = function() {
var t;
return 0 === (t = e.readyState) || 4 === t ? (n(i), i.progress = 100) : 3 === e.readyState && (i.progress = 50),
"function" == typeof s ? s.apply(null, arguments) : void 0
}
},
r = function(t, e) {
for (var n, r = this,
s = this.progress = 0,
o = (n = ["error", "open"]).length; s < o; s++) p(t, n[s],
function() {
return e(r),
r.progress = 100
})
},
rt.prototype.complete = function(e) {
return this.elements = this.elements.filter(function(t) {
return t !== e
})
},
k = rt,
st.prototype.check = function() {
var t = this;
return document.querySelector(this.selector) ? this.done() : setTimeout(function() {
return t.check()
},
T.elements.checkInterval)
},
st.prototype.done = function() {
return this.completeCallback(this),
this.completeCallback = null,
this.progress = 100
},
i = st,
ot.prototype.states = {
loading: 0,
interactive: 50,
complete: 100
},
B = ot,
Q = function() {
var e, n, r, s, o, i = this;
this.progress = 0,
o = [],
s = 0,
r = P(),
n = setInterval(function() {
var t = P() - r - 50;
return r = P(),
o.push(t),
o.length > T.eventLag.sampleCount && o.shift(),
e = h(o),
++s >= T.eventLag.minSamples && e < T.eventLag.lagThreshold ? (i.progress = 100, clearInterval(n)) : i.progress = 3 / (e + 3) * 100
},
50)
},
it.prototype.tick = function(t, e) {
return 100 <= (e = null == e ? j(this.source, "progress") : e) && (this.done = !0),
e === this.last ? this.sinceLastUpdate += t: (this.sinceLastUpdate && (this.rate = (e - this.last) / this.sinceLastUpdate), this.catchup = (e - this.progress) / T.catchupTime, this.sinceLastUpdate = 0, this.last = e),
e > this.progress && (this.progress += this.catchup * t),
e = 1 - Math.pow(this.progress / 100, T.easeFactor),
this.progress += e * this.rate * t,
this.progress = Math.min(this.lastProgress + T.maxProgressPerFrame, this.progress),
this.progress = Math.max(0, this.progress),
this.progress = Math.min(100, this.progress),
this.lastProgress = this.progress,
this.progress
},
v = it,
b = e = _ = w = E = N = null,
y.running = !1,
q = function() {
if (T.restartOnPushState) return y.restart()
},
null != window.history.pushState && (I = window.history.pushState, window.history.pushState = function() {
return q(),
I.apply(window.history, arguments)
}),
null != window.history.replaceState && (G = window.history.replaceState, window.history.replaceState = function() {
return q(),
G.apply(window.history, arguments)
}),
l = {
ajax: u,
elements: k,
document: B,
eventLag: Q
},
(x = function() {
var t, e, n, r, s, o, i, a;
for (y.sources = N = [], e = 0, r = (o = ["ajax", "elements", "document", "eventLag"]).length; e < r; e++) ! 1 !== T[t = o[e]] && N.push(new l[t](T[t]));
for (n = 0, s = (a = null != (i = T.extraSources) ? i: []).length; n < s; n++) C = a[n],
N.push(new C(T));
return y.bar = w = new c,
E = [],
_ = new v
})(),
y.stop = function() {
return y.trigger("stop"),
y.running = !1,
w.destroy(),
b = !0,
null != e && ("function" == typeof f && f(e), e = null),
x()
},
y.restart = function() {
return y.trigger("restart"),
y.stop(),
y.start()
},
y.go = function() {
var m;
return y.running = !0,
w.render(),
m = P(),
b = !1,
e = O(function(t, e) {
w.progress;
for (var n, r, s, o, i, a, u, c, l, p, h = a = 0,
f = !0,
g = u = 0,
d = N.length; u < d; g = ++u) for (C = N[g], i = null != E[g] ? E[g] : E[g] = [], s = c = 0, l = (r = null != (p = C.elements) ? p: [C]).length; c < l; s = ++c) o = r[s],
f &= (o = null != i[s] ? i[s] : i[s] = new v(o)).done,
o.done || (h++, a += o.tick(t));
return n = a / h,
w.update(_.tick(t, n)),
w.done() || f || b ? (w.update(100), y.trigger("done"), setTimeout(function() {
return w.finish(),
y.running = !1,
y.trigger("hide")
},
Math.max(T.ghostTime, Math.max(T.minTime - (P() - m), 0)))) : e()
})
},
y.start = function(t) {
d(T, t),
y.running = !0;
try {
w.render()
} catch(t) {
n = t
}
return document.querySelector(".pace") ? (y.trigger("start"), y.go()) : setTimeout(y.start, 50)
},
"function" == typeof define && define.amd ? define(function() {
return y
}) : "object" == typeof exports ? module.exports = y: T.startOnPageLoad && y.start()
}.call(this);

_config.butterfly.yml主题文件中加入

1
2
3
4
inject:
head:
- <script src="https://npm.elemecdn.com/pace-js@latest/pace.min.js"></script>
- <link rel="stylesheet" href="/css/load.css">

Hexo 白昼切换

看惯了Hexo Butterfly默认的黑夜/白天效果,正好看到 Jayhrnの糖衣阁大佬的黑白切换效果超级nice,所以也是第一时间换上了,下面告诉大家一下相关配置,相关文件大家也是可以在Gitee上找到的,链接我放底下了哦

(1)在themes\butterfly\layout\includes\custom\下新建一个sun_moon.pug【如果includes\下没有custom,记得自己创建哦】

主要用途:通过 js 操作它的旋转显隐,淡入淡出实现动画效果

1
2
3
4
5
6
7
8
9
svg(aria-hidden='true', style='position:absolute; overflow:hidden; width:0; height:0')
symbol#icon-sun(viewBox='0 0 1024 1024')
path(d='M960 512l-128 128v192h-192l-128 128-128-128H192v-192l-128-128 128-128V192h192l128-128 128 128h192v192z', fill='#FFD878', p-id='8420')
path(d='M736 512a224 224 0 1 0-448 0 224 224 0 1 0 448 0z', fill='#FFE4A9', p-id='8421')
path(d='M512 109.248L626.752 224H800v173.248L914.752 512 800 626.752V800h-173.248L512 914.752 397.248 800H224v-173.248L109.248 512 224 397.248V224h173.248L512 109.248M512 64l-128 128H192v192l-128 128 128 128v192h192l128 128 128-128h192v-192l128-128-128-128V192h-192l-128-128z', fill='#4D5152', p-id='8422')
path(d='M512 320c105.888 0 192 86.112 192 192s-86.112 192-192 192-192-86.112-192-192 86.112-192 192-192m0-32a224 224 0 1 0 0 448 224 224 0 0 0 0-448z', fill='#4D5152', p-id='8423')
symbol#icon-moon(viewBox='0 0 1024 1024')
path(d='M611.370667 167.082667a445.013333 445.013333 0 0 1-38.4 161.834666 477.824 477.824 0 0 1-244.736 244.394667 445.141333 445.141333 0 0 1-161.109334 38.058667 85.077333 85.077333 0 0 0-65.066666 135.722666A462.08 462.08 0 1 0 747.093333 102.058667a85.077333 85.077333 0 0 0-135.722666 65.024z', fill='#FFB531', p-id='11345')
path(d='M329.728 274.133333l35.157333-35.157333a21.333333 21.333333 0 1 0-30.165333-30.165333l-35.157333 35.157333-35.114667-35.157333a21.333333 21.333333 0 0 0-30.165333 30.165333l35.114666 35.157333-35.114666 35.157334a21.333333 21.333333 0 1 0 30.165333 30.165333l35.114667-35.157333 35.157333 35.157333a21.333333 21.333333 01030.165333-30.165333z', fill='#030835', p-id='11346')

(2)themes\butterfly\source\css_layout\文件夹中新建一个sun_moon.styl

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
.Cuteen_DarkSky,
.Cuteen_DarkSky:before
content ''
position fixed
left 0
right 0
top 0
bottom 0
z-index 88888888

.Cuteen_DarkSky
background linear-gradient(#feb8b0, #fef9db)
&:before
transition 2s ease all
opacity 0
background linear-gradient(#4c3f6d, #6c62bb, #93b1ed)

.DarkMode
.Cuteen_DarkSky
&:before
opacity 1

.Cuteen_DarkPlanet
z-index 99999999
position fixed
left -50%
top -50%
width 200%
height 200%
-webkit-animation CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1)
animation CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1)
transform-origin center bottom


@-webkit-keyframes CuteenPlanetMove {
0% {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
@keyframes CuteenPlanetMove {
0% {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
.Cuteen_DarkPlanet
&:after
position absolute
left 35%
top 40%
width 9.375rem
height 9.375rem
border-radius 50%
content ''
background linear-gradient(#fefefe, #fffbe8)

.search
span
display none

.menus_item
a
text-decoration none!important
//按钮相关,对侧栏按钮做过魔改的可以调整这里的数值
.icon-V
padding 5px

(3)在\themes\butterfly\source\js\custom\下新建sun_moon.js【如果js\下没有custom,记得自己创建哦】

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
function switchNightMode() {
document.querySelector('body').insertAdjacentHTML('beforeend', '<div class="Cuteen_DarkSky"><div class="Cuteen_DarkPlanet"></div></div>'),
setTimeout(function() {
document.querySelector('body').classList.contains('DarkMode') ? (document.querySelector('body').classList.remove('DarkMode'), localStorage.setItem('isDark', '0'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-moon')) : (document.querySelector('body').classList.add('DarkMode'), localStorage.setItem('isDark', '1'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-sun')),
setTimeout(function() {
document.getElementsByClassName('Cuteen_DarkSky')[0].style.transition = 'opacity 3s';
document.getElementsByClassName('Cuteen_DarkSky')[0].style.opacity = '0';
setTimeout(function() {
document.getElementsByClassName('Cuteen_DarkSky')[0].remove();
}, 1e3);
}, 2e3)
})
const nowMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
if (nowMode === 'light') {
activateDarkMode()
saveToLocal.set('theme', 'dark', 2)
GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night)
document.getElementById('modeicon').setAttribute('xlink:href', '#icon-sun')
} else {
activateLightMode()
saveToLocal.set('theme', 'light', 2)
document.querySelector('body').classList.add('DarkMode'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-moon')
}
// handle some cases
typeof utterancesTheme === 'function' && utterancesTheme()
typeof FB === 'object' && window.loadFBComment()
window.DISQUS && document.getElementById('disqus_thread').children.length && setTimeout(() => window.disqusReset(), 200)
}

(4)修改 [Blogroot]\themes\butterfly\layout\includes\head.pug

1
2
3
4
5
6
7
8
9
10
11
//- global config
!=partial('includes/head/config', {}, {cache: true})

include ./head/config_site.pug
include ./head/noscript.pug
include ./custom/sun_moon.pug【添加上这句】

!=fragment_cache('injectHeadJs', function(){return inject_head_js()})

!=fragment_cache('injectHead', function(){return injectHtml(theme.inject.head)})

(5)修改 [Blogroot]\themes\butterfly\layout\includes\rightside.pug, 把原本的昼夜切换按钮替换掉

1
2
3
4
5
6
7
8
9
10
when 'translate'
if translate.enable
button#translateLink(type="button" title=_p('rightside.translate_title'))= translate.default
when 'darkmode'
if darkmode.enable && darkmode.button
button#darkmode(type="button" title=_p('rightside.night_mode_title')) 【这句删除掉】
i.fas.fa-adjust 【这句删除掉】
a.icon-V.hidden(onclick='switchNightMode()', title=_p('rightside.night_mode_title'))【添加上这句】
svg(width='25', height='25', viewBox='0 0 1024 1024')【添加上这句】
use#modeicon(xlink:href='#icon-moon')【添加上这句】

(6)修改 [Blogroot]_config.butterfly.yml, 引入一下 js

1
2
3
4
inject:
head:
bottom:
- <script src="/js/custom/sun_moon.js" async></script>

朋友圈

看到很多博主都整了属于自己的朋友圈页面,所以在自己的轻量级服务器上也是第一时间部署上了,这里直接说在server部署咯

这个是我自己的:朋友圈 | 七鳄の学习格 (gmcj0816.top)

后端配置

上传文件

  • 下载文件

方法一:clone项目仓库,地址:https://github.com/Rock-Candy-Tea/hexo-circle-of-friends

1
git clone https://github.com/Rock-Candy-Tea/hexo-circle-of-friends

方法二:这里也是可以先从物理机上下载然后上传到云服务器上

1
https://github.com/Rock-Candy-Tea/hexo-circle-of-friends

然后连接并上传到服务器上

在服务器上下载Python3.x

因为获取相关数据主要就是用python3 爬虫,所以需要下载Python3.x,这里以3.8为例

  • 下载相关依赖
1
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel yum vim gcc
  • 安装Python3.8.8
1
2
3
4
wget https://www.python.org/ftp/python/3.8.8/Python-3.8.8.tgz
tar -zxf Python-3.8.8.tgz && cd Python-3.8.8
./configure --prefix=/usr/local/python3
make && make install
  • 进行软链接
1
2
ln -s /usr/local/python3/bin/python3.8 /usr/bin/python3
ln -s /usr/local/python3/bin/pip3.8 /usr/bin/pip3

安装完成之后验证是否成功,正常是可以看到版本号的

1
python3 --version

需要下载pip

这个主要是朋友圈5.x之后需要有这个,不然会报错

1
pip install pyyaml

在服务器上下载git

如果有git可以跳过

1
yum install -y git

修改相关配置

  • 编辑/hexo_circle_of_friends/fc_settings.yaml文件,需要修改的配置如下:
1
2
LINK:
- {link: "https://www.yyyzyyyz.cn/link/", theme: "butterfly"} # link改为你的友链页地址,theme选择你的博客主题

因为是server部署,这里需要改成server

1
2
3
4
BLOCK_SITE: []
DATABASE: sqlite # 这里可以默认不需要修改
DEPLOY_TYPE: server # 需要改成server
GITEE_FRIENDS_LINKS:
  • 运行位于项目根目录的部署脚本:
1
python3 deploy.py

部署画面

选择server--->部署,等待运行完毕即可。

部署完毕后,查看进程,服务器上开始运行两个进程,一个是爬虫程序,另一个是api服务:

进程

查看效果

1
curl 127.0.0.1:8000/all

Nginx代理

因为https访问http接口就会禁止

1
2
3
4
5
6
7
在你的Hexo 443端口下添加
location ^~/friendlink{
proxy_pass http://127.0.0.1:端口号/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

前端配置

新建页面

比如hexo在博客根目录使用命令

1
hexo new fcircle

可以看到source/fcircle/index.md 文件,打开该文件,粘贴以下内容(注意修改api地址):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
---
title: 朋友圈
date: 2022-01-29 15:23:17
---

<div id="app"></div>
<script>
let UserConfig = {
// 填写你的api地址
private_api_url: 'https://blog.gmcj0816.top/friendlink', //这里改成自己的
// 点击加载更多时,一次最多加载几篇文章,默认10
page_turning_number: 10,
// 头像加载失败时,默认头像地址
error_img: 'https://sdn.geekzu.org/avatar/57d8260dfb55501c37dde588e7c3852c',
// 进入页面时第一次的排序规则
sort_rule: 'created'
}
</script>
<script type="text/javascript" src="https://npm.elemecdn.com/imgscdn@1.1.39/fcircle/app.min.js"></script>
<script type="text/javascript" src="https://npm.elemecdn.com/imgscdn@1.1.39/fcircle/bundle.js"></script>

到这里基本就完事了

下面就是根据自己的实际修改了,在5.x版本是可以前端修改相关信息的

补充

这里本站的前端已经更换成安知鱼的教程类型,现在发现越来越Heo化了

这里就参考安知鱼 - 生活明朗 万物可爱 (anzhiy.cn)

安装插件

在博客根目录[Blogroot]下打开终端,运行以下指令(与旧版前端方案不兼容,如有安装旧版请先卸载):

1
2
3
npm uninstall hexo-butterfly-fcircle --save
npm uninstall hexo-filter-fcircle --save
npm install hexo-filter-fcircle-anzhiyu --save

添加配置信息

在站点配置文件_config.yml或者主题配置文件例如_config.butterfly.yml中添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# fcircle
# see https://akilar.top/posts/62f13a97/
fcircle:
enable: true #控制开关
apiurl: https://friends.anzhiy.cn/ #api地址(注意后面要有/)
initnumber: 30 #【可选】页面初始化展示文章数量
stepnumber: 30 #【可选】每次加载增加的篇数
css: https://npm.elemecdn.com/hexo-filter-fcircle-anzhiyu@1.0.9/assets/css/default.css #【可选】开发者接口,自定义css链接
js: https://npm.elemecdn.com/hexo-filter-fcircle-anzhiyu@1.0.9/assets/js/fcircle.js #【可选】开发者接口,自定义js链接
fetchJs: https://npm.elemecdn.com/hexo-filter-fcircle-anzhiyu@1.0.9/assets/js/fetch.js
randomFriendsPostJS: https://npm.elemecdn.com/hexo-filter-fcircle-anzhiyu@1.0.9/assets/js/random-friends-post.js
path: /fcircle #【可选】fcircle的路径名称。默认为 fcircle,生成的页面为 fcircle/index.html
topIcon: fas fa-arrow-right
topLink: /about/
front_matter: #【可选】fcircle页面的 front_matter 配置
title: 朋友圈
comments: false
aside: false
top_img: false
  • 样式适配

安装完成✅以后,会发现顶部样式有亿点奇怪, 需要与自己的主题样式进行适配, 可以尝试加入以下自定义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
.author-content.author-content-item.fcirclePage {
position: relative;
border-radius: 15px;
}
.author-content-item .card-content {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 2;
display: flex;
flex-direction: column;
padding: 1rem 2rem;
}
.author-content-item .author-content-item-tips {
opacity: .8;
font-size: .6rem;
margin-bottom: 0.5rem;
}
.author-content-item .card-content .author-content-item-title {
margin-bottom: 0.5rem;
}
.author-content-item .author-content-item-title {
font-size: 36px;
font-weight: 700;
line-height: 1;
}
.author-content-item .content-bottom {
margin-top: auto;
display: flex;
align-items: center;
justify-content: space-between;
}
.author-content-item .card-content .banner-button-group {
position: absolute;
bottom: 1.5rem;
right: 2rem;
}
.author-content-item .card-content .banner-button-group .banner-button {
height: 40px;
width: 124px;
border-radius: 20px;
justify-content: center;
background: var(--sevene--bg);
color: var(--font-color);
display: flex;
align-items: center;
z-index: 1;
transition: .3s;
cursor: pointer;
border-bottom: 0!important;
}
.author-content-item .card-content .banner-button-group .banner-button i {
margin-right: 8px;
font-size: 1rem;
}

该项目中css使用了css变量, 添加变量css如下, 您可自行修改。

1
2
3
4
5
6
7
8
/* 颜色 */
[data-theme='light'] {
--sevene-card-bg: #fff;
}

[data-theme='dark'] {
--sevene-card-bg: #1d1b26;
}
  • 整页背景调整

加完以后会发现还是有点奇怪并且无法修改背景, 因为需要给当前页面加一个特定的类名来修改当前页面背景和底部页脚的文字颜色。
修改themes/butterfly/layout/page.pug第5行, 注意缩进

1
2
3
4
5
6
  block content
+ - let fcircle_page = (is_current('/fcircle/')) ? true : false
- #page
+ #page(class= (fcircle_page === true) ? 'fcircle_page' : '')
if top_img === false
h1.page-title= page.title

修改themes/butterfly/layout/includes/layout.pug第16行, 注意缩进

1
2
3
4
5
  if theme.background
- web_bg
+ #web_bg(class= (fcircle_page === true) ? 'fcircle_page-page-background' : '')

!=partial('includes/sidebar', {}, {cache: true})

改完以后就可以通过css来修改当前页面的背景和底部页脚的文字颜色了, 加入以下css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.fcircle_page-page-background#web_bg {
background: var(--sevene-background) !important;
}
[data-theme='dark'] .fcircle_page-page-background#web_bg {
background: var(--global-bg) !important;
}
[data-theme=light] .fcircle_page-page-background ~ .page #footer #footer-wrap {
color: var(--font-color);
}
[data-theme=light] .fcircle_page-page-background ~ .page #footer #footer-wrap a{
color: var(--font-color);
}
.author-content.author-content-item.fcirclePage {
background: url("这里修改成自己喜欢的图片") center center no-repeat !important
}

开启了pjax的同学, 需要修改 themes/butterfly/layout/includes/third-party/pjax.pug 加上#web_bg以完成适配

1
2
3
4
5
6
7
  - var pjaxExclude = 'a:not([target="_blank"])'
if theme.pjax.exclude
each val in theme.pjax.exclude
- pjaxExclude = pjaxExclude + `:not([href="${val}"])`

- - let pjaxSelectors = ['head > title','#config-diff','#body-wrap','#rightside-config-hide','#rightside-config-show','.js-pjax']
+ - let pjaxSelectors = ['head > title','#config-diff','#body-wrap','#rightside-config-hide','#rightside-config-show','.js-pjax', '#web_bg']

Github徽标

  1. github徽标可以直接通过shields.io在线生成。
  2. 理论上可以放在页面的任何地方。教程案例是添加在页脚。
  3. 工具网站包括:

具体步骤

1.打开生成网站

通过shields.io在线生成。

  • label:标签,徽标左侧内容
  • message:信息,徽标右侧内容
  • color:色值,支持支持十六进制、rgb、rgba、hsl、hsla和 css 命名颜色。十六进制记得删除前面的#号

2.输入相关信息

点击make badge即可得到徽标的URL。可以用img标签引用,写法简单。不过正式写法建议用object标签引用,写法示例如下:

1
2
3
4
5
6
<!-- label=Frame,Message=Hexo,color=blue -->
https://img.shields.io/badge/Frame-Hexo-blue
<!-- 在页面上可以使用img标签来引用 -->
<img src="https://img.shields.io/badge/Frame-Hexo-blue">
<!-- 部分属性例如link需要用object标签来引用 -->
<object data="https://img.shields.io/badge/Frame-Hexo-blue?link=https://hexo.io"></object>

3.拓展写法示例

仅仅如此肯定是不能令人满意的,还可以继续添加样式。
shields.io提供直接在URL内添加样式属性的功能。使用?引用,使用&连接各属性。

属性 说明 示例
style 徽标样式,默认提供了五种样式: plastic,flat,flat-square, for-the-badge,social ?style=flat-square
label 覆盖默认的左侧文本 (空格或特殊字符需要转URL编码!) ?label=healthinesses
logo 给左侧标签前插入图标 可以访问simpleicons查询图标 ?logo=Hexo
logo 自定义图标, 限制较多,不推荐 ?logo=data:image/png;base64,url
logoColor 设置徽标的颜色 (支持十六进制、rgb、 rgba、hsl、hsla 和 css 命名颜色)。 支持命名徽标, 但不支持自定义徽标。 ?logoColor=violet
logoWidth 给图标提供的水平空间 ?logoWidth=40
link 徽标指向的链接, 此时需要用object标签 引用才能生效 写法看示例代码 ?link=http://example.com
labelColor 左侧部分背景色, (支持十六进制、rgb、 rgba、hsl、hsla 和 css 命名颜色) ?labelColor=abcdef 或者?colorA=abcdef
color 右侧部分背景色, (支持十六进制、rgb、 rgba、hsl、hsla 和 css 命名颜色) ?color=fedcba或者?colorB=fedcba

1.普通样式

2.五种style预览





3.添加图标和自定义label

4.添加图标和图标宽度

5.图标、label、message三部分颜色自定义

6.给标签添加链接

7.可以通过嵌套a标签来实现添加链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- 普通样式 -->
<img src="https://img.shields.io/badge/Frame-Hexo-blue">
<!-- 五种style预览 -->
<img src="https://img.shields.io/badge/Frame-Hexo-blue?logo=Hexo&style=plastic">
<img src="https://img.shields.io/badge/Frame-Hexo-blue?logo=Hexo&style=flat">
<img src="https://img.shields.io/badge/Frame-Hexo-blue?logo=Hexo&style=flat-square">
<img src="https://img.shields.io/badge/Frame-Hexo-blue?logo=Hexo&style=for-the-badge">
<img src="https://img.shields.io/badge/Frame-Hexo-blue?logo=Hexo&style=social">
<!-- 添加图标和自定义label -->
<img src="https://img.shields.io/badge/Frame-Hexo-blue?logo=Hexo&label=框架">
<!-- 添加图标和图标宽度 -->
<img src="https://img.shields.io/badge/Frame-Hexo-blue?logo=Hexo&logoWidth=30">
<!-- 图标、label、message三部分颜色自定义 -->
<img src="https://img.shields.io/badge/Frame-Hexo-blue?logo=Hexo&label=框架&logoColor=violet&labalColor=#1fd041&color=rgb(222, 31, 31)">
<!-- 给标签添加链接 -->
<object data="https://img.shields.io/badge/Frame-Hexo-blue?logo=Hexo&link=https://hexo.io/&https://hexo.io/zh-cn/docs/"></object>
<!-- 也可以通过嵌套a标签来实现添加链接 -->
<a target="_blank" href="https://hexo.io" title="框架采用Hexo"><img src="https://img.shields.io/badge/Frame-Hexo-blue"></a>

4.使用

[Blogroot]\_config.butterfly.ymlfooter配置项中添加徽标,注意事先压缩一下,使他们只留一行。为了不至于太过紧凑,设置一下行内间隔属性margin-inline

1
2
3
4
5
6
7
8
      footer:
owner:
enable: true
since: 2016
- custom_text:
+ custom_text: <p><a style="margin-inline:5px" target="_blank" href="https://hexo.io/"><img src="https://img.shields.io/badge/Frame-Hexo-blue?style=flat&logo=hexo" title="博客框架为Hexo"></a><a style="margin-inline:5px" target="_blank" href="https://butterfly.js.org/"><img src="https://img.shields.io/badge/Theme-Butterfly-6513df?style=flat&logo=bitdefender" title="主题采用butterfly"></a><a style="margin-inline:5px" target="_blank" href="https://www.jsdelivr.com/"><img src="https://img.shields.io/badge/CDN-jsDelivr-orange?style=flat&logo=jsDelivr" title="本站使用JsDelivr为静态资源提供CDN加速"></a><a style="margin-inline:5px" target="_blank" href="https://vercel.com/ "><img src="https://img.shields.io/badge/Hosted-Vercel-brightgreen?style=flat&logo=Vercel" title="本站采用双线部署,默认线路托管于Vercel"></a><a style="margin-inline:5px" target="_blank" href="https://vercel.com/ "><img src="https://img.shields.io/badge/Hosted-Coding-0cedbe?style=flat&logo=Codio" title="本站采用双线部署,联通线路托管于Coding"></a><a style="margin-inline:5px" target="_blank" href="https://github.com/"><img src="https://img.shields.io/badge/Source-Github-d021d6?style=flat&logo=GitHub" title="本站项目由Github托管"></a><a style="margin-inline:5px" target="_blank" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img src="https://img.shields.io/badge/Copyright-BY--NC--SA%204.0-d42328?style=flat&logo=Claris" title="本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可"></a></p>
copyright: false # Copyright of theme and framework
ICP: # Chinese ICP License

常用徽章【可以直接用哦】

(1).找到合适的图标图片,建议先行用PS抠图成透明背景,然后存储为png格式,此时,要记得尽量将图片的尺寸调整的小一点,这样转的base64图片链接才不至于过长。

(2).找个在线转base64图片的网站,把制作好的图片转为base64链接。这里推荐用

UrlEncode编码/UrlDecode解码 - 站长工具 (chinaz.com)

BASE64转图片 - 站长工具 - 极速数据 (jisuapi.com)

(3).把base64链接作为logo填进徽标链接。

1.公安备案徽章

1
<p><a style="margin-inline:5px"target="_blank" href="http://www.beian.gov.cn/portal/index.do"><img src="https://img.shields.io/badge/%E5%86%80%E5%85%AC%E5%AE%89%E5%A4%87-1111111%E5%8F%B7--1-e1d492?style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAABS2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+nhxg7wAACNlJREFUSInF1mmMVeUdx/Hv2e+5+519mJWBYQZkGxZZxLKJqBXGoLS1iXWrmihotFXaJiTWWlsbl6q1aetWd5u0VkKjNG4YEJSlOCibDLMwM8x679z9nnPP1jcVJUxf+7z6J8+LT37/Z4VvaQhfFS8+sBXbctCDGrVTKlBUH4mxAbI9Hfj0IJLsp6paJ5/tmn20N/D0wKDRMq9F/c3M2U1/V0vDfWMFh+tv/Ig1zYPMabDImPJ52OaXO87W580KggCiiOsJOJ6I3wcNFaaeNKxrt72f2fLGu4FpJ/sDQABRzD22fH7/Yze069vGc6mrDLNIJCDik10sxz2by3VdPM87xzkP9jwPTZFRVI1YUJKH+oy7n3tbvv/P2wW/UQxRWe6w4ZJRptYLHDoCuz8v5cP92XbI762O+h6UVWHnUFbPpU0fEb2A60mMJ7MUi9b/b7UgKhiZMaIxm8YLplLMDPz8hl/EH+rs8TNlUpFf32uyZJGLPDwCiTGUyTWodTN49eUCdz2YwXb9NNcObp1X98WDoufynzMVCEKGn27ayPTWBi5ad8P5iQUkJEnFLjqM9Z+hrVX0vfDe6K2dPRWsW2bwyp9EUifSJB84gdxrkR0eRgv1o/3I4fbbprJ6scqamzVO9pffec1S5ZWY2Nfz5qEy/FqOC2Y3s3j53HMSi18VRjFPwSwg+1RfVbl115vvJrsfej7UGIsYPPGgQ7JXoO+Xx5B3dHEomyJ9x1qiQozkr95h5937aFnVyouPlgJK+Ss7Fxz64OTSxSX+LHYxT2IsRW5kbGI4oHcR0jqoqTjV9se3I7/f8rS/ClS23GxSXhph6L5d9Akm7qqZhHWBQGUJ+CWGFzcg7e7m6D3/ZuW1Ea5YKdA3EojuONi813TqNi+YPYOKUhXDtCeGL26/hakLLiEcdsaHRkRAoLRc4fJrmhnekyF0apgZowWSwwkaa+rw3f8WA1GZZsPP5JEChX8dhZTN6iU6kAcs5s+dHd183SJ0VVKL57pfw6YdRQw23aeWTns47DPTALWlRTR7kMLew6hGgYqUhWXYFFUdPZ6lUBahLA8hVcOftckfi7No7VRAAQqsX1dybfvG1qwriM9mM5mJ4e4jO5Cc01dPqixbr8tWGBQUL4vjGigEEShi+xUmZ2RiR/sJ1pbS8NkgZrKAGw0TsgQsQyFaF/nfYTGprAlMFysbA1pI3mhkR6snhGsaymYGvPyFEb9IdbUE2AzFFTwpRqCtBY0wmdER+hZW4j63gcJj38V+/ErSUZXsYBfjIZHIRW0c2Z8BskCAqN+CbBJBFnyyKjR+Ez57nBxLqpfMUeSISElMBFz6x2Q6OxzWrYjyxWVzEewioU3LCS5vQY6nMUrLwNaxXvoQ59IloFSx54PPAZtQLExVZZDxsVE8J4dn6v4JYatgbSjk0owPw7RGH2ADMo88Z7L20ip8f7gC7fAo0q4+0rt7kEQDvaghVZbiPHUHcyeXcfLjT3jmpR7AYsnSScya3UR8bARVMck7Y/cB75/X6rDf3Fg2dw2jKZm5dXGm1LuAzO5DCo9v6aT0ibco5kzOvLOP+NGTFJtDpPYeZKijk/Rn3QxsfZV7txwhX7ABiZUXBsGvIvguQApNQQva9RMmTvZ2dpVUls+tX/UD7GN/Y8Ws05w6rQF+9vyzg1vZjbvMRJhXiRSU8DpTFFe0QE8S6SfPkOkZoktrB2oAhZWrwljxOPmchiSMYOWNoxNuruFU5vWeXdsojiUon345113dBBQBmTYlTimgdB8nfPo4WjaNFgN9OMEkJ02dnadVt5ki54Esqy+bzKJltVhSPbI3iN2zCyMTeXNCuG7Omm2Zok7PR2+R7jvD8ouruHhmCrB5jVZeYxLdrTP4sr4Vtd9g4MA4qc4c+6cu5NPamfw4P59t2WrA4YdXKkASf7SFivo6PDdEPmf1fRM++zp1bH/0r4I1dD1ODtOWaW4IsvPjL7nqXhloQiSPwjjgMYkMASyGEBkjhISCQwkwzve/18AbT+pk8pVY4UacQi9y+gyZ0eRAw4qHa89LXEx1LXMSPfhDJYRb59BtlLKg2WPT2l6qYl1svtGkrLYckyA1S+t5+2ATm37WCui0LSynsckDNH5zTxAchbQtkx08hDHYiW6NgC0enHBzEZ102UDH8QORdEckjEzZrNWkRydzyx17uGnDXqbUnGZ6dRPjSY91q2TqwjFuvTxLo5Zn5Qo/pumRSFcTLQtybEhGE0fQrDhhJ0VvH2lTnnHPhGtsmWan469apERjI2MH3qN7+7MEfH6ql29CbV7PvsMG32k6yU2XDhEKyZw66eJaRdrXR7CzCcqUNC3zwgymPJRCH4KRRLINimpL14A5Y4GDeOqbsPRVcfuN7Xj44pav/hFfrNT2kr2rsqf2Ibp5pEA14ZIImUyW3t5REkkTXRGQ/DGGhtLginhqCWknQDE5hKf5UFSF9Lj020Q2ul5V1AR2hr+8vuP8Vlc2zMPRxoSjnx7XBC14sDoydahSGq7KdO/HFyrBchxCVfX4fDKp4T7SCQejYODZLrYgIqgKFsNIgQqEYob8mW6yiUyb7Z64LVK/+B85xznnJ3AWzqTzuIX46mr5wLs+UUTyIriBCjRNxguHMJIFDLEEvXEOVRWnSJ0+jCd4CJoGjoedM1CLcXQziW3nMV2TSMBeOx7vWZvPt1r+cMPzE8KunaUkFn0vNrvtqXj34c1W6gzxlEQ6naIoBahtnkMwoFMwIVzSRNguMt53Aj2s4nkSlgPoGqLkICsRNF0gl8rYWuP8+11/w/OOJDEhHPKLCIpOXmi+M9AgP+maiesLifF2T1Rn5ZNj5Lo/Qc/GcPMmhdoqlEgIGzCK4PiCmJKK68p4KfF3qYGuF0qCRUkJTzleUbvQyWRTuE5xYthxQbBs7EISAbkzUFG3VfXXbK2YFi3X/eryfKKnqVBItNjJxDzH8erddC4SqWwcN5WyTtlyO1RP/Lh3eHD76MB40swmiDVJyDLYRhpc5+ub6tse/wWKbvSQEAw1awAAAABJRU5ErkJggg==" title="公安备案"></a></p>

在相关代码中找到

1
%E5%86%80%E5%85%AC%E5%AE%89%E5%A4%87-1111111%E5%8F%B7--1

使用UrlEncode编码/UrlDecode解码 - 站长工具 (chinaz.com) UrlEncode解码即可解码成:冀公安备-1111111号—1,修改成自己的,然后点击UrlEncode编码替换相应的即可

2.萌ICP备案徽章

1
<p><a style="margin-inline:5px"target="_blank" href="https://icp.gov.moe/"><img src="https://img.shields.io/badge/%E8%90%8CICP%E5%A4%87-20210100-fe1384?style-flat&logo=data:image/png;base64,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 title="萌ICP备案"></a></p>

在相关代码中找到

1
%E8%90%8CICP%E5%A4%87-20210100

使用UrlEncode编码/UrlDecode解码 - 站长工具 (chinaz.com) UrlEncode解码即可解码成:冀公安备-1111111号—1,修改成自己的,然后点击UrlEncode编码替换相应的即可

此文章借鉴:

Akilarの糖果屋 - Akilar.top