以下步骤基于hexo stellar主题进行。

Stellar 主题自带模块

基本的配置见官方文档:Stellar:网站和主题基本信息配置 - XAOXUU

Memos & Timeline

提醒:自己搭建memos需要域名和服务器,谨慎开启。

  1. 首先安装docker,参考Windows 环境下安装 Docker 的详细教程(超详细图文)_docker安装windows-CSDN博客。当然,对于我这种折腾过太多次的老油条,直接在Docker Desktop: The #1 Containerization Tool for Developers | Docker下载AMD64版,安装,GITHUB登录就可以了。

  2. 接下来在CMD中用DOCKER安装:docker run -d --name memos -p 5230:5230 -v ~/.memos/:/var/opt/memos neosmemo/memos:latest

  3. 访问 http://localhost:5230/

  4. 注册MEMOS。自己的localhost,自己当然是管理员。

  5. 部署MEMOS。需要一个服务器,这里选择clawcloud的最低等级VPS service:请稍候…。教程见:操作指南 | ClawCloud文档概览 | ClawCloud文档

    1. 创建好VPS后,SSH登录到VPS。
    2. 输入密码后,安装DOCKER环境,进行MEMOS部署。参考:搭建开源、轻量级笔记服务 Memos - 兔哥博客
    3. API地址:https://memos.yourdomain.com/api/v1/memo?creatorId=1&rowStatus=NORMAL&limit=10
    4. 把API地址加到timeline插件或是页面中:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      timeline:  # widgets.yml
      layout: timeline
      title: 近期动态
      api: https://memos.yantares.cn/api/v1/memos
      user: # 默认显示所有人的数据,设置名称可过滤为仅显示某人的数据,多个名称用英文逗号隔开,不要加空格
      limit: # 默认通过 api 上增加 per_page 来设置,如果是友链朋友圈,可通过这个设置数量

      {% timeline api:https://memos.yantares.cn/api/v1/memos type:memos %} # index.md
      {% endtimeline %}

偷师

根据IP显示欢迎语

根据参考源,注册腾讯地图账号并获取APIkey。

需要在主题config.yml的plugin中引入jquery和自定义的json:(json见参考源)

1
2
3
4
5
6
txmap_widget:
enable: true
inject: |
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
<script data-pjax src="/js/services/txmap.js"></script>

足迹地图TravelMap

简而言之就是导入一个静态地图,鼠标放在省份上时显示预定义的去过次数。

贴一个Gemini帮我写的超简单index.md,放在map文件夹内即可。可以自定义省份去过次数、省份快捷跳转文章等:

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
---
title: 我的足迹地图
---
<div id="main" style="width: 100%; height: 70vh; min-height: 450px; border-radius: var(--card-border-radius, 16px);"></div>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts/map/js/china.js"></script>
<script type="text/javascript">
var chartDom = document.getElementById('main');
var initialTheme = document.documentElement.getAttribute('data-theme') || 'light';
var myChart = echarts.init(chartDom, initialTheme);
// value: 请确保这里填写的是您“去过的次数”
var myData = [
{name: '四川', value: 10},
{name: '上海', value: 8},
{name: '内蒙古', value: 3},
{name: '甘肃', value: 1},
{name: '青海', value: 1},
{name: '西藏', value: 1},
{name: '广西', value: 5},
{name: '云南', value: 1},
{name: '贵州', value: 1, link: 'https://yantares.cn/2025/08/15/%E9%9A%8F%E7%AC%94/%E5%85%AD%E7%9B%98%E6%B0%B4%E6%B8%B8%E8%AE%B0/'},
{name: '海南', value: 1},
{name: '陕西', value: 1},
{name: '吉林', value: 1},
{name: '浙江', value: 1},
{name: '江苏', value: 4},
{name: '北京', value: 2},
{name: '台湾', value: 1},
];
function getMapOption(theme) {
var isDark = theme === 'dark';
var themeColor = 'hsl(192 98% 55%)'; // 约 #05D9FF (Stellar 主题色)
var accentColor = 'hsl(14 100% 57%)'; // 约 #FF5722 (Stellar 强调色)
var visitedColor = isDark ? themeColor : '#A6C8FF';
var unvisitedColor = isDark ? 'rgba(255, 255, 255, 0.1)' : '#E0E0E0';
var textColor = isDark ? '#FFFFFF' : '#000000';
var tooltipBg = isDark ? 'rgba(0, 0, 0, 0.85)' : 'rgba(255, 255, 255, 0.9)';
var tooltipBorder = isDark ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.1)';
var linkColor = isDark ? accentColor : '#FF6347'; // 链接使用强调色
return {
backgroundColor: 'transparent', // 地图背景透明
tooltip: {
trigger: 'item',
backgroundColor: tooltipBg,
borderColor: tooltipBorder,
borderWidth: 1,
textStyle: {
color: textColor,
fontSize: 14
},
formatter: function (params) {
if (params.data && params.data.value > 0) {
let content = `<strong style="font-size: 16px; margin-bottom: 5px; display: block;">${params.name}</strong>`;
content += `去过 ${params.data.value} 次`;
if (params.data.link) {
content += `<br/><a href="${params.data.link}" target="_blank" style="color: ${linkColor}; text-decoration: underline;">查看相关游记</a>`;
}
return content;
} else {
return `<strong style="font-size: 16px;">${params.name}</strong><br/>未去过`;
}
}
},
visualMap: {
min: 0,
max: 10, // !!确保这个 max 值 >= 您 myData 中的最大 value 值
left: 'left',
top: 'bottom',
text: ['去过', '未去'],
calculable: false,
textStyle: {
color: textColor
},
inRange: {
color: [unvisitedColor, visitedColor, themeColor]
},
show: true
},
series: [
{
name: '足迹',
type: 'map',
map: 'china',
roam: true,
label: {
show: false
},
emphasis: {
label: {
show: true,
color: textColor
},
itemStyle: { // 留空,ECharts 会自动提亮
}
},
data: myData
}
]
};
}
myChart.setOption(getMapOption(initialTheme));
function bindClickEvent(chartInstance) {
chartInstance.on('click', function (params) {
if (params.data && params.data.link) {
window.open(params.data.link);
}
});
}
bindClickEvent(myChart);
function handleThemeChange() {
var currentTheme = document.documentElement.getAttribute('data-theme') || 'light';
myChart.dispose();
myChart = echarts.init(chartDom, currentTheme);
myChart.setOption(getMapOption(currentTheme));
bindClickEvent(myChart);
}
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'attributes' && mutation.attributeName === 'data-theme') {
handleThemeChange();
}
});
});
observer.observe(document.documentElement, {
attributes: true
});
window.addEventListener('resize', function() {
myChart.resize();
});
</script>

obsidian 联动

Callout Block

  1. 更换渲染器

    1. 卸载默认渲染器:npm uninstall hexo-renderer-marked --save
    2. 安装新渲染器:npm install hexo-renderer-markdown-it-plus --save
  2. 安装参考源博主写的插件,并在 _config.yml 中增加相应配置

    1. npm install markdown-it-obsidian-callouts
    2. 注意,在博客根目录的_config.yml 中配置,而非主题的_config.yml
      1. 配置高亮引擎(实现 Callout 和高级代码块并存):为了同时拥有 Callout 功能和 Stellar 主题原生的高级代码块(带行号、复制按钮),让 Hexo 负责高亮,让 markdown-it-plus 负责 Callout。
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        # 1. 启用 Hexo 原生的高亮引擎
        # 这是为了生成 Stellar 主题认识的 <figure class="highlight"> 结构
        syntax_highlighter: highlight.js

        # 2. 配置原生高亮,开启你需要的功能
        highlight:
        line_number: true
        auto_detect: true
        tab_replace: ''
        wrap: true
        hljs: true # 确保开启

        # 3. 注释掉所有其他冲突的高亮插件
        # prismjs:
        # preprocess: true
        # ...
        # prism_plugin:
        # mode: 'preprocess'
        # ...
      2. 更改markdown配置为:
        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
        markdown_it_plus:
        preset: "default"
        highlight: false # <--- 关键!必须为 false,防止双重渲染冲突
        render:
        html: true
        xhtmlOut: false
        langPrefix: "language-"
        breaks: true
        linkify: true
        typographer: true
        quotes: "“”‘’"
        enable_rules:
        disable_rules:
        plugins:
        # Callouts 插件
        - plugin:
        name: markdown-it-obsidian-callouts
        enable: true
        # Checkbox 插件
        - plugin:
        name: markdown-it-checkbox
        enable: true
        # Expandable 插件 (可折叠块)
        - plugin:
        name: markdown-it-expandable
        enable: true
        # Image Size 插件
        - plugin:
        name: markdown-it-imsize
        enable: true
        anchors:
        level: 2
        collisionSuffix: ""
        permalink: false
        permalinkClass: "header-anchor"
        permalinkSide: "left"
        permalinkSymbol: "¶"
        case: 0
        separator: "-"
        一定注意把所有markdown相关插件都配置好。如果渲染成普通的引用块(blockquote),可以试试删除node_modules、db.json、package-lock.json,再npm install试试。
  3. 引入CSS

    1. 在参考源博主的基础上加了折叠、展开block的功能:
      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
      :root {
      --line-height-tight: 1.3;
      --callout-border-width: 0px;
      --callout-border-opacity: 0.25;
      --callout-padding: 18px 12px 1px 15px;
      --callout-radius: 4px;
      --callout-title-color: inherit;
      --callout-title-padding: 0;
      --callout-title-size: inherit;
      --callout-title-weight: 600;
      --callout-content-padding: 0;
      --callout-content-background: transparent;
      --callout-blend-mode: var(darken);
      --callout-default: 8, 109, 221;
      --callout-info: 0, 176, 255;
      /*--callout-todo: 8, 109, 221;*/
      --callout-bug: 233, 49, 71;
      --callout-error: 233, 49, 71;
      --callout-fail: 233, 49, 71;
      --callout-success: 8, 185, 78;
      --callout-example: 120, 82, 238;
      --callout-important: 0, 191, 188;
      --callout-summary: 0, 191, 188;
      --callout-tip: 0, 191, 188;
      --callout-question: 232, 148, 0;
      --callout-warning: 236, 117, 0;
      --callout-quote: 158, 158, 158;
      --callout-collapse-icon: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMiIgZD0ibTkgMThsNi02bC02LTYiLz48L3N2Zz4=");
      }
      .theme-light {
      --callout-blend-mode: var(darken);
      }
      .theme-dark {
      --callout-blend-mode: var(lighten);
      }
      html[data-theme="light"] #app {
      --callout-blend-mode: var(darken);
      }
      html[data-theme="dark"] #app {
      --callout-blend-mode: var(lighten);
      }
      .callout {
      /*overflow: hidden;*/
      border-style: solid;
      border-color: rgba(var(--callout-color), var(--callout-border-opacity));
      border-width: var(--callout-border-width);
      border-radius: var(--callout-radius);
      margin: 1em 0;
      mix-blend-mode: var(--callout-blend-mode);
      background-color: rgba(var(--callout-color), 0.1);
      padding: var(--callout-padding);
      --callout-color: var(--callout-default);
      --callout-icon: lucide-pencil;
      }
      .callout .callout-title {
      padding: var(--callout-title-padding);
      display: flex;
      gap: 7px;
      font-size: var(--callout-title-size);
      color: rgb(var(--callout-color));
      line-height: var(--line-height-tight);
      align-items: flex-start;
      }
      .callout.is-collapsible .callout-title {
      margin-bottom: 12px;
      cursor: pointer;
      }
      .callout .callout-title .callout-icon {
      flex: 0 0 auto;
      display: flex;
      align-items: center;
      }
      .callout-title-icon svg {
      width: 19px; /* 宽度 */
      height: 19px; /* 高度 */
      }
      .callout .callout-title .callout-title-inner {
      --font-weight: var(--callout-title-weight);
      font-weight: var(--font-weight);
      color: var(--callout-title-color);
      }
      .callout .callout-title .callout-fold {
      background-color: rgb(var(--callout-color));
      mask-image: var(--callout-collapse-icon);
      mask-size: 100%;
      -webkit-mask-image: var(--callout-collapse-icon);
      -webkit-mask-size: 100%;
      height: 15px; /* 可调整 */
      width: 19px; /* 可调整 */
      transition: 100ms ease-in-out;
      }
      .callout.is-collapsible.is-collapsed > .callout-title > .callout-fold {
      transform: rotate(-90deg);
      }
      .callout.is-collapsible:not(.is-collapsed) > .callout-title > .callout-fold {
      transform: rotate(90deg);
      }
      .callout .callout-content {
      /*overflow-x: auto;*/
      padding: var(--callout-content-padding);
      background-color: var(--callout-content-background);
      }
      .callout[data-callout="info"], .callout[data-callout="todo"] {
      --callout-color: var(--callout-info);
      --callout-icon: lucide-check-circle-2;
      }
      .callout[data-callout="success"], .callout[data-callout="check"], .callout[data-callout="done"] {
      --callout-color: var(--callout-success);
      --callout-icon: lucide-check;
      }
      .callout[data-callout="warning"], .callout[data-callout="caution"], .callout[data-callout="attention"]
      {
      --callout-color: var(--callout-warning);
      --callout-icon: lucide-alert-triangle;
      }
      .callout[data-callout="question"], .callout[data-callout="help"], .callout[data-callout="faq"]
      {
      --callout-color: var(--callout-question);
      --callout-icon: lucide-alert-triangle;
      }
      .callout[data-callout="danger"], .callout[data-callout="error"], .callout[data-callout="bug"],
      .callout[data-callout="failure"], .callout[data-callout="fail"], .callout[data-callout="missing"]
      {
      --callout-color: var(--callout-error);
      --callout-icon: lucide-zap;
      }
      .callout[data-callout="tip"], .callout[data-callout="hint"], .callout[data-callout="important"] {
      --callout-color: var(--callout-tip);
      --callout-icon: lucide-flame;
      }
      .callout[data-callout="example"] {
      --callout-color: var(--callout-example);
      --callout-icon: lucide-list;
      }
      .callout[data-callout="abstract"], .callout[data-callout="summary"], .callout[data-callout="tldr"] {
      --callout-color: var(--callout-summary);
      --callout-icon: lucide-clipboard-list;
      }
      .callout[data-callout="quote"], .callout[data-callout="cite"] {
      --callout-color: var(--callout-quote);
      --callout-icon: quote-glyph;
      }
    2. 将CSS inject到主题的_config.yml ,各主题的操作不同。Stellar主题可在plugins中加入以下代码,并将CSS放在主题文件夹的对应路径内:
      1
      2
      3
      4
      callout_blocks:
      enable: true
      inject: |
      <link rel="stylesheet" href="/css/callout_blocks.css">
    3. 为了解决 Callout 之外的样式问题(如列表缩进、文本选中、代码块颜色),需要在自定义样式文件(例如 source/_data/_custom.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
      // ==================================================
      // 1. 修复:强制恢复文本选中
      // ==================================================
      .md-text
      user-select: text !important
      -webkit-user-select: text !important

      // ==================================================
      // 2. 修复:列表首层缩进过大 (精准打击 li 内部的 p 标签)
      // ==================================================
      .md-text li p
      text-indent: 0 !important
      margin-top: 0.2em !important
      margin-bottom: 0.2em !important

      // 辅助:确保列表容器的缩进是合理的
      .md-text ol,
      .md-text ul
      padding-inline-start: 1.5em !important
      margin-left: 0 !important
      list-style-position: outside !important

      .md-text li
      text-indent: 0 !important
      padding-left: 0.2em !important
      margin-left: 0 !important

      // ==================================================
      // 3. 修复:代码块颜色与 Callout 冲突 (强制统一为深色)
      // ==================================================
      // 强制外层容器使用深色背景
      .md-text .highlight
      background: #282c34 !important
      color: #abb2bf !important
      border-radius: var(--border-bar)

      // 强制内层元素背景透明
      .md-text .highlight table,
      .md-text .highlight tr,
      .md-text .highlight td,
      .md-text .highlight pre,
      .md-text .highlight code
      background: transparent !important
      border: none !important

      // 修复行号区域 (纯白)
      .md-text .highlight .gutter
      background: #282c34 !important
      border-right: 1px solid #3e4451 !important
      color: #ffffff !important

      .md-text .highlight .gutter pre,
      .md-text .highlight .gutter span
      color: #ffffff !important

      // 修复代码块标题栏/语言提示 (纯白)
      .md-text .highlight figcaption
      background: #21252b !important
      color: #ffffff !important
      border-bottom: 1px solid #3e4451 !important

      .md-text .highlight figcaption a,
      .md-text .highlight:after,
      .md-text .highlight:before
      color: #ffffff !important

完毕。

PS:Obsidian内部代码块的显示更改可使用第三方插件Codeblock Custimizer。

「图书馆」页面

「图书馆」

目标:
在 Hexo 博客中创建一个 yoursite.com/library/ 页面。这个页面会自动抓取所有“读罢有感”分类下的文章,并以精美卡片的形式(包含封面、评分、作者、短评、分类标签)按阅读完成时间倒序排列。

优点:

  • 全自动: 只需在 _posts 目录中按格式写一篇新书评,这个页面会自动更新。

  • 可靠: 不使用易出错的 tag 插件或 EJS 页面渲染,而是使用 Hexo 的 generator。它保证在所有文章被加载完毕后才执行。

Step 1 规范书评 Front-matter

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
---
title: 银河系搭车客指南
date: 2025-11-10 12:00:00
categories:
- 读罢有感 # 关键:脚本将通过这个分类来查找
completed: 2025-11-01 # 关键:脚本将通过这个日期来排序
cover: /imgs/hitchhiker-cover.jpg # 卡片封面图
author: 道格拉斯·亚当斯 # 卡片信息
score: ⭐⭐⭐⭐⭐ # 卡片信息
comment: 英式喜剧。 # 卡片信息
type:
- 科幻小说 # 卡片上的“类型”小标签
---
书评正文...

注意: 只有同时包含 categories: [读罢有感]completed 字段的文章才会被收录。

Step 2 创建页面生成器

scripts/ 文件夹中,创建一个文件(或覆盖旧文件),命名为 library-generator.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
// 文件位置: /scripts/library-generator.js
// 描述:一个“一体化”脚本,它会抓取数据、生成HTML,并创建页面。

hexo.extend.generator.register('library_page_generator', function(locals) {

// --- 1. 抓取并筛选数据 (来自 locals.posts) ---
// locals.posts 此时包含了所有文章,非常可靠
const catName = '读罢有感';
let books = locals.posts.data.filter(p => {
// 筛选逻辑:必须有 'completed' 字段
if (!p.completed || !p.categories || !p.categories.length) {
return false;
}
return p.categories.some(cat => cat.name === catName);
});

// --- 2. 排序 ---
books.sort((a, b) => new Date(b.completed) - new Date(a.completed));

// --- 3. 把数据"翻译"成 HTML 卡片 ---
let cardHtml = '';
if (books && books.length > 0) {
cardHtml += '<div class="grid-items match-height">';

books.forEach(p => {
// 准备卡片描述
let cardDesc = '';
if (p.score) cardDesc += `<span style="margin-right: 8px;">${Array.isArray(p.score) ? p.score.join('') : p.score}</span>`;
if (p.author) cardDesc += `<span>${p.author}</span>`;
if (p.comment) cardDesc += `<br><span style="opacity:0.8; font-size: 0.9em;">${p.comment}</span>`;

// 提取 'type' 字段作为标签
const type = (p.type && p.type.length > 0) ? (Array.isArray(p.type) ? p.type[0] : p.type) : '';
let typeHtml = '';
if (type) {
typeHtml = `<span class="card-type-tag">${type}</span>`;
}

// 处理文章和封面的路径
const postPath = hexo.config.root + p.path;
// 健壮性修复:检查 p.cover 是否存在,防止崩溃
const coverPath = (p.cover && p.cover.startsWith('/')) ? hexo.config.root + p.cover.substring(1) : (p.cover || '');

cardHtml += `
<div class="grid-item">
<a class="card-link" href="${postPath}" title="${p.title}">
<div class="card-bg" style="background-image: url('${coverPath}')"></div>
<div class="card-body">
${typeHtml}
<div class="card-content">
<h3 class="card-title">${p.title}</h3>
<div class="card-desc">${cardDesc}</div>
</div>
</div>
</a>
</div>
`;
});
cardHtml += '</div>';
} else {
cardHtml = '<p>图书馆正在整理中,还没有书...</p>';
}

// --- 4. 嵌入所有必需的 CSS 样式 ---
const pageStyle = `
<style>
.wiki-library .grid-items { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); grid-gap: 16px; }
.wiki-library .grid-item { border-radius: 12px; overflow: hidden; background: var(--card-bg); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); transition: all 0.2s ease; }
.wiki-library .grid-item:hover { transform: translateY(-4px); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.12); }
.wiki-library .card-bg { height: 160px; background-size: cover; background-position: center; background-color: #eee; transition: transform 0.3s ease-out; }
.wiki-library .grid-item:hover .card-bg { transform: scale(1.05); }
.wiki-library .card-body { padding: 12px; }
.wiki-library .card-title { margin: 0 0 8px 0 !important; font-size: 1.1em; line-height: 1.4; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wiki-library .card-desc { font-size: 0.9em; opacity: 0.8; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.wiki-library .card-type-tag {
display: inline-block;
background-color: var(--stellar-card-bg-assist, var(--stellar-card-bg, #f3f3f3));
color: var(--stellar-text-color-assist, #888);
font-size: 0.75em;
padding: 2px 8px;
border-radius: 4px;
margin-bottom: 8px;
font-weight: 500;
}
</style>
`;

const fullHtmlContent = pageStyle + '<div class="wiki-library">' + cardHtml + '</div>';

// --- 5. 返回一个完整的“虚拟页面”给 Hexo ---
return {
path: 'library/index.html', // 最终的 URL
layout: 'page', // 使用你主题的 'page' 布局
data: {
title: '图书馆', // 页面标题
content: fullHtmlContent, // 我们生成的 HTML 将被注入为"正文"
comments: true // 开启评论
}
};
});

附:如何(我们如何)修复图标脚本

如果你有一个会给所有链接添加小图标的 JS 脚本,它可能会影响卡片美观度。

修复: 在图标脚本中,增加一个检查,让它跳过所有 card-link 类的链接。

1
2
3
4
5
6
7
8
9
10
11
// ...
links.forEach(function(link) {

// 增加检查:
if (link.classList.contains('card-link')) {
return; // 跳过图书馆卡片
}

// ...
});
// ...


本站总访问量次!

本站由 Yantares 使用 Stellar 1.33.1 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

发表了 96 篇文章 · 总计 175k 字