fix(icons): faviconV2 加入 drop_404_icon=true 参数避免404占位图以触发回退

- helpers:faviconV2Url / faviconFallbackUrl 统一追加 drop_404_icon=true
- runtime:新增站点的 faviconV2 com/cn URL 同步追加该参数
- docs:更新模板与 helper 文档示例
- test:新增用例防止参数回归
This commit is contained in:
rbetree
2026-01-16 22:51:00 +08:00
parent 0e154bc43e
commit d19c4da51d
5 changed files with 168 additions and 88 deletions

View File

@@ -53,9 +53,11 @@ templates/
**位置**: `templates/layouts/`
**主要布局**:
- `default.hbs` - 默认布局,定义整个页面框架
**示例**:
```handlebars
<!DOCTYPE html>
<html lang="zh-CN">
@@ -70,7 +72,7 @@ templates/
<nav class="sidebar">
{{> navigation navigationData}}
</nav>
<!-- 内容区域 -->
<main class="content">
{{#each pages}}
@@ -91,6 +93,7 @@ templates/
**位置**: `templates/pages/`
**主要页面**:
- `page.hbs` - 通用页面模板(默认/回退模板;普通页面常用)
- `bookmarks.hbs` - 书签页
- `projects.hbs` - 项目页
@@ -102,6 +105,7 @@ templates/
> “首页/默认打开页”由 `site.yml -> navigation` 的**第一项**决定;首页可使用任意页面模板,具体取决于该页面配置(`pages/<homePageId>.yml` 的 `template` 字段与回退规则)。
**示例** (`page.hbs`):
```handlebars
<div class="page-template page-template-{{pageId}}">
{{> page-header}}
@@ -120,6 +124,7 @@ templates/
> 说明:生成器启动时会自动扫描 `templates/components/` 下的所有 `.hbs` 并注册为 Handlebars partialpartial 名称=文件名去掉 `.hbs`)。因此新增组件后无需手动“注册步骤”,可直接通过 `{{> component-name}}` 引用。
**主要组件**:
- `page-header.hbs` - 统一页面标题区(首页/非首页/书签更新时间/项目热力图)
- `navigation.hbs` - 导航菜单
- `site-card.hbs` - 站点卡片
@@ -128,6 +133,7 @@ templates/
- `social-links.hbs` - 社交链接
**示例** (`site-card.hbs`,精简展示关键结构):
```handlebars
{{#if url}}
<a href="{{url}}"
@@ -146,6 +152,7 @@ templates/
```
说明:
- `type=article`:用于 articles Phase 2 的只读文章条目卡片(仍保留 `data-*` 结构;扩展解析应以 `data-type="article"` 区分类型)
- `style=repo`:用于 projects 的代码仓库风卡片(展示 language/stars/forks 等只读元信息)
@@ -156,6 +163,7 @@ templates/
`category.hbs` 是多层级嵌套的核心组件,可渲染 `categories -> subcategories -> groups -> sites` 的结构;更深一层的 `subgroups``group.hbs` 负责渲染。
**功能特性**:
- 支持 2~4 层嵌套(`categories -> subcategories -> groups -> subgroups -> sites`,其中 `subgroups` 可选)
- 自动计算标题层级h2/h3/h4/h5
- 根据层级自动应用对应的 CSS 类(如 `category-level-2``group-level-4`
@@ -163,6 +171,7 @@ templates/
**递归渲染原理**:
通过在模板内部调用自身实现递归渲染:
```handlebars
{{#each subcategories}}
{{> category level=2}}
@@ -170,12 +179,14 @@ templates/
```
**level参数的作用**:
- 用于跟踪当前嵌套层级
- 控制标题标签的层级h{{add level 1}}
- 应用对应的CSS类category-level-{{level}}
- 传递给子组件以保持层级一致性
**使用示例**:
```handlebars
<!-- 顶级分类 -->
{{> category category}}
@@ -189,6 +200,7 @@ templates/
`group.hbs` 是用于在分类内组织站点的组件,同样支持层级参数。
**功能特性**:
- 支持在分类内创建站点分组
- 支持子分组(`subgroups`,用于第 4 层结构)
- 自动应用层级样式
@@ -196,6 +208,7 @@ templates/
- 与category.hbs保持一致的层级系统
**使用示例**:
```handlebars
<!-- 在分类模板中使用 -->
{{#each groups}}
@@ -213,27 +226,28 @@ templates/
```yaml
# 配置示例
categories:
- name: "技术"
icon: "fas fa-code"
- name: '技术'
icon: 'fas fa-code'
subcategories:
- name: "前端开发"
icon: "fas fa-laptop-code"
- name: '前端开发'
icon: 'fas fa-laptop-code'
groups:
- name: "框架"
icon: "fas fa-cubes"
- name: '框架'
icon: 'fas fa-cubes'
subgroups:
- name: "React生态"
icon: "fab fa-react"
- 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"
- name: 'React'
url: 'https://reactjs.org'
icon: 'fab fa-react'
- name: 'Next.js'
url: 'https://nextjs.org'
icon: 'fas fa-triangle'
```
对应的模板渲染:
```handlebars
<!-- category.hbs 会递归渲染 -->
<section class="category category-level-1" data-level="1">
@@ -287,10 +301,12 @@ categories:
- **层级4 (level=4)**: 子分组使用h5标题用于 4 层结构)
每个层级都有对应的CSS类
- `category-level-1`, `category-level-2`
- `group-level-3`, `group-level-4`
这种设计确保了:
1. 语义化的HTML结构
2. 一致的视觉层级
3. 可预测的嵌套深度(当前导入脚本与样式保证到 level=4
@@ -301,6 +317,7 @@ categories:
当启用 `icons.mode: favicon`(默认)时,站点卡片会优先显示站点 favicon当 URL 非 http/https、加载失败或网络受限则自动回退到 Font Awesome 图标。相关助手:`ifHttpUrl`(条件)与 `encodeURIComponent`(工具)。
站点级覆盖(可选,写在每个 `sites[]` 节点上):
- `faviconUrl`:为单站点指定图标链接(优先级最高,失败回退到手动图标;本地路径建议以 `assets/` 开头,构建会复制到 `dist/` 同路径)
- `forceIconMode: favicon | manual`:强制该站点使用指定模式(不设置则跟随全局 `icons.mode`
- 优先级:`faviconUrl` > `forceIconMode` > 全局 `icons.mode`
@@ -324,7 +341,7 @@ categories:
<i class="fas fa-circle-notch fa-spin icon-placeholder" aria-hidden="true"></i>
<img
class="favicon-icon"
src="https://t3.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url={{encodeURIComponent url}}&size=32"
src="https://t3.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url={{encodeURIComponent url}}&size=32&drop_404_icon=true"
alt="{{name}} favicon"
loading="lazy"
onload="this.classList.add('loaded'); this.previousElementSibling.classList.add('hidden');"
@@ -345,6 +362,7 @@ categories:
```
提示:关于 `icons.mode` 的配置与隐私说明,请参见:
- `config/README.md``site.yml 常用字段`[`../config/README.md#siteyml-常用字段`](../config/README.md#siteyml-%E5%B8%B8%E7%94%A8%E5%AD%97%E6%AE%B5)
- 根目录 `README.md` 的“近期更新”:[`../README.md#近期更新`](../README.md#%E8%BF%91%E6%9C%9F%E6%9B%B4%E6%96%B0)
@@ -359,6 +377,7 @@ MeNav 模板系统的数据流如下:
5. 组件模板 (`components/*.hbs`) 在页面中通过 `{{> component-name}}` 引用
主要数据对象:
- `site` - 网站配置信息
- `navigationData` - 导航菜单数据
- `categories` - 分类和站点数据
@@ -366,6 +385,7 @@ MeNav 模板系统的数据流如下:
- `social` - 社交链接数据
常见派生字段(由生成器注入,供模板差异化使用):
- `homePageId`:首页页面 ID始终等于 `navigation` 第一项的 `id`
- `pageId`:当前页面 ID用于 `.page-template-{{pageId}}` 等)
- `pageMeta.updatedAt/updatedAtSource`:仅 bookmarks 模板页用于“update: YYYY-MM-DD | from: ...”展示
@@ -377,26 +397,29 @@ MeNav 模板系统的数据流如下:
## 模板使用示例
### 布局模板使用
布局模板通常只有一个 `default.hbs`,会自动被系统使用。
### 页面模板使用
页面模板对应导航中的各个页面,有两种使用方式:
1. **自动匹配**系统会尝试使用与页面ID同名的模板例如页面ID为 `projects` 时会使用 `projects.hbs`
2. **显式指定**:在页面配置中使用 `template` 字段指定要使用的模板
#### 模板指定示例
`config/user/pages/项目.yml` 中:
```yaml
title: "我的项目"
subtitle: "这里展示我的所有项目"
template: "projects" # 使用 projects.hbs 模板而不是使用页面ID命名的模板
title: '我的项目'
subtitle: '这里展示我的所有项目'
template: 'projects' # 使用 projects.hbs 模板而不是使用页面ID命名的模板
categories:
- name: "网站项目"
icon: "fas fa-globe"
- name: '网站项目'
icon: 'fas fa-globe'
sites:
- name: "个人博客"
- name: '个人博客'
# ... 其他字段
```
@@ -417,9 +440,9 @@ categories:
```handlebars
{{#if profile.title}}
<h2>{{profile.title}}</h2>
<h2>{{profile.title}}</h2>
{{else}}
<h2>欢迎使用</h2>
<h2>欢迎使用</h2>
{{/if}}
```
@@ -467,22 +490,23 @@ categories:
3. 页面内容可引用现有组件或创建新组件
示例:
```handlebars
<!-- templates/pages/about.hbs -->
<div class="about-page">
<h2>关于我</h2>
<p>{{about.description}}</p>
{{#if about.skills}}
<div class="skills">
<h3>技能</h3>
<ul>
{{#each about.skills}}
<li>{{this}}</li>
{{/each}}
</ul>
<div class='about-page'>
<h2>关于我</h2>
<p>{{about.description}}</p>
{{#if about.skills}}
<div class='skills'>
<h3>技能</h3>
<ul>
{{#each about.skills}}
<li>{{this}}</li>
{{/each}}
</ul>
</div>
{{/if}}
{{/if}}
</div>
```
@@ -492,17 +516,19 @@ categories:
2. 在页面或其他组件中引用
示例:
```handlebars
<!-- templates/components/skill-card.hbs -->
<div class="skill-card">
<h4>{{name}}</h4>
<div class="skill-level" data-level="{{level}}">
<div class="skill-bar" style="width: {{level}}%"></div>
</div>
<div class='skill-card'>
<h4>{{name}}</h4>
<div class='skill-level' data-level='{{level}}'>
<div class='skill-bar' style='width: {{level}}%'></div>
</div>
</div>
```
使用新组件:
```handlebars
{{#each skills}}
{{> skill-card}}