feat: 页面模板差异化改进 + 配置优化 + 兼容清理 (#29)
- 首页判定:navigation 第一项 - 模板:page/projects/articles/bookmarks/search-results - bookmarks:update: YYYY-MM-DD | from: git|mtime - articles:RSS 聚合只读条目 + 分类聚合 + 影子写回结构 - projects:repo 卡片 + 可选热力图 + 自动抓取元信息 - 工作流:构建前 sync + schedule 定时刷新 - 移除兼容:config.yml/config.yaml、navigation.yml、home 特例 - 迁移说明:config/update-instructions.md
This commit is contained in:
@@ -30,10 +30,13 @@ templates/
|
||||
├── layouts/ # 布局模板 - 定义页面整体结构
|
||||
│ └── default.hbs # 默认布局
|
||||
├── pages/ # 页面模板 - 对应不同页面内容
|
||||
│ ├── home.hbs # 首页
|
||||
│ ├── page.hbs # 通用页面模板(默认/回退模板;普通页面常用)
|
||||
│ ├── projects.hbs # 项目页(repo 风格卡片)
|
||||
│ ├── articles.hbs # 文章页(RSS 聚合/只读文章条目)
|
||||
│ ├── bookmarks.hbs # 书签页
|
||||
│ └── ...
|
||||
│ └── search-results.hbs # 搜索结果页(内置)
|
||||
├── components/ # 组件模板 - 可复用的界面元素
|
||||
│ ├── page-header.hbs # 统一标题区(首页/非首页/书签更新时间/项目热力图)
|
||||
│ ├── navigation.hbs # 导航组件
|
||||
│ ├── site-card.hbs # 站点卡片组件
|
||||
│ ├── category.hbs # 分类组件
|
||||
@@ -88,20 +91,24 @@ templates/
|
||||
**位置**: `templates/pages/`
|
||||
|
||||
**主要页面**:
|
||||
- `home.hbs` - 首页
|
||||
- `page.hbs` - 通用页面模板(默认/回退模板;普通页面常用)
|
||||
- `bookmarks.hbs` - 书签页
|
||||
- `projects.hbs` - 项目页
|
||||
- `articles.hbs` - 文章页
|
||||
- `search-results.hbs` - 搜索结果
|
||||
- 其他自定义页面
|
||||
|
||||
**示例** (`home.hbs`):
|
||||
> 说明:MeNav 不再依赖 `home.hbs` 作为首页模板。
|
||||
> “首页/默认打开页”由 `site.yml -> navigation` 的**第一项**决定;首页可使用任意页面模板,具体取决于该页面配置(`pages/<homePageId>.yml` 的 `template` 字段与回退规则)。
|
||||
|
||||
**示例** (`page.hbs`):
|
||||
```handlebars
|
||||
<div class="welcome-section">
|
||||
<h2>{{profile.title}}</h2>
|
||||
<h3>{{profile.subtitle}}</h3>
|
||||
<div class="page-template page-template-{{pageId}}">
|
||||
{{> page-header}}
|
||||
{{#each categories}}
|
||||
{{> category}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{#each categories}}
|
||||
{{> category}}
|
||||
{{/each}}
|
||||
```
|
||||
|
||||
### 组件模板
|
||||
@@ -110,25 +117,38 @@ templates/
|
||||
|
||||
**位置**: `templates/components/`
|
||||
|
||||
> 说明:生成器启动时会自动扫描 `templates/components/` 下的所有 `.hbs` 并注册为 Handlebars partial(partial 名称=文件名去掉 `.hbs`)。因此新增组件后无需手动“注册步骤”,可直接通过 `{{> component-name}}` 引用。
|
||||
|
||||
**主要组件**:
|
||||
- `page-header.hbs` - 统一页面标题区(首页/非首页/书签更新时间/项目热力图)
|
||||
- `navigation.hbs` - 导航菜单
|
||||
- `site-card.hbs` - 站点卡片
|
||||
- `category.hbs` - 分类容器(支持多层级嵌套)
|
||||
- `group.hbs` - 分组容器(支持多层级嵌套)
|
||||
- `social-links.hbs` - 社交链接
|
||||
- `search-results.hbs` - 搜索结果展示
|
||||
|
||||
**示例** (`site-card.hbs`):
|
||||
**示例** (`site-card.hbs`,精简展示关键结构):
|
||||
```handlebars
|
||||
{{#if url}}
|
||||
<a href="{{url}}" class="site-card{{#if style}} site-card-{{style}}{{/if}}" title="{{name}} - {{description}}" {{#if external}}target="_blank" rel="noopener"{{/if}}>
|
||||
<i class="{{#if icon}}{{icon}}{{else}}fas fa-link{{/if}}"></i>
|
||||
<h3>{{#if name}}{{name}}{{else}}未命名站点{{/if}}</h3>
|
||||
<p>{{description}}</p>
|
||||
<a href="{{url}}"
|
||||
class="site-card{{#if style}} site-card-{{style}}{{/if}}"
|
||||
{{#if external}}target="_blank" rel="noopener"{{/if}}
|
||||
data-type="{{#if type}}{{type}}{{else}}site{{/if}}"
|
||||
data-name="{{name}}"
|
||||
data-url="{{url}}">
|
||||
<div class="site-card-icon">...</div>
|
||||
<div class="site-card-content">
|
||||
<h3>{{#if name}}{{name}}{{else}}未命名站点{{/if}}</h3>
|
||||
<p>{{description}}</p>
|
||||
</div>
|
||||
</a>
|
||||
{{/if}}
|
||||
```
|
||||
|
||||
说明:
|
||||
- `type=article`:用于 articles Phase 2 的只读文章条目卡片(仍保留 `data-*` 结构;扩展解析应以 `data-type="article"` 区分类型)
|
||||
- `style=repo`:用于 projects 的代码仓库风卡片(展示 language/stars/forks 等只读元信息)
|
||||
|
||||
### 多层级嵌套模板组件
|
||||
|
||||
#### category.hbs - 分类容器组件
|
||||
@@ -338,6 +358,15 @@ MeNav 模板系统的数据流如下:
|
||||
- `profile` - 个人资料数据
|
||||
- `social` - 社交链接数据
|
||||
|
||||
常见派生字段(由生成器注入,供模板差异化使用):
|
||||
- `homePageId`:首页页面 ID(始终等于 `navigation` 第一项的 `id`)
|
||||
- `pageId`:当前页面 ID(用于 `.page-template-{{pageId}}` 等)
|
||||
- `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` 负责。
|
||||
|
||||
## 模板使用示例
|
||||
|
||||
### 布局模板使用
|
||||
@@ -427,7 +456,7 @@ categories:
|
||||
### 添加新页面
|
||||
|
||||
1. 在 `templates/pages/` 创建新的 `.hbs` 文件
|
||||
2. 在 `config/_default/site.yml` 的 `navigation` 部分添加页面配置
|
||||
2. 在 `config/user/site.yml` 的 `navigation` 部分添加页面配置(配置采用“完全替换”策略,推荐使用 user 配置)
|
||||
3. 页面内容可引用现有组件或创建新组件
|
||||
|
||||
示例:
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<div class="sites-grid" data-container="sites">
|
||||
{{#if sites.length}}
|
||||
{{#each sites}}
|
||||
{{> site-card}}
|
||||
{{> site-card style=@root.siteCardStyle}}
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<p class="empty-sites">暂无网站</p>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<div class="sites-grid" data-container="sites">
|
||||
{{#if sites.length}}
|
||||
{{#each sites}}
|
||||
{{> site-card}}
|
||||
{{> site-card style=@root.siteCardStyle}}
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<p class="empty-sites">暂无网站</p>
|
||||
|
||||
36
templates/components/page-header.hbs
Normal file
36
templates/components/page-header.hbs
Normal file
@@ -0,0 +1,36 @@
|
||||
{{!-- page-header.hbs - 统一页面标题区(可选显示书签页内容更新时间) --}}
|
||||
<div class="welcome-section{{#ifCond projectsMeta '&&' projectsMeta.heatmap}} welcome-section-with-side{{/ifCond}}">
|
||||
<div class="welcome-section-main">
|
||||
{{#ifEquals pageId @root.homePageId}}
|
||||
<h2 data-editable="profile-title">{{title}}</h2>
|
||||
<h3 data-editable="profile-subtitle">{{subtitle}}</h3>
|
||||
{{else}}
|
||||
<div class="welcome-title-row">
|
||||
<h2 data-editable="page-title">{{title}}</h2>
|
||||
{{#if pageMeta}}
|
||||
{{#if pageMeta.updatedAt}}
|
||||
<span class="page-updated-inline" title="{{pageMeta.updatedAt}}">
|
||||
update: {{formatDate pageMeta.updatedAt "YYYY-MM-DD"}} | from: {{pageMeta.updatedAtSource}}
|
||||
</span>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<p class="subtitle" data-editable="page-subtitle">{{subtitle}}</p>
|
||||
{{/ifEquals}}
|
||||
</div>
|
||||
|
||||
{{#if projectsMeta}}
|
||||
{{#if projectsMeta.heatmap}}
|
||||
<div class="welcome-section-side">
|
||||
<div class="heatmap-container" title="我的 GitHub 贡献热力图">
|
||||
<a href="{{projectsMeta.heatmap.profileUrl}}" target="_blank" rel="noopener">
|
||||
<img class="heatmap-img"
|
||||
src="{{projectsMeta.heatmap.imageUrl}}"
|
||||
alt="Github Chart"
|
||||
loading="lazy" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
@@ -1,11 +0,0 @@
|
||||
<!-- 搜索结果组件 -->
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="page-title">搜索结果</h2>
|
||||
<p class="subtitle" data-editable="page-subtitle">在所有页面中找到的匹配项</p>
|
||||
</div>
|
||||
{{#each navigation}}
|
||||
<section class="category search-section" data-section="{{id}}" data-type="category" data-name="{{name}}" data-icon="{{icon}}" style="display: none;">
|
||||
<h2 data-editable="category-name"><i class="{{icon}}"></i> {{name}}匹配项</h2>
|
||||
<div class="sites-grid" data-container="sites"></div>
|
||||
</section>
|
||||
{{/each}}
|
||||
@@ -1,37 +1,123 @@
|
||||
{{#if url}}
|
||||
<a href="{{url}}" class="site-card{{#if style}} site-card-{{style}}{{/if}}"
|
||||
{{#if external}}target="_blank" rel="noopener"{{/if}}
|
||||
data-type="site"
|
||||
data-type="{{#if type}}{{type}}{{else}}site{{/if}}"
|
||||
data-name="{{name}}"
|
||||
data-url="{{url}}"
|
||||
data-icon="{{#if icon}}{{icon}}{{else}}fas fa-link{{/if}}"
|
||||
data-description="{{#if description}}{{description}}{{else}}{{extractDomain url}}{{/if}}">
|
||||
<div class="site-card-icon" aria-hidden="true">
|
||||
{{#ifEquals @root.icons.mode "favicon"}}
|
||||
{{#ifHttpUrl url}}
|
||||
<div class="icon-container">
|
||||
<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"
|
||||
alt="{{name}} favicon"
|
||||
loading="lazy"
|
||||
onload="this.classList.add('loaded'); this.previousElementSibling.classList.add('hidden');"
|
||||
onerror="this.classList.add('error'); this.previousElementSibling.classList.add('hidden'); this.nextElementSibling.classList.add('visible');"
|
||||
/>
|
||||
<i class="{{#if icon}}{{icon}}{{else}}fas fa-link{{/if}} icon-fallback" aria-hidden="true"></i>
|
||||
data-description="{{#if description}}{{description}}{{else}}{{extractDomain url}}{{/if}}"
|
||||
{{#if publishedAt}}data-published-at="{{publishedAt}}"{{/if}}
|
||||
{{#if source}}data-source="{{source}}"{{/if}}>
|
||||
{{!-- articles:首行图标+标题;下方“时间/来源 + 简介”全宽对齐,不被图标列缩进 --}}
|
||||
{{#ifEquals type "article"}}
|
||||
<div class="article-card-header">
|
||||
<div class="site-card-icon" aria-hidden="true">
|
||||
{{#ifEquals @root.icons.mode "favicon"}}
|
||||
{{#ifHttpUrl url}}
|
||||
<div class="icon-container">
|
||||
<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"
|
||||
alt="{{name}} favicon"
|
||||
loading="lazy"
|
||||
onload="this.classList.add('loaded'); this.previousElementSibling.classList.add('hidden');"
|
||||
onerror="this.classList.add('error'); this.previousElementSibling.classList.add('hidden'); this.nextElementSibling.classList.add('visible');"
|
||||
/>
|
||||
<i class="{{#if icon}}{{icon}}{{else}}fas fa-link{{/if}} icon-fallback" aria-hidden="true"></i>
|
||||
</div>
|
||||
{{else}}
|
||||
<i class="{{#if icon}}{{icon}}{{else}}fas fa-link{{/if}} site-icon" aria-hidden="true"></i>
|
||||
{{/ifHttpUrl}}
|
||||
{{else}}
|
||||
<i class="{{#if icon}}{{icon}}{{else}}fas fa-link{{/if}} site-icon" aria-hidden="true"></i>
|
||||
{{/ifEquals}}
|
||||
</div>
|
||||
<div class="article-card-title">
|
||||
<h3>{{#if name}}{{name}}{{else}}未命名站点{{/if}}</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="article-card-body">
|
||||
{{#ifCond publishedAt '||' source}}
|
||||
<div class="site-card-meta">
|
||||
{{#if publishedAt}}
|
||||
<span class="site-card-meta-date">{{formatDate publishedAt "YYYY-MM-DD"}}</span>
|
||||
{{/if}}
|
||||
{{#ifCond publishedAt '&&' source}}
|
||||
<span class="site-card-meta-sep">·</span>
|
||||
{{/ifCond}}
|
||||
{{#if source}}
|
||||
<span class="site-card-meta-source">{{source}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/ifCond}}
|
||||
<p>{{#if description}}{{description}}{{else}}{{extractDomain url}}{{/if}}</p>
|
||||
</div>
|
||||
{{else}}
|
||||
{{!-- projects:代码仓库风格卡片(保留 data-* 结构,便于扩展识别与写回) --}}
|
||||
{{#ifEquals style "repo"}}
|
||||
<div class="repo-header">
|
||||
<i class="{{#if icon}}{{icon}}{{else}}fas fa-code{{/if}} repo-icon" aria-hidden="true"></i>
|
||||
<div class="repo-title">{{#if name}}{{name}}{{else}}未命名项目{{/if}}</div>
|
||||
</div>
|
||||
|
||||
<div class="repo-desc">{{#if description}}{{description}}{{else}}{{extractDomain url}}{{/if}}</div>
|
||||
|
||||
{{#ifCond language '||' stars}}
|
||||
<div class="repo-stats">
|
||||
{{#if language}}
|
||||
<div class="stat-item">
|
||||
<span class="lang-dot" style="background-color: {{#if languageColor}}{{languageColor}}{{else}}#909296{{/if}};"></span>
|
||||
{{language}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if stars}}
|
||||
<div class="stat-item">
|
||||
<i class="far fa-star" aria-hidden="true"></i> {{stars}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if forks}}
|
||||
<div class="stat-item">
|
||||
<i class="fas fa-code-branch" aria-hidden="true"></i> {{forks}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if issues}}
|
||||
<div class="stat-item">
|
||||
<i class="fas fa-exclamation-circle" aria-hidden="true"></i> {{issues}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/ifCond}}
|
||||
{{else}}
|
||||
<div class="site-card-icon" aria-hidden="true">
|
||||
{{#ifEquals @root.icons.mode "favicon"}}
|
||||
{{#ifHttpUrl url}}
|
||||
<div class="icon-container">
|
||||
<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"
|
||||
alt="{{name}} favicon"
|
||||
loading="lazy"
|
||||
onload="this.classList.add('loaded'); this.previousElementSibling.classList.add('hidden');"
|
||||
onerror="this.classList.add('error'); this.previousElementSibling.classList.add('hidden'); this.nextElementSibling.classList.add('visible');"
|
||||
/>
|
||||
<i class="{{#if icon}}{{icon}}{{else}}fas fa-link{{/if}} icon-fallback" aria-hidden="true"></i>
|
||||
</div>
|
||||
{{else}}
|
||||
<i class="{{#if icon}}{{icon}}{{else}}fas fa-link{{/if}} site-icon" aria-hidden="true"></i>
|
||||
{{/ifHttpUrl}}
|
||||
{{else}}
|
||||
<i class="{{#if icon}}{{icon}}{{else}}fas fa-link{{/if}} site-icon" aria-hidden="true"></i>
|
||||
{{/ifHttpUrl}}
|
||||
{{else}}
|
||||
<i class="{{#if icon}}{{icon}}{{else}}fas fa-link{{/if}} site-icon" aria-hidden="true"></i>
|
||||
{{/ifEquals}}
|
||||
</div>
|
||||
{{/ifEquals}}
|
||||
</div>
|
||||
|
||||
<div class="site-card-content">
|
||||
<h3>{{#if name}}{{name}}{{else}}未命名站点{{/if}}</h3>
|
||||
<p>{{#if description}}{{description}}{{else}}{{extractDomain url}}{{/if}}</p>
|
||||
</div>
|
||||
<div class="site-card-content">
|
||||
<h3>{{#if name}}{{name}}{{else}}未命名站点{{/if}}</h3>
|
||||
<p>{{#if description}}{{description}}{{else}}{{extractDomain url}}{{/if}}</p>
|
||||
</div>
|
||||
{{/ifEquals}}
|
||||
{{/ifEquals}}
|
||||
</a>
|
||||
{{/if}}
|
||||
|
||||
@@ -1,14 +1,66 @@
|
||||
{{#ifEquals pageId @root.homePageId}}
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="profile-title">{{title}}</h2>
|
||||
<h3 data-editable="profile-subtitle">{{subtitle}}</h3>
|
||||
{{!-- articles.hbs - 文章页面:恢复分类展示;Phase 2 优先展示文章条目(只读) --}}
|
||||
<div class="page-template page-template-articles">
|
||||
{{> page-header}}
|
||||
|
||||
{{#if articlesItems.length}}
|
||||
{{!-- Phase 2:按配置分类聚合展示文章条目(只读),保持与页面分类结构一致 --}}
|
||||
{{#if articlesCategories.length}}
|
||||
{{#each articlesCategories}}
|
||||
<section class="category category-level-1 category-readonly">
|
||||
<div class="category-header" data-toggle="category">
|
||||
<h2>
|
||||
<i class="{{#if icon}}{{icon}}{{else}}fas fa-rss{{/if}}"></i>
|
||||
{{name}}
|
||||
<span class="toggle-icon">
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</span>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="category-content">
|
||||
{{#if items.length}}
|
||||
<div class="sites-grid">
|
||||
{{#each items}}
|
||||
{{> site-card type="article" style=@root.siteCardStyle}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{else}}
|
||||
<p class="empty-content">暂无文章</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
</section>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
{{!-- 兜底:无分类映射时展示为单一“最新文章”列表 --}}
|
||||
<section class="category category-level-1 category-readonly">
|
||||
<div class="category-header" data-toggle="category">
|
||||
<h2>
|
||||
<i class="fas fa-rss"></i>
|
||||
最新文章
|
||||
<span class="toggle-icon">
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</span>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="category-content">
|
||||
<div class="sites-grid">
|
||||
{{#each articlesItems}}
|
||||
{{> site-card type="article" style=@root.siteCardStyle}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{/if}}
|
||||
|
||||
{{!-- 保留扩展可写回结构(隐藏),避免文章条目影响 DOM → IR → YAML --}}
|
||||
<div class="menav-extension-shadow" data-extension-shadow="true" data-search-exclude="true" aria-hidden="true">
|
||||
{{#each categories}}
|
||||
{{> category}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{!-- Phase 1:来源站点入口(可写回) --}}
|
||||
{{#each categories}}
|
||||
{{> category}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="page-title">{{title}}</h2>
|
||||
<p class="subtitle" data-editable="page-subtitle">{{subtitle}}</p>
|
||||
</div>
|
||||
{{/ifEquals}}
|
||||
{{#each categories}}
|
||||
{{> category}}
|
||||
{{/each}}
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
{{#ifEquals pageId @root.homePageId}}
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="profile-title">{{title}}</h2>
|
||||
<h3 data-editable="profile-subtitle">{{subtitle}}</h3>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="page-title">{{title}}</h2>
|
||||
<p class="subtitle" data-editable="page-subtitle">{{subtitle}}</p>
|
||||
</div>
|
||||
{{/ifEquals}}
|
||||
{{> page-header}}
|
||||
{{#each categories}}
|
||||
{{> category}}
|
||||
{{/each}}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
{{#ifEquals pageId @root.homePageId}}
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="profile-title">{{title}}</h2>
|
||||
<h3 data-editable="profile-subtitle">{{subtitle}}</h3>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="page-title">{{title}}</h2>
|
||||
<p class="subtitle" data-editable="page-subtitle">{{subtitle}}</p>
|
||||
</div>
|
||||
{{/ifEquals}}
|
||||
{{#each categories}}
|
||||
{{> category}}
|
||||
{{/each}}
|
||||
@@ -1,14 +0,0 @@
|
||||
{{#ifEquals pageId @root.homePageId}}
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="profile-title">{{title}}</h2>
|
||||
<h3 data-editable="profile-subtitle">{{subtitle}}</h3>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="page-title">{{title}}</h2>
|
||||
<p class="subtitle" data-editable="page-subtitle">{{subtitle}}</p>
|
||||
</div>
|
||||
{{/ifEquals}}
|
||||
{{#each categories}}
|
||||
{{> category}}
|
||||
{{/each}}
|
||||
@@ -1,142 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{site.title}}</title>
|
||||
<link rel="icon" href="./{{site.favicon}}" type="image/x-icon">
|
||||
<link rel="shortcut icon" href="./{{site.favicon}}" type="image/x-icon">
|
||||
<link href="{{{googleFontsLink}}}" rel="stylesheet">
|
||||
<style>
|
||||
{{{fontVariables}}}
|
||||
</style>
|
||||
<!-- 预设主题和侧边栏状态,避免闪烁 -->
|
||||
<script>
|
||||
(function() {
|
||||
// 读取并应用主题设置
|
||||
var savedTheme = localStorage.getItem('theme');
|
||||
if (savedTheme === 'light') {
|
||||
document.documentElement.classList.add('theme-preload');
|
||||
}
|
||||
|
||||
// 读取并应用侧边栏状态
|
||||
var sidebarCollapsed = localStorage.getItem('sidebarCollapsed') === 'true';
|
||||
var isMobile = window.innerWidth <= 768;
|
||||
if (sidebarCollapsed && !isMobile) {
|
||||
document.documentElement.classList.add('sidebar-collapsed-preload');
|
||||
}
|
||||
|
||||
// 添加这个类用于控制初始渲染
|
||||
document.documentElement.classList.add('preload');
|
||||
})();
|
||||
</script>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.7.2/css/all.min.css">
|
||||
</head>
|
||||
<body class="loading">
|
||||
<!-- 滚动进度指示条 -->
|
||||
<div class="scroll-progress"></div>
|
||||
<div class="layout">
|
||||
<!-- 移动端按钮 -->
|
||||
<div class="mobile-buttons">
|
||||
<button class="menu-toggle" aria-label="切换菜单">
|
||||
<i class="fas fa-bars"></i>
|
||||
</button>
|
||||
<button class="search-toggle" aria-label="切换搜索">
|
||||
<i class="fas fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 遮罩层 -->
|
||||
<div class="overlay"></div>
|
||||
|
||||
<!-- 左侧导航 -->
|
||||
<nav class="sidebar">
|
||||
<div class="logo">
|
||||
<h1>{{site.logo_text}}</h1>
|
||||
<button class="sidebar-toggle" aria-label="收起/展开侧边栏">
|
||||
<i class="fas fa-chevron-left toggle-icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-content">
|
||||
<div class="nav-section">
|
||||
{{#each navigationData}}
|
||||
{{> navigation}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
<div class="social-links">
|
||||
{{> social-links}}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- 右侧内容区 -->
|
||||
<main class="content">
|
||||
<!-- 顶部操作栏 -->
|
||||
<div class="main-header">
|
||||
<div class="left-actions">
|
||||
<button class="theme-toggle" aria-label="切换主题">
|
||||
<i class="fas fa-moon"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="search-container">
|
||||
<div class="search-input-container">
|
||||
<i class="fas fa-search"></i>
|
||||
<input type="text" class="search-input" placeholder="搜索..." aria-label="搜索">
|
||||
<button class="search-clear" aria-label="清除搜索">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-actions">
|
||||
<button class="fullscreen-toggle" aria-label="切换全屏模式">
|
||||
<i class="fas fa-expand"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主要内容 -->
|
||||
<div class="main-content">
|
||||
<!-- home页 -->
|
||||
<div class="page active" id="home">
|
||||
{{{pages.home}}}
|
||||
</div>
|
||||
|
||||
<!-- 项目页 -->
|
||||
<div class="page" id="projects">
|
||||
{{{pages.projects}}}
|
||||
</div>
|
||||
|
||||
<!-- 文章页 -->
|
||||
<div class="page" id="articles">
|
||||
{{{pages.articles}}}
|
||||
</div>
|
||||
|
||||
<!-- 朋友页 -->
|
||||
<div class="page" id="friends">
|
||||
{{{pages.friends}}}
|
||||
</div>
|
||||
|
||||
<!-- 书签页 -->
|
||||
<div class="page" id="bookmarks">
|
||||
{{{pages.bookmarks}}}
|
||||
</div>
|
||||
|
||||
<!-- 搜索结果页 -->
|
||||
<div class="page" id="search-results">
|
||||
{{{pages.search-results}}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 页脚 -->
|
||||
<footer class="main-footer">
|
||||
<p>© {{currentYear}} {{site.title}} | {{site.footer}}</p>
|
||||
</footer>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,16 +1,7 @@
|
||||
<div class="page" id="{{pageId}}">
|
||||
{{#ifEquals pageId @root.homePageId}}
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="profile-title">{{title}}</h2>
|
||||
<h3 data-editable="profile-subtitle">{{subtitle}}</h3>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="page-title">{{title}}</h2>
|
||||
<p class="subtitle" data-editable="page-subtitle">{{subtitle}}</p>
|
||||
</div>
|
||||
{{/ifEquals}}
|
||||
{{!-- page.hbs - 通用页面模板:结构与其他页面一致(标题区 + 分类内容) --}}
|
||||
<div class="page-template page-template-{{pageId}}">
|
||||
{{> page-header}}
|
||||
{{#each categories}}
|
||||
{{> category}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
{{#ifEquals pageId @root.homePageId}}
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="profile-title">{{title}}</h2>
|
||||
<h3 data-editable="profile-subtitle">{{subtitle}}</h3>
|
||||
{{!-- projects.hbs - 项目页:风格 A(代码仓库风),标题栏右侧展示 GitHub 热力图(可选) --}}
|
||||
<div class="page-template page-template-projects">
|
||||
{{> page-header}}
|
||||
|
||||
{{#each categories}}
|
||||
{{> category}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="page-title">{{title}}</h2>
|
||||
<p class="subtitle" data-editable="page-subtitle">{{subtitle}}</p>
|
||||
</div>
|
||||
{{/ifEquals}}
|
||||
{{#each categories}}
|
||||
{{> category}}
|
||||
{{/each}}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<!-- 搜索结果页 -->
|
||||
<div class="welcome-section">
|
||||
<h2 data-editable="page-title">搜索结果</h2>
|
||||
<p class="subtitle" data-editable="page-subtitle">在所有页面中找到的匹配项</p>
|
||||
<div class="welcome-section-main">
|
||||
<h2 data-editable="page-title">搜索结果</h2>
|
||||
<p class="subtitle" data-editable="page-subtitle">在所有页面中找到的匹配项</p>
|
||||
</div>
|
||||
</div>
|
||||
{{#each navigation}}
|
||||
<section class="category search-section" data-section="{{id}}" data-type="category" data-name="{{name}}" data-icon="{{icon}}" style="display: none;">
|
||||
<h2 data-editable="category-name"><i class="{{icon}}"></i> {{name}}匹配项</h2>
|
||||
<div class="sites-grid" data-container="sites"></div>
|
||||
</section>
|
||||
{{/each}}
|
||||
{{/each}}
|
||||
|
||||
Reference in New Issue
Block a user