给安知鱼主题侧边栏调用似水流年卡片

从友链朋友圈发现的文章,进入博客之后发现有一个非常不错的计时卡片,修改之后命名为 似水流年,是很多 PHP 博客常见功能。

美中不足的是,背景进度条,没有能修改成炫彩的动态进度条,主要是自己技术太菜,留给有能力的朋友魔改。

1.添加主题设置

打开主题文件夹下面的 _config.yml 文件,搜索 # aside (侧边栏) ,在 aside: 里面添加如下设置

1
2
3
4
# 新增:似水流年组件配置
time_flies:
enable: true # 开启计时卡片
title: 似水流年 # 卡片标题

2.添加标题设置

打开根目录下面的 /themes/anzhiyu/languages 文件夹,在里面找到 default.yml 文件,打开之后找到如下代码

1
2
3
4
5
6
7
8
9
aside:
articles: 文章
tags: 标签
categories: 分类
card_announcement: 公告
card_categories: 分类
card_tags: 标签
card_archives: 归档
card_recent_post: 最近发布

代码之后还有很多行代码,主要是在

1
card_recent_post: 最近发布

下面,添加如下代码

1
card_time_flies: 似水流年

添加之后的效果

1
2
3
4
5
6
7
8
9
10
11
aside:
articles: 文章
tags: 标签
categories: 分类
card_announcement: 公告
card_categories: 分类
card_tags: 标签
card_archives: 归档
card_recent_post: 最近发布
card_time_flies: 似水流年
card_webinfo:

3.添加 pug 模板代码

打开 /themes/anzhiyu/layout/includes/widget 文件夹,在里面新建 card_time_flies.pug 文件,之后复制下面的代码粘贴到文件中

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
if theme.aside.time_flies.enable
.card-widget#card-widget-time-flies
.item-headline
i.anzhiyufont.anzhiyu-icon-clock
span= theme.aside.time_flies.title || "似水流年"
.item-content
#aside-time-flies
.schedule-r3
.schedule-d0 日
.schedule-d1
span.aside-span1#p_span_day
span.aside-span2#p_text_day
progress#pBar_day(max="24")
.schedule-r2
.schedule-d0 周
.schedule-d1
span.aside-span1#p_span_week
span.aside-span2#p_text_week
progress#pBar_week(max="7")
.schedule-r1
.schedule-d0 月
.schedule-d1
span.aside-span1#p_span_month
span.aside-span2#p_text_month
progress#pBar_month
.schedule-r0
.schedule-d0 年
.schedule-d1
span.aside-span1#p_span_year
span.aside-span2#p_text_year
progress#pBar_year(max="365")
p.schedule-today#time-flies-today

然后打开同文件夹下的 index.pugcard_time_flies.pug 文件引入到模板中,在这个文件夹中,找到如下代码

1
2
3
4
5
else
//- page
!=partial('includes/widget/card_author', {}, {cache: true})
!=partial('includes/widget/card_announcement', {}, {cache: true})
!=partial('includes/widget/card_weixin', {}, {cache: true})

你如果修改过这个文件,应该清除把 card_time_flies.pug 放到哪里,我把这个 card_time_flies.pug 文件放在了

1
!=partial('includes/widget/card_weixin', {}, {cache: true})

代码下面,我的代码如下

1
2
3
4
5
6
7
else
//- page
!=partial('includes/widget/card_author', {}, {cache: true})
!=partial('includes/widget/card_weixin', {}, {cache: true})
!=partial('includes/widget/card_announcement', {}, {cache: true})
!=partial('includes/widget/card_recent_post', {}, {cache: true})
!=partial('includes/widget/card_time_flies', {}, {cache: true})

到这里代码文件修改完成,我顺便调用了 似水流年 板块。

在这里顺便记录一下安知鱼主题的 iconfont 库的链接地址,因为需要修改这个板块的图标,所以查阅了一下

1
https://www.iconfont.cn/collections/detail?cid=44481

使用起来会很方便的。

4.添加 CSS 调用

在博客根目录 /themes/anzhiyu/source/css/ 下面,新建 time_flies.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
#card-widget-time-flies {
display: block !important;
visibility: visible !important;
margin-top: 16px;
padding: 16px;
border: 1px solid #eee;
border-radius: 6px;
background: #fff;
}

#card-widget-time-flies .item-headline {
display: flex;
align-items: center;
margin-bottom: 12px;
font-size: 16px;
font-weight: 600;
color: #333;
}

#card-widget-time-flies .item-headline i {
margin-right: 8px;
color: #0b0c1f;
}

#aside-time-flies .schedule-r3,
#aside-time-flies .schedule-r2,
#aside-time-flies .schedule-r1,
#aside-time-flies .schedule-r0 {
display: flex;
align-items: center;
margin: 8px 0;
width: 100%;
}

#aside-time-flies .schedule-d0 {
width: 30px;
text-align: center;
font-size: 14px;
color: #333;
}

#aside-time-flies .schedule-d1 {
flex: 1;
margin-left: 10px;
display: flex;
flex-direction: column;
gap: 4px;
}

#aside-time-flies .aside-span1 {
font-size: 14px;
color: #4285f4;
font-weight: 600;
display: inline-block;
width: 70%;
text-align: left;
}

#aside-time-flies .aside-span2 {
font-size: 12px;
color: #666;
display: inline-block;
width: 30%;
text-align: right;
}

#aside-time-flies progress {
width: 100%;
height: 100%;
border-radius: 5px;
display: block !important;
}

#time-flies-today {
margin-top: 12px;
padding-top: 12px;
border-top: 1px solid #eee;
font-size: 13px;
color: #666;
text-align: center;
margin-bottom: 0;
}

@media (prefers-color-scheme: dark) {
#card-widget-time-flies {
background: #222;
border-color: #333;
}
#card-widget-time-flies .item-headline,
#aside-time-flies .schedule-d0 {
color: #fff;
}
#aside-time-flies .aside-span2,
#time-flies-today {
color: #aaa;
}

5.添加JavaScript代码

核心的时间调用 JavaScript 代码,在 /themes/anzhiyu/source/js/ 文件夹下,新建 time_flies.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
  // 似水流年核心功能
