前言

旧版工程太臃肿了,加了很多冗余的东西,而且版本有些落后了,故此更新。新博客很清爽。

未改动

  • 域名不变,仍是 sococo.cn
  • 文章未做大改,无清理

改动

版本变动

首先是 package 更新,Hexo 版本更新到了 7.3.0,这需要更高版本的 Node.js,笔者版本为 v20.18.0。具体插件以及版本如下。

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

{
"hexo": {
"version": "7.3.0"
},
"dependencies": {
"cheerio": "^1.0.0",
"hexo": "^7.3.0",
"hexo-butterfly-tag-plugins-plus": "^1.0.18",
"hexo-deployer-git": "^4.0.0",
"hexo-filter-mathjax": "^0.9.0",
"hexo-generator-archive": "^2.0.0",
"hexo-generator-category": "^2.0.0",
"hexo-generator-index": "^4.0.0",
"hexo-generator-search": "^2.4.3",
"hexo-generator-tag": "^2.0.0",
"hexo-math": "^5.0.0",
"hexo-renderer-ejs": "^2.0.0",
"hexo-renderer-markdown-it": "^7.1.1",
"hexo-renderer-pug": "^3.0.0",
"hexo-renderer-stylus": "^3.0.1",
"hexo-server": "^3.0.0",
"hexo-solitude-tag": "^1.0.13",
"hexo-theme-landscape": "^1.0.0",
"hexo-theme-solitude": "^2.1.4",
"hexo-wordcount": "^6.0.1"
},

}

其中 hexo-butterfly-tag-plugins-plus 是为了旧版兼容的暂时,预计将文章改完后即可 uninstall。

主题变动

抛弃了 Butterfly 主题为基础,换成了 Solitude,在此基础上进行了简单的修改。文档不是很完善,部分链接寄了,但是总体还好。

essay

Solitude 主题兼容笔者旧版魔改的 essay,倒不如说用的是一套模板,但是还是对于 aplayer 播放器的部分,笔者添加了自定义的部分,而不是只能解析服务商的歌单。
在 theme/layout/page/says 中仿照格式添加如下代码,注意对齐和缩进。

1
2
3
4
5

if item.aplayer2
.bber-music
meting-js(name=item.aplayer2.name, artist=item.aplayer2.artist, url=item.aplayer2.url, cover=item.aplayer2.cover)

此时在 essay.yml 中添加如下格式的内容即可添加自定义音乐了。

1
2
3
4
5
6
7
8

- content: 以及别离不知从何时起 已渐渐并肩而行了
date: 2024-03-22 22:38:58
aplayer2:
name: Pray
url: https://dlink.host/musics/aHR0cHM6Ly9vbmVkcnYtbXkuc2hhcmVwb2ludC5jb20vOnU6L2cvcGVyc29uYWwvc3Rvcl9vbmVkcnZfb25taWNyb3NvZnRfY29tL0VSNVBVc3dhYmtsTHB6dW9zVWhZSlgwQjdKYThEclg1UllSQ2FkNWI3c1Mza3c.mp3
cover: https://y.qq.com/music/photo_new/T002R300x300M0000021UZUx1h0MHf_1.jpg?max_age=2592000

latex

这一部分官方文档说明中有插件用 npm 找不到文件无法下载,故出此解决方法,目前使用 mathjax。
插件见上, config.yml 中添加如下配置。

1
2
3
4
5
6
7
8
math:
mathjax:
css: 'https://cdn.jsdelivr.net/npm/hexo-math@4.0.0/dist/style.css'
options:
conversion:
display: false
tex:
svg:

Front Matter 前将 mathjax 配置为 true 即可。已知存在问题会和外挂标签的 audio 冲突,以及最好每个公式都用 <span> 嵌套来避免 md 错误解析。

1
2
3
4
5
6
7
<span>

$$
\frac{x^Td}{\sqrt{x^Tx+d^Td}}\approx 0
$$

<span>

charts

参考链接:https://blog.eurkon.com/post/1213ef82.html
需要注意是的尽管 Soltude 不会报错,但是仍然要安装 cheerio,不然 chart 是不会显示的。

album_1.0 目前问题 图片加载不出来orz

旧版魔改和新版底层的 main.js 框架不一样,没法直接去改 img 的解析,暂时空着了。
之前的相册之后再迁移。

measure

ps:theme/layout/include/widgets/page/banner.pug 为 solitude 原有内容

  • 在 theme/layout/includes/page 添加 album.pug;
1
2
3
4
5
6
7
8
9
10
11
12
include ../widgets/page/banner
#album
.card-album
each i in site.data.album
.card(onclick=`pjax.loadUrl("${i.path_name}")`)
img.card_cover(src=i.cover)
.card__content
p.card__category=i.class_name
h3.card__heading=i.description
.album-content-nocover
.album-content-nocover
.album-content-nocover
  • 在 theme/layout/includes/page.pug 添加如下,注意缩进对齐;
1
2
when 'album'
include includes/page/album.pug
  • 在 theme/source/css/ 添加 _extra/ 文件夹。其中添加 album.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
@media screen and (max-width: 768px){
body[data-type="album"] .author-content.author-content-item.sharePage{
width: calc(100% - 40px);
margin: auto;
}
}

@media screen and (max-width: 540px){
body[data-type="album"] .author-content.author-content-item.sharePage{
width: calc(100% - 40px);
margin: auto;
}
#album .card_cover {
width: calc(100% - 40px) !important;
margin: auto;
}
}

@media screen and (max-width: 540px){
body[data-type="album"] div#post-comment{
width: calc(100% - 40px);
margin: auto;
}
}

@media screen and (max-width: 768px){
body[data-type="album"] div#post-comment{
width: calc(100% - 40px);
margin: auto;
}
}


/* 处理单页背景 */
body[data-type="album"] #web_bg {
background: var(--anzhiyu-background);
}
body[data-type="album"] #page {
border: 0;
box-shadow: none !important;
padding: 0 !important;
background: 0 0 !important;
}
body[data-type="album"] #page .page-title {
display: none;
}

/* 变量定义 */
:root {
--album-background-dark: #2d3548;
--album-text-light: rgba(255, 255, 255, 0.6);
--album-text-lighter: rgba(255, 255, 255, 0.9);
--album-spacing-s: 8px;
--album-spacing-m: 16px;
--album-spacing-l: 24px;
--album-spacing-xl: 32px;
--album-spacing-xxl: 64px;
}

/* 卡片样式 */
#album .card-album {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
margin: var(--album-spacing-xxl) 0 0;
}
#album .card-album .album-content-nocover {
width: calc(100% / 4 - 40px);
}

#album .card-album .card {
list-style: none;
position: relative;
display: flex;
width: calc(100% / 4 - 10px);
padding: 10px;
}
#album .card-album .card:hover {
cursor: pointer;
}

#album .card_cover {
border-radius: var(--album-spacing-l);
filter: brightness(0.75) saturate(1.2) contrast(0.85);
transform-origin: center;
transform: scale(1) translateZ(0);
transition: filter 200ms linear, transform 200ms linear;
max-width: 100%;
overflow: hidden;
height: 550px;
width: 100%;
max-width: 100%;
object-fit: cover;
border-radius: var(--album-spacing-l);
}

#album .card:hover .card_cover {
transform: scale(1.05) translateZ(0);
filter: brightness(0.9) saturate(1.2) contrast(1);
}

#album .card-album:hover > .card:not(:hover) .card_cover {
filter: brightness(0.5) saturate(0.9) contrast(1.2) blur(20px);
}

#album .card__content {
left: 0;
padding: var(--album-spacing-l);
position: absolute;
top: 0;
}

#album .card__category {
color: var(--album-text-light);
font-size: 0.9rem;
margin-bottom: var(--album-spacing-s);
text-transform: uppercase;
}

#album .card__heading {
color: var(--album-text-lighter);
font-size: 1.9rem;
text-shadow: 2px 2px 20px rgba(0, 0, 0, 0.2);
line-height: 1.4;
word-spacing: 100vw;
}

@media (min-width: 1024px) {
#album img.card_cover {
height: 600px;
}
}

@media (max-width: 960px) {
#album .card-album .card {
width: calc(100% / 2 - 40px);
}
}

@media (max-width: 540px) {
#album .card-album .card {
width: calc(100% - 40px);
}
}

