侧边栏云端文件树改造记录:中文目录、分类树与 SPA 导航
WordPress 迁移到 Hugo 后,顺手把主题(ark)的侧边栏云端文件树整体重构了一遍。这篇记录改造的思路、结构与踩坑,方便日后维护。
需求来源
原本的侧边栏云端树只有”按分类分组的文章 + 散落的页面链接”,分类和文件都是英文 slug,页面路径直接裸暴露(如 pages/friends/index.md),既不美观也不符合中文站点的使用习惯。改造目标是:
- 目录全部中文化,文件树里显示文章标题而不是英文 slug
- 结构分层:页面 / 归档 / 分类 / 标签 / 管理 五个一级目录
- 分类、标签做成文件树,可配置显示哪些分类
- 点击目录时:展开文件树 + 打开对应列表页,且不刷新浏览器(SPA)
最终结构
☁ 云端
├─ 📁 页面
│ ├─ Arkylin的小屋 ← 主页(显示网站名,点击回首页)
│ ├─ 示例页面.md(紫色) ← pages 目录的页面,标题显示
│ └─ 友情链接.md ...
├─ 📁 归档 ← 链接到 /archives/
│ ├─ 📁 2019 (35) ← 按年份分组,带文章计数
│ ├─ 📁 2020 (72)
│ └─ ...
├─ 📁 分类 ← 链接到 /categories/
│ ├─ 📁 学习(带链接) ← 点击跳转 /categories/学习/
│ │ └─ 文章标题.md
│ └─ ...
├─ 📁 标签 ← 链接到 /tags/
│ ├─ Aliyun (1)
│ └─ ...(70 个,默认折叠)
└─ 📁 管理
├─ admin.md / settings.md / account.md
关键实现
1. 分类按配置显示
hugo.toml 里通过 [params.sidebar] 控制:
[params.sidebar]
# 允许显示的分类文件夹(留空 = 全部显示)
show_categories = ['学习', '开发', '日记', '代码', 'VPS测评', '记录', '测评', '未分类']
模板里用 in $showCats . 过滤分类文件夹;一篇文章有多个分类时,按分类分组(Go 模板 dict 累加),自然在多个分类文件夹里同时出现。
2. 点击目录:展开树 + SPA 打开页面
文件树的文件夹 label 用 <span data-tree-link="/categories/">,点击时由 JS 处理:
document.addEventListener('click', function (e) {
var el = e.target.closest('[data-tree-link]');
if (!el) return;
var href = el.getAttribute('data-tree-link');
if (!href) return;
var d = el.closest('details');
if (d) d.open = true; // 展开文件树
if (typeof navigateTo === 'function') {
navigateTo(href); // 主题自带 SPA 导航,不刷新
} else {
window.location.href = href;
}
});
关键点:不要直接 window.location.href = href——主题(ark)有完整的 SPA 路由(navigateTo,fetch 页面 + DOMParser 替换内容),直接赋值会整页刷新,丢失编辑器 tab、树高亮等状态。点击后新页面树默认展开(<details open>)。
3. 层级引导线
云端树原本没有层级竖线,本地虚拟树有,视觉不一致。用伪元素 + 重复渐变实现连续列线(每行按深度画所有祖先列,避免”线被二级目录截断”):
.file-tree .tree-depth-1 > summary::after,
.file-tree .file-item.tree-depth-2::after,
/* ...depth 1-5 */
{
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: calc(13px + ((var(--tree-depth) - 1) * 12px) + 12px);
background: repeating-linear-gradient(
to right,
transparent 0 12px,
color-mix(in srgb, var(--line) 68%, transparent) 12px 13px
);
}
4. 目录行高统一(踩坑)
文件夹的 summary 是 3 列网格 grid-template-columns: 16px 18px minmax(0, 1fr)。给”年份文件夹”加文章计数后变成 4 个元素,第 4 个被挤到下一行,行高直接翻倍(22px → 44px),看起来”有的目录大有的小”:
.file-tree .tree-folder.is-year > summary {
grid-template-columns: 16px 18px minmax(0, 1fr) auto;
}
另外,文件夹 label 用 <a> 和 <span> 渲染观感不同(链接有默认交互样式),统一用 <span> + JS 跳转,目录大小/颜色才完全一致。分类文件夹原有的蓝色图标也一并改回灰色,与标签/归档文件夹统一。
遗留
- 本地虚拟树(浏览器本地文件)和云端树结构不同,云端已中文化,本地保持原样
extra_dirs配置项已废弃(归档固定为一级目录),如需在页面文件夹下追加自定义目录可恢复该逻辑
相关文件
themes/ark/layouts/partials/sidebar.html— 云端树模板 + 点击跳转 JSthemes/ark/assets/css/ark-sidebar.7d3ea819.css— 引导线、is-year 网格、label 样式hugo.toml—[params.sidebar]分类显示配置