左栏组件
个人名片
1 | profile: |
外观类配置项
| 配置项 | 说明 | 默认值 |
|---|---|---|
avatar |
头像图片路径 | 主题自带占位头像 |
avatar_size |
头像直径,接受 72px 这类带单位值,或直接写数字 72(按 px 处理) |
64px |
title |
头像下方的主标题(如昵称、站名) | 空 |
title_icon |
主标题左侧的小图标,常配站点 favicon 使用 |
空 |
badge |
头像右下角角标文字 | 不显示 |
badge_title |
角标的鼠标悬停提示 | 空 |
bio |
简介文字;写成 bio: false 或留空可整段隐藏 |
取站点 description |
social_title |
社交图标区上方的小标题 | 空 |
icon_size |
社交图标直径(数字,按 px 处理) | 19 |
社交链接
social[].name决定图标,可用:github/bilibili/telegram/mail/rss/link。social[].title同时作为图标的title与无障碍标签,鼠标悬停可见。avatar加载失败时会自动回退到主题自带的占位头像。- 不写
name和bio时,会回退到站点_config.yml的author和description。 - 想省掉社交区,直接把
social整体注释掉即可,标题和分隔线会一并隐藏。
头像与角标尺寸用的是 CSS 变量(
--avatar-size/--icon-size)实现,因此改动后无需改动任何样式文件。
音乐播放器
单曲模式:
1 | music: |
歌单模式(填了 playlist 就优先用它):
1 | music: |
播放器支持播放/暂停、上一首、下一首、随机、循环和音量。
浏览器通常禁止自动播放,需要访客手动点一次播放键。
src必须是直链(以.mp3/.m4a结尾),网盘分享页不能直接播放。
分类与标签
1 | category: |
显示顺序按内容数量从多到少,数量为 0 的分类不会出现。
左栏分类是跟随页面上下文的:
- 首页、归档页:显示全部分类;
- 文章页(文章总页、文章详情页、文章分类页):只显示含有文章的分类;
- 资源页(资源总页、类型页、资源详情页):只显示含有资源帖的分类。
这样文章读者不会被资源分类干扰,资源访客也看不到纯文章分类,两侧列表都更短、更聚焦。
右栏组件
站点统计
1 | stats: |
show 数组控制显示哪些行以及顺序,删掉哪一项就不显示哪一项。
运行时长从 since 开始计算。
日历
1 | calendar: |
日历支持翻月,当天有描边标记,有文章的日期会显示小圆点,
下方列出最近更新的 3 篇内容。
站点信息
1 | siteinfo: |
页脚
1 | footer: |
页脚会显示 © 2024 - 2026 这样的年份区间,起始年份取 since。
开了 beian 之后会额外显示一条备案链接。
接入评论
主题内置 Giscus(基于 GitHub Discussions),在 _config.yml 里填好参数即可:
1 | comments: |
前置条件:目标仓库必须是 public,并已安装 giscus 应用、开启 Discussions。
- 评论框在正文上方(
input_position: top),深浅色跟随站点主题切换。 - 换成 Waline / Twikoo 等其它服务:改
layout/_partial/comments.ejs里的脚本即可,
文章页的引入位置不用动。
入场动画
卡片滚动进入视口时会淡入上移,由 echo.js 里的 IntersectionObserver 实现,默认开启。
想关掉的话,删除 source/js/echo.js 中「Reveal on scroll」那一段即可。
常见问题
菜单点了打不开 / 页面空白
先看终端有没有报错。最常见的原因是模板里引用了不存在的变量,
或者生成器返回的 page.posts 被当成了 Query 对象处理。
1 | npx hexo clean && npx hexo generate |
重新生成时终端会直接指出出错的文件和行号。
改了配置不生效
分三种情况:
| 改了什么 | 需要做什么 |
|---|---|
themes/echo/_config.yml |
重启 hexo server |
站点 _config.yml |
重启 hexo server |
scripts/*.js(生成器) |
重启 hexo server |
| CSS / JS / 模板 | 一般热更新,必要时强刷(Ctrl+F5) |
改了
colors.accent却没变?主色是在head.ejs里注入的,
如果你改的是编译后的public/css/echo.css,下次生成会被覆盖——
要改就改themes/echo/_config.yml,然后hexo clean && hexo generate。
浅色主题下横幅还是原来的深色 / 灰色
自己写浅色覆盖规则时,最容易踩的两个坑:
- 选择器优先级不够。主题里深色状态的横幅用的是
.page-banner.has-banner .page-banner-card(三个 class),
而[data-theme='light'] .page-banner-card(一个属性 + 一个 class)压不过它。
写浅色规则时必须带上.page-banner/.has-banner上下文,把优先级提上去。 - 横幅大图写在 HTML 内联样式里。
.page-banner的style="background-image:url(...)"是模板输出的内联属性,
普通 CSS 盖不住,需要在浅色规则里用background: ... !important压制。
另外浅色规则要同时照顾两个属性:data-theme(head.ejs 里的运行时 JS 写入)
和 data-theme-hint(layout.ejs 直接输出的配置值,用于 JS 尚未执行时防闪帧)。
验证时如果无头浏览器也跟着系统深色渲染,可以临时做一个强制data-theme="light" 的验证页截图确认,改完记得删掉。
排查口诀:改完 CSS → hexo clean && hexo generate → 停掉旧 server 换端口重启 → 浏览器强刷。
只改源文件就断定”没生效”是最常见的原因,因为运行中的 server 会一直供旧 CSS。
窄屏展开菜单后白底白字(浅色主题)
如果你是照着上一条 FAQ 给自己写浅色规则时遇到的,八成是踩了同一个坑:
首页 Hero 的导航是透明悬浮在深色大图上的,所以浅色规则会主动排除它
(:not(.has-hero)),让白字保留。可是窄屏展开的抽屉菜单是
自带实底浮层(background: var(--bg-elev),浅色下为纯白),
它的链接同样继承了白字 —— 于是白底白字。
判断原则:看这个元素自己有没有底色。
- 有自己的实底(抽屉、卡片、弹窗)→ 文字必须跟随主题色,用
var(--text)/var(--text-soft) - 透明悬浮在大图上(首页顶栏)→ 固定用白字,任何主题都一样
主题里对应的修法(≤900px 生效):
1 | @media (max-width: 900px) { |
抽屉在深色主题下本来就是深底白字,所以这条只需要覆盖浅色。
资源没出现在资源库
按顺序检查:
- front-matter 里
resource.enable是不是true resource.type的值是否与站点_config.yml里resources.types[].key一致- 文章文件是否放在
source/_posts/下 - 有没有执行过
hexo clean
侧栏收起后目录不见了
这是预期行为:右栏在 1280px 以下会收起,
此时目录会转移到正文顶部的可折叠区块,不会丢失。
封面图不显示
- 确认路径以
/开头,且文件真实存在于source/images/下。 - 路径是相对站点 source,不是相对文章文件。
- 没有封面时卡片会显示渐变占位块,属于正常回退。
导航栏挡住锚点
主题已通过 scroll-padding-top 处理锚点偏移,
滚动到标题时不会贴在导航栏下面。如果你自定义了导航高度,
记得同步调整 --header-h 变量。
进阶定制
改配色
主题所有颜色都走 CSS 变量,定义在 echo.css 顶部的 :root:
1 | :root { |
深色模式只需覆盖 [data-theme='dark'] 里的同名变量。
加一个侧栏组件
- 在
layout/_rail/下新建your-widget.ejs - 在
layout/_partial/rail-left.ejs或rail-right.ejs里引入 - 在主题
_config.yml里加对应的enable开关
组件外层用 rail-card 类就能自动继承卡片样式:
1 | <section class="rail-card"> |
发布主题前要清理什么
- 主题
_config.yml里的个人信息、头像、社交链接 source/images/下你自己上传的图片- 演示文章(
source/_posts/里的示例内容) public/与.deploy_git/之类的构建产物
想改某个字段的中文名 / 显示逻辑
资源字段(版本 / 平台 / 大小 / 语言 / 更新日期)的映射与过滤统一在scripts/helper.js:
1 | const RESOURCE_FIELD_LABELS = { version: '版本', platform: '平台', /* ... */ }; |
改这里会同时影响资源卡片、资源详情页摘要、普通文章卡片三处,不用逐个模板改。
其他 helper 也都集中在同一个文件底部注册,模板里通过 echo_xxx 调用。
主题代码里哪些是「公开 API」,改动需谨慎
| 位置 | 作用 | 稳定性 |
|---|---|---|
helper.js 的 echo_* helper |
模板可调用的函数 | 稳定,改动会影响所有模板 |
source/css/echo.css 的 --* 变量 |
主题对外暴露的设计变量 | 稳定,自定义 CSS 建议只改这些 |
.rail-card / .field-chip / .btn 等类 |
供你在 Markdown 里直接用的组件类 | 稳定,可放心在正文里用 |
scripts/articles.js 等生成器 |
改站点数据来源 | 内部实现,改动需同步生成器逻辑 |
反过来,下面这些不要依赖:
- 纯为视觉服务的状态类(
has-hero/is-scrolled/is-compact等),
它们会随主题实现调整 .ab-*(卡片网格)、.hd-*(下载区)这类给 Markdown 手写内容用的组件类,
虽然保留但版式可能微调
系列总结
六篇下来,你应该已经掌握:
- 主题的架构与目录职责
- 安装启用与两套配置文件的区别
- 三栏布局、响应式收栏与首页大图
- 资源帖写法、网盘链接与配色
- 写作规范、代码块与文章页开关
- 侧栏组件、页脚与问题排查
后续计划:资源排序与筛选增强、磁力链接支持、评论系统开箱接入。
评论