(function() {
const config = {
enable: true,
title: "似水流年",
updateInterval: 60000
};

// 未启用则移除组件
if (!config.enable) {
const card = document.getElementById("card-widget-time-flies");
if (card) card.remove();
return;
}

// 缓存DOM元素(完全匹配原网页ID)
const dom = {
day: { span: document.getElementById('p_span_day'), text: document.getElementById('p_text_day'), bar: document.getElementById('pBar_day') },
week: { span: document.getElementById('p_span_week'), text: document.getElementById('p_text_week'), bar: document.getElementById('pBar_week') },
month: { span: document.getElementById('p_span_month'), text: document.getElementById('p_text_month'), bar: document.getElementById('pBar_month') },
year: { span: document.getElementById('p_span_year'), text: document.getElementById('p_text_year'), bar: document.getElementById('pBar_year') },
today: document.getElementById('time-flies-today')
};

// 工具函数:补零(原网页格式:024/007)
const padZero3 = (num) => num.toString().padStart(3, '0');
// 工具函数:计算百分比(保留2位小数,匹配原网页)
const calcPercent = (passed, total) => ((passed / total) * 100).toFixed(2);

// 核心计算逻辑:文本格式完全匹配原网页
function updateTimeFlies() {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth(); // 0-11
const date = now.getDate();
const hours = now.getHours();
const minutes = now.getMinutes();
const seconds = now.getSeconds();

// 1. 今日进度(匹配原网页:9.8 / 024 格式)
const dayTotal = 24;
const dayPassed = hours + minutes/60 + seconds/3600;
const dayPercent = calcPercent(dayPassed, dayTotal);
dom.day.span.textContent = `${dayPercent}%`;
dom.day.text.textContent = `${dayPassed.toFixed(1)} / ${padZero3(dayTotal)}`; // 9.8 / 024
dom.day.bar.max = dayTotal;
dom.day.bar.value = dayPassed;

// 2. 本周进度(匹配原网页:2.5 / 007 格式)
const weekDay = now.getDay() || 7; // 周日转7
const weekTotal = 7;
const weekPassed = (weekDay - 1) + dayPassed / dayTotal;
const weekPercent = calcPercent(weekPassed, weekTotal);
dom.week.span.textContent = `${weekPercent}%`;
dom.week.text.textContent = `${weekPassed.toFixed(1)} / ${padZero3(weekTotal)}`; // 2.5 / 007
dom.week.bar.max = weekTotal;
dom.week.bar.value = weekPassed;

// 3. 本月进度(匹配原网页:15.2 / 031 格式)
const monthTotal = new Date(year, month + 1, 0).getDate();
const monthPassed = date + dayPassed / dayTotal;
const monthPercent = calcPercent(monthPassed, monthTotal);
dom.month.span.textContent = `${monthPercent}%`;
dom.month.text.textContent = `${monthPassed.toFixed(1)} / ${padZero3(monthTotal)}`; // 15.2 / 031
dom.month.bar.max = monthTotal;
dom.month.bar.value = monthPassed;

// 4. 本年进度(匹配原网页:89.5 / 366 格式)
const isLeapYear = (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
const yearTotal = isLeapYear ? 366 : 365;
const yearPassed = (Date.UTC(year, month, date, hours, minutes, seconds) - Date.UTC(year, 0, 1)) / (1000 * 60 * 60 * 24);
const yearPercent = calcPercent(yearPassed, yearTotal);
dom.year.span.textContent = `${yearPercent}%`;
dom.year.text.textContent = `${yearPassed.toFixed(1)} / ${padZero3(yearTotal)}`; // 89.5 / 366
dom.year.bar.max = yearTotal;
dom.year.bar.value = yearPassed;

// 今日日期展示(匹配原网页格式)
const weekText = ['日', '一', '二', '三', '四', '五', '六'][now.getDay()];
dom.today.textContent = `${year}${(month + 1).toString().padStart(2, '0')}${date.toString().padStart(2, '0')}日 星期${weekText}`;
}

// 初始化+定时更新
try {
if (dom.day.span && dom.week.span && dom.month.span && dom.year.span) {
updateTimeFlies();
setInterval(updateTimeFlies, config.updateInterval);
} else {
console.warn('time_flies组件:未找到匹配的DOM元素');
}
} catch (e) {
console.error('time_flies组件更新失败:', e);
}
})();

6.引入 CSS 和 JS 文件

在安知鱼主题的配置文件中搜索 inject ,就会找到如下代码

1
2
3
4
5
6
7
8
9
10
11
# Inject
# Insert the code to head (before '</head>' tag) and the bottom (before '</body>' tag)
# 插入代码到头部 </head> 之前 和 底部 </body> 之前
inject:
head:
# 自定义css
# - <link rel="stylesheet" href="/css/custom.css" media="defer" onload="this.media='all'">

bottom:
# 自定义js
# - <script src="/js/xxx"></script>

head 处进行自定义 CSS 的引入工作

1
- <link rel="stylesheet" href="/css/time_flies.css" media="defer" onload="this.media='all'">

bottom 处进行自定义 js 的引入工作:

1
- <script src="/js/time_flies.js"></script>

修改完之后的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
# Inject
# Insert the code to head (before '</head>' tag) and the bottom (before '</body>' tag)
# 插入代码到头部 </head> 之前 和 底部 </body> 之前
inject:
head:
# 自定义css
# - <link rel="stylesheet" href="/css/custom.css" media="defer" onload="this.media='all'">
- <link rel="stylesheet" href="/css/time_flies.css" media="defer" onload="this.media='all'">

bottom:
# 自定义js
# - <script src="/js/xxx"></script>
- <script src="/js/time_flies.js"></script>

7.检查效果生成

最后 Hexo 三连(hexo c && hexo g && hexo s)就可以看到文章中第二张图调用的效果。