@media (max-width: 768px) {
#album .card-album {
margin-top: 10px;
}
#album .card-album .card {
padding: 10px 0px;
}
}

  • 在 /hexo-theme-solitude\source\css\index.styl 添加
1
@import '_extra/*.css'
  • 终端中输入以下命令,它将在 source 文件夹下生成 album 文件夹,其中包含 index.md ​文件。
1
hexo new page album
  • index.md 中的内容替换成以下
1
2
3
4
5
6
7
8
9
10
11
---
title: album
date: 2023-01-23 14:56:17
type: "album"
aside: false
comment: false
rightbtn: myself
rightbtnlink: /about/
leftend:
cover:
---
  • 终端中输入以下命令,它将在 source 文件夹下生成 album_detial 文件夹,其中包含 index.md ​文件。这是 album 的子文件夹,名称为 your-albumname。
1
hexo new page your-albumname
  • index.md 中的内容替换成以下
1
2
3
4
5
6
7
8
9
10
11
12
---
title: "your-albumname"
type: "album_detial"
top_img: false
type: banner
container: true
rightbtn: back
rightbtnlink: /album/
leftend:
rightend:
cover:
---
  • source/_data/ 添加 album.yml,your-albumname 即为新建的 type 为 album_detial 的文件夹,配置如下:
1
2
3
4
- class_name: Awards
description:
path_name: /your-albumname
cover:
  • album_detial 内暂时用 tag 标签,justified-gallery 修不好。
  • 存在问题,作者把 img 高度写死了,找到参数以后要改长点,不然丢长图片会有问题。

schedule

  • 新建 source/schedule.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
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
.card-widget {
padding: 10px!important;
max-height: calc(100vh - 100px);
}

.card-times a, .card-times div {
color: var(--efu-fontcolor);
}

#card-widget-calendar .item-content {
display: flex;
}

#calendar-area-left {
width: 45%;
}

#calendar-area-right {
width: 55%;
}

#calendar-area-left, #calendar-area-right {
height: 100%;
padding: 4px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

#calendar-main {
width: 100%;
}

#calendar-week {
height: 1.2rem;
font-size: 14px;
letter-spacing: 1px;
font-weight: 700;
align-items: center;
display: flex;
}

#calendar-date {
height: 3rem;
line-height: 1.3;
font-size: 64px;
letter-spacing: 3px;
color: var(--efu-main);
font-weight: 700;
align-items: center;
display: flex;
position: absolute;
top: calc(50% - 2.1rem);
}

#calendar-lunar, #calendar-solar {
height: 1rem;
font-size: 12px;
align-items: center;
display: flex;
position: absolute;
}

#calendar-solar {
bottom: 2.1rem;
}

#calendar-lunar {
bottom: 1rem;
color: var(--efu-secondtext);
}

#calendar-main a {
height: 1rem;
width: 1rem;
border-radius: 50%;
font-size: 12px;
line-height: 12px;
display: flex;
justify-content: center;
align-items: center;
}

#calendar-main a.now {
background: var(--efu-main);
color: var(--efu-card-bg);
}

#calendar-main .calendar-rh a {
color: var(--efu-secondtext);
}

.calendar-r0, .calendar-r1, .calendar-r2, .calendar-r3, .calendar-r4, .calendar-r5, .calendar-rh {
height: 1.2rem;
display: flex;
}

.calendar-d0, .calendar-d1, .calendar-d2, .calendar-d3, .calendar-d4, .calendar-d5, .calendar-d6 {
width: calc(100% / 7);
display: flex;
justify-content: center;
align-items: center;
}

#card-widget-schedule .item-content {
display: flex;
}

#schedule-area-left, #schedule-area-right {
height: 100px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

#schedule-area-left {
width: 30%;
}

#schedule-area-right {
width: 70%;
padding: 0 5px;
}

.schedule-r0, .schedule-r1, .schedule-r2 {
height: 2rem;
width: 100%;
align-items: center;
display: flex;
}

.schedule-d0 {
width: 30px;
margin-right: 5px;
text-align: center;
font-size: 12px;
}

.schedule-d1 {
width: calc(100% - 35px);
height: 1.5rem;
align-items: center;
display: flex;
}

progress::-webkit-progress-bar {
background: linear-gradient(to right, var(--efu-main-op-deep), var(--efu-main-op), var(--efu-main-op-light));
border-radius: 5px;
overflow: hidden;
}

progress::-webkit-progress-value {
background: var(--efu-main);
border-radius: 5px;
}

.aside-span1, .aside-span2 {
height: 1rem;
font-size: 12px;
z-index: 1;
display: flex;
align-items: center;
position: absolute;
}

.aside-span1 {
margin-left: 5px;
}

.aside-span2 {
right: 20px;
color: var(--efu-secondtext);
}

.aside-span2 a {
margin: 0 3px;
}

#pBar_month, #pBar_week, #pBar_year {
width: 100%;
border-radius: 5px;
height: 100%;
}

#schedule-date, #schedule-days, #schedule-title {
display: flex;
align-items: center;
}

#schedule-title {
height: 25px;
line-height: 1;
font-size: 14px;
font-weight: 700;
}

#schedule-days {
height: 40px;
line-height: 1;
font-size: 30px;
font-weight: 900;
color: var(--efu-main);
}

#schedule-date {
height: 20px;
line-height: 1;
font-size: 12px;
color: var(--efu-secondtext);
}
  • 新建 source/schedule.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
document.addEventListener("DOMContentLoaded", () => {
initializeCard();
});

document.addEventListener("pjax:complete", () => {
initializeCard();
});

function initializeCard() {
cardTimes();
cardRefreshTimes();
}

let year, month, week, date, dates, weekStr, monthStr, asideTime, asideDay, asideDayNum, animalYear, ganzhiYear, lunarMon, lunarDay;
const now = new Date();

function cardRefreshTimes() {
const e = document.getElementById("card-widget-schedule");
if (e) {
asideDay = (now - asideTime) / 1e3 / 60 / 60 / 24;
e.querySelector("#pBar_year").value = asideDay;
e.querySelector("#p_span_year").innerHTML = (asideDay / 365 * 100).toFixed(1) + "%";
e.querySelector(".schedule-r0 .schedule-d1 .aside-span2").innerHTML = `还剩<a> ${(365 - asideDay).toFixed(0)} </a>天`;
e.querySelector("#pBar_month").value = date;
e.querySelector("#pBar_month").max = dates;
e.querySelector("#p_span_month").innerHTML = (date / dates * 100).toFixed(1) + "%";
e.querySelector(".schedule-r1 .schedule-d1 .aside-span2").innerHTML = `还剩<a> ${(dates - date)} </a>天`;
e.querySelector("#pBar_week").value = week === 0 ? 7 : week;
e.querySelector("#p_span_week").innerHTML = ((week === 0 ? 7 : week) / 7 * 100).toFixed(1) + "%";
e.querySelector(".schedule-r2 .schedule-d1 .aside-span2").innerHTML = `还剩<a> ${(7 - (week === 0 ? 7 : week))} </a>天`;
}
}

function cardTimes() {
year = now.getFullYear();
month = now.getMonth();
week = now.getDay();
date = now.getDate();

const e = document.getElementById("card-widget-calendar");
if (e) {
const isLeapYear = year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
weekStr = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"][week];
const monthData = [
{ month: "1月", days: 31 },
{ month: "2月", days: isLeapYear ? 29 : 28 },
{ month: "3月", days: 31 },
{ month: "4月", days: 30 },
{ month: "5月", days: 31 },
{ month: "6月", days: 30 },
{ month: "7月", days: 31 },
{ month: "8月", days: 31 },
{ month: "9月", days: 30 },
{ month: "10月", days: 31 },
{ month: "11月", days: 30 },
{ month: "12月", days: 31 }
];
monthStr = monthData[month].month;
dates = monthData[month].days;

const t = (week + 8 - date % 7) % 7;
let n = "", d = false, s = 7 - t;
const o = (dates - s) % 7 === 0 ? Math.floor((dates - s) / 7) + 1 : Math.floor((dates - s) / 7) + 2;
const c = e.querySelector("#calendar-main");
const l = e.querySelector("#calendar-date");

l.style.fontSize = ["64px", "48px", "36px"][Math.min(o - 3, 2)];

for (let i = 0; i < o; i++) {
if (!c.querySelector(`.calendar-r${i}`)) {
c.innerHTML += `<div class='calendar-r${i}'></div>`;
}
for (let j = 0; j < 7; j++) {
if (i === 0 && j === t) {
n = 1;
d = true;
}
const r = n === date ? " class='now'" : "";
if (!c.querySelector(`.calendar-r${i} .calendar-d${j} a`)) {
c.querySelector(`.calendar-r${i}`).innerHTML += `<div class='calendar-d${j}'><a${r}>${n}</a></div>`;
}
if (n >= dates) {
n = "";
d = false;
}
if (d) {
n += 1;
}
}
}

const lunarDate = chineseLunar.solarToLunar(new Date(year, month, date));
animalYear = chineseLunar.format(lunarDate, "A");
ganzhiYear = chineseLunar.format(lunarDate, "T").slice(0, -1);
lunarMon = chineseLunar.format(lunarDate, "M");
lunarDay = chineseLunar.format(lunarDate, "d");

const newYearDate = new Date("2025/01/28 00:00:00");
const daysUntilNewYear = Math.floor((newYearDate - now) / 1e3 / 60 / 60 / 24);
asideTime = new Date(`${new Date().getFullYear()}/01/01 00:00:00`);
asideDay = (now - asideTime) / 1e3 / 60 / 60 / 24;
asideDayNum = Math.floor(asideDay);
const weekNum = week - asideDayNum % 7 >= 0 ? Math.ceil(asideDayNum / 7) : Math.ceil(asideDayNum / 7) + 1;

e.querySelector("#calendar-week").innerHTML = `第${weekNum}周&nbsp;${weekStr}`;
e.querySelector("#calendar-date").innerHTML = date.toString().padStart(2, "0");
e.querySelector("#calendar-solar").innerHTML = `${year}${monthStr}&nbsp;第${asideDay.toFixed(0)}天`;
e.querySelector("#calendar-lunar").innerHTML = `${ganzhiYear}${animalYear}年&nbsp;${lunarMon}${lunarDay}`;
document.getElementById("schedule-days").innerHTML = daysUntilNewYear;
}
}
  • 新建 _data/aside.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
- name: schedule
id: card-widget-schedule
content_html: |
<div id="schedule-area-left">
<div id="schedule-title">距离除夕</div>
<div id="schedule-days"></div>
<div id="schedule-date">2025-01-28</div>
</div>
<div id="schedule-area-right">
<div class="schedule-r0">
<div class="schedule-d0">本年</div>
<div class="schedule-d1">
<span id="p_span_year" class="aside-span1"></span>
<span class="aside-span2">还剩<a></a>天</span>
<progress max="365" id="pBar_year"></progress>
</div>
</div>
<div class="schedule-r1">
<div class="schedule-d0">本月</div>
<div class="schedule-d1">
<span id="p_span_month" class="aside-span1"></span>
<span class="aside-span2">还剩<a></a>天</span>
<progress max="30" id="pBar_month"></progress>
</div>
</div>
<div class="schedule-r2">
<div class="schedule-d0">本周</div>
<div class="schedule-d1">
<span id="p_span_week" class="aside-span1"></span>
<span class="aside-span2">还剩<a></a>天</span>
<progress max="7" id="pBar_week"></progress>
</div>
</div>
</div>

- name: calendar
id: card-widget-calendar
content_html: |
<div id="calendar-area-left">
<div id="calendar-week"></div>
<div id="calendar-date" style="font-size: 48px;"></div>
<div id="calendar-solar"></div>
<div id="calendar-lunar"></div>
</div>
<div id="calendar-area-right">
<div id="calendar-main">
</div>
</div>
  • 修改 _config.solitude.yaml 文件,在 aside 与 extends 中添加以下
1
2
3
4
5
6
7
8
9
10
aside:
home:
+ noSticky: "about,calendar,schedule"
Sticky: "allInfo"
extends:
head:
+ - <link rel="stylesheet" href="/css/schedule.css">
body:
+ - <script src="/js/schedule.js"></script>
+ - <script src="https://open.lightxi.com/unpkg/chinese-lunar@0.1.4/lib/chinese-lunar.js"></script>