MeNav 项目使用 Handlebars 作为模板引擎,实现了组件化架构,将页面内容与逻辑分离。模板系统的核心优势:
templates/
├── layouts/ # 布局模板 - 定义页面整体结构
│ └── default.hbs # 默认布局
├── pages/ # 页面模板 - 对应不同页面内容
│ ├── page.hbs # 通用页面模板(默认/回退模板;普通页面常用)
│ ├── content.hbs # 内容页(Markdown 内容页:构建期渲染)
│ ├── projects.hbs # 项目页(repo 风格卡片)
│ ├── articles.hbs # 文章页(RSS 聚合/只读文章条目)
│ ├── bookmarks.hbs # 书签页
│ └── search-results.hbs # 搜索结果页(内置)
├── components/ # 组件模板 - 可复用的界面元素
│ ├── page-header.hbs # 统一标题区(首页/非首页/书签更新时间/项目热力图)
│ ├── navigation.hbs # 导航组件
│ ├── site-card.hbs # 站点卡片组件
│ ├── category.hbs # 分类组件
│ └── ...
└── README.md # 本文档
布局模板定义了整个页面的HTML结构,包含头部、导航栏、内容区和底部等基本框架。
位置: templates/layouts/
主要布局:
default.hbs - 默认布局,定义整个页面框架示例:
页面模板对应网站的不同页面,每个页面模板通常包含多个组件组合。
位置: templates/pages/
主要页面:
page.hbs - 通用页面模板(默认/回退模板;普通页面常用)content.hbs - 内容页(从本地 Markdown 文件构建期渲染为 HTML)bookmarks.hbs - 书签页projects.hbs - 项目页articles.hbs - 文章页search-results.hbs - 搜索结果说明:MeNav 不再依赖
home.hbs作为首页模板。 “首页/默认打开页”由site.yml -> navigation的第一项决定;首页可使用任意页面模板,具体取决于该页面配置(pages/<homePageId>.yml的template字段与回退规则)。
内容页用于承载“关于 / 帮助 / 使用说明 / 更新日志 / 迁移指南”等纯文本内容。
content.file 指向本地 .md 文件(例如 content/about.md)![]() 不会被渲染)site.yml -> security.allowedSchemes 白名单策略处理,不安全链接会被降级为 #对应模板文件:templates/pages/content.hbs
配置写法示例见:
config/README.md的“内容页(template: content)”。
示例 (page.hbs):
组件是可复用的UI元素,用于在不同页面中重复使用。
位置: templates/components/
说明:生成器启动时会自动扫描
templates/components/下的所有.hbs并注册为 Handlebars partial(partial 名称=文件名去掉.hbs)。因此新增组件后无需手动“注册步骤”,可直接通过 `` 引用。
主要组件:
page-header.hbs - 统一页面标题区(首页/非首页/书签更新时间/项目热力图)home-dashboard.hbs - 首页仪表盘(时钟卡片、TODO 待办卡片)navigation.hbs - 导航菜单site-card.hbs - 站点卡片category.hbs - 分类容器(支持多层级嵌套)group.hbs - 分组容器(支持多层级嵌套)social-links.hbs - 社交链接示例 (site-card.hbs,精简展示关键结构):
说明:
type=article:用于 articles Phase 2 的只读文章条目卡片(仍保留 data-* 结构;扩展解析应以 data-type="article" 区分类型)style=repo:用于 projects 的代码仓库风卡片(展示 language/stars/forks 等只读元信息)category.hbs 是多层级嵌套的核心组件,可渲染 categories -> subcategories -> groups -> sites 的结构;更深一层的 subgroups 由 group.hbs 负责渲染。
功能特性:
categories -> subcategories -> groups -> subgroups -> sites,其中 subgroups 可选)category-level-2、group-level-4)递归渲染原理: 通过在模板内部调用自身实现递归渲染:
level参数的作用:
使用示例:
group.hbs 是用于在分类内组织站点的组件,同样支持层级参数。
功能特性:
subgroups,用于第 4 层结构)使用示例:
典型的(最多 4 层)结构:分类 → 子分类 → 分组 → 子分组 → 站点(subgroups 可选)
# 配置示例
categories:
- name: '技术'
icon: 'fas fa-code'
subcategories:
- name: '前端开发'
icon: 'fas fa-laptop-code'
groups:
- name: '框架'
icon: 'fas fa-cubes'
subgroups:
- name: 'React生态'
icon: 'fab fa-react'
sites:
- name: 'React'
url: 'https://reactjs.org'
icon: 'fab fa-react'
- name: 'Next.js'
url: 'https://nextjs.org'
icon: 'fas fa-triangle'
对应的模板渲染:
每个层级都有对应的CSS类:
category-level-1, category-level-2group-level-3, group-level-4这种设计确保了:
当启用 icons.mode: favicon(默认)时,站点卡片会优先显示站点 favicon;当 URL 非 http/https、加载失败或网络受限,则自动回退到 Font Awesome 图标。相关助手:ifHttpUrl(条件)与 encodeURIComponent(工具)。
站点级覆盖(可选,写在每个 sites[] 节点上):
faviconUrl:为单站点指定图标链接(优先级最高,失败回退到手动图标;本地路径建议以 assets/ 开头,构建会复制到 dist/ 同路径)forceIconMode: favicon | manual:强制该站点使用指定模式(不设置则跟随全局 icons.mode)faviconUrl > forceIconMode > 全局 icons.mode注意:用于根据站点 URL 生成 faviconV2 地址的模板 helper 已更名为
faviconV2Url,从而避免与站点字段faviconUrl同名冲突;自定义模板如需生成 faviconV2 地址,请使用。如需强制读取站点字段 `faviconUrl`,也可使用(推荐在复杂上下文中显式读取字段)。
示例(与内置组件实现保持一致):
提示:关于 icons.mode 的配置与隐私说明,请参见:
config/README.md 的 site.yml 常用字段:../config/README.md#siteyml-常用字段README.md 的“近期更新”:../README.md#近期更新MeNav 模板系统的数据流如下:
generator.js 加载配置文件并处理数据layouts/default.hbs) 作为外层容器pages/*.hbs) 填充布局中的内容区域components/*.hbs) 在页面中通过 `` 引用主要数据对象:
site - 网站配置信息navigationData - 导航菜单数据categories - 分类和站点数据profile - 个人资料数据social - 社交链接数据常见派生字段(由生成器注入,供模板差异化使用):
homePageId:首页页面 ID(始终等于 navigation 第一项的 id)pageId:当前页面 ID(用于 .page-template- 等)pageMeta.updatedAt/updatedAtSource:仅 bookmarks 模板页用于“update: YYYY-MM-DD |
from: …”展示 |
projectsMeta.heatmap:仅 projects 模板页用于右侧 GitHub 热力图展示(需要配置 site.github.username)articlesItems/articlesCategories:仅 articles 模板页(Phase 2)用于渲染只读文章条目(RSS 缓存存在时)提示:页面模板是“页面内容片段”,不要包含
<!DOCTYPE html>等整页骨架;整页骨架由layouts/default.hbs负责。
布局模板通常只有一个 default.hbs,会自动被系统使用。
页面模板对应导航中的各个页面,有两种使用方式:
projects 时会使用 projects.hbs)template 字段指定要使用的模板在 config/user/pages/项目.yml 中:
title: '我的项目'
subtitle: '这里展示我的所有项目'
template: 'projects' # 使用 projects.hbs 模板而不是使用页面ID命名的模板
categories:
- name: '网站项目'
icon: 'fas fa-globe'
sites:
- name: '个人博客'
# ... 其他字段
注意:当系统找不到指定的模板或与页面ID匹配的模板时,会自动使用通用模板 page.hbs。
在页面或其他组件中引用组件:
根据条件显示内容:
循环渲染数据列表:
site-card.hbs、search-results.hbstemplates/pages/ 创建新的 .hbs 文件config/user/site.yml 的 navigation 部分添加页面配置(配置采用“完全替换”策略,推荐使用 user 配置)示例:
templates/components/ 创建新的 .hbs 文件示例:
使用新组件: