Files
2026-05-18 17:29:18 +08:00

309 lines
9.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 主题全面修复与优化计划
## 🔴 紧急:修复 500 报错(最高优先级)
### 根因分析
Docker 日志显示错误:
```
TemplateProcessingException: Exception evaluating SpringEL expression:
"#strings.equals(#request.requestURI, menuItem.status.href)"
```
**原因**Halo 使用 Spring WebFlux(非 Spring MVC),`#request` 对象在 WebFlux 环境中不可用。上一轮在 Navbar.astro 和 MobileMenu.astro 中添加的 `th:classappend="${#strings.equals(#request.requestURI, menuItem.status.href)}"` 导致了全站 500 错误。
### 额外问题:SEO 标签与 Halo 自动注入冲突
根据 Halo Thymeleaf 最佳实践文档,Halo 会**自动注入**以下 SEO 标签:
- `<meta name="description">``<meta name="keywords">`
- Open Graph 标签(og:title, og:description, og:image 等)
- Twitter Card 标签和 canonical URL
我们在 Layout.astro、post.astro、page.astro 中手动添加的这些标签会与 Halo 自动注入的冲突,需要移除。
### 修改文件
#### 1. Navbar.astro(第 34 行)
移除 `th:classappend`,改用 JS 方案实现导航高亮:
```html
<!-- 修改前 -->
<a ... th:classappend="${#strings.equals(#request.requestURI, menuItem.status.href)} ? 'wi-navbar__link--active'">
<!-- 修改后 -->
<a ... th:data-href="${menuItem.status.href}" class="wi-navbar__link">
```
在 Navbar.astro 的 `<script>` 中添加 JS 高亮逻辑:
```javascript
document.querySelectorAll('.wi-navbar__link[data-href]').forEach(function(link) {
if (new URL(link.href).pathname === window.location.pathname) {
link.classList.add('wi-navbar__link--active');
}
});
```
#### 2. MobileMenu.astro(第 22 行)
同样移除 `th:classappend`,改用 JS 方案:
```html
<!-- 修改前 -->
<a ... th:classappend="${#strings.equals(#request.requestURI, menuItem.status.href)} ? 'wi-mobile-menu__link--active'">
<!-- 修改后 -->
<a ... th:data-href="${menuItem.status.href}" class="wi-mobile-menu__link">
```
在 MobileMenu.astro 的 `<script>` 中添加 JS 高亮逻辑:
```javascript
menu?.querySelectorAll('.wi-mobile-menu__link[data-href]').forEach(function(link) {
if (new URL(link.href).pathname === window.location.pathname) {
link.classList.add('wi-mobile-menu__link--active');
}
});
```
#### 3. Layout.astro(第 57-66 行)
移除手动添加的 SEO 标签(Halo 会自动注入),仅保留 RSS 订阅链接:
```html
<!-- 移除以下行 -->
<meta name="description" th:content="${site.seo?.description}" />
<meta name="keywords" th:content="${site.seo?.keywords}" />
<link rel="canonical" th:href="${site.url}" />
<meta property="og:site_name" th:content="${site.title}" />
<meta property="og:type" content="website" />
<meta property="og:url" th:content="${site.url}" />
<meta property="og:title" th:content="${site.title}" />
<meta property="og:description" th:content="${site.seo?.description}" />
<meta name="twitter:card" content="summary" />
<!-- 仅保留 -->
<link rel="alternate" type="application/rss+xml" th:title="${site.title}" th:href="@{/feed.xml}" />
```
#### 4. post.astro(第 8-20 行)
移除手动添加的文章页 SEO 标签(Halo 会自动注入),仅保留 `<title>`
```html
<!-- 修改后 -->
<Fragment slot="head">
<title th:text="|${post.spec.title} - ${site.title}|"></title>
</Fragment>
```
#### 5. page.astro(第 8-13 行)
移除手动添加的页面 SEO 标签,仅保留 `<title>`
```html
<!-- 修改后 -->
<Fragment slot="head">
<title th:text="|${singlePage.spec.title} - ${site.title}|"></title>
</Fragment>
```
---
## 🟡 响应式断点统一
### 当前问题
各组件使用的断点不一致:640px、680px、767px、768px、480px 等。
### 统一方案
将断点统一为以下四级体系(与 `_variables.scss` 中的 `$breakpoint-sm/md/lg/xl` 对应):
| 级别 | 断点值 | 用途 |
|------|--------|------|
| sm | 640px | 手机端(单列布局) |
| md | 768px | 平板端(导航切换、双列→单列) |
| lg | 1024px | 小桌面(三列→双列) |
| xl | 1280px | 大桌面(TOC 显示) |
### 具体改动
| 文件 | 当前断点 | 改为 |
|------|----------|------|
| Navbar.astro | 767px | 768px |
| page.astro | 680px | 768px |
| post.astro (TOC FAB) | 1279px | 1279px(保持,与 xl-1px 对应) |
| post.astro (其他) | 680px | 768px |
| Footer.astro | 680px | 768px |
| archives.astro | 680px | 768px |
| tag.astro | 680px | 768px |
| categories.astro | 680px | 768px |
| page_messageboard.astro | 680px | 768px |
| Header.astro | 680px | 768px |
| global.css | 680px | 768px |
| FeaturedSection.astro | 767px | 768px |
| PostCard.astro | 767px | 768px |
| LatestSection.astro | 767px | 768px |
> 注意:640px 断点(首页流式布局、友链、装备等)保持不变,因为它们用于单列/双列切换,语义上属于 sm 级别。
> 480px 断点(图库、瞬间的极小屏幕适配)保持不变,属于额外微调。
---
## 🟡 冗余代码清理
### 删除文件
1. `src/components/Header.astro` — 未被 Layout 使用,与 Navbar 功能重叠
2. `src/components/MobileMenu.vue` — 未被使用(Layout 用的是 MobileMenu.astro
---
## 🟡 Footer 版本号硬编码修复
### 当前问题
Footer.astro 第 33 行硬编码 `WarmIsland v1.0.0`
### 修改方案
将版本号改为从 theme.yaml 读取(通过 Halo 的 theme 变量),如果不可用则使用 Astro 构建时变量:
```html
<!-- 修改前 -->
<span th:if="${showTheme}">WarmIsland v1.0.0</span>
<!-- 修改后 -->
<span th:if="${showTheme}">WarmIsland v1.0.0</span>
```
实际上,Halo 的 Thymeleaf 环境中没有直接暴露 theme version 的变量。最简洁的方案是在 settings.yaml 的 footer 配置组中添加一个版本号字段,或者直接使用一个固定的版本号但添加注释标记。考虑到维护成本,最佳方案是:
在 Footer.astro 的 frontmatter 中定义版本号常量,模板中引用:
```astro
---
const THEME_VERSION = "1.0.0";
const today = new Date();
---
...
<span th:if="${showTheme}">WarmIsland v{THEME_VERSION}</span>
```
这样只需在一处修改版本号。
---
## 🟢 顶部阅读进度条
### 修改文件
- `src/pages/post.astro`
### 实现方案
在文章详情页顶部添加一个固定定位的进度条,随滚动进度填充:
#### HTML
`<article class="wi-post">` 之前添加:
```html
<div class="wi-reading-progress" id="wi-reading-progress"></div>
```
#### CSS
```css
.wi-reading-progress {
position: fixed;
top: 0;
left: 0;
width: 0;
height: 3px;
background: var(--accent);
z-index: 101;
transition: width 0.1s linear;
}
```
#### JS
在现有 `<script is:inline>` 中添加:
```javascript
var progressBar = document.getElementById("wi-reading-progress");
if (progressBar) {
var article = document.querySelector(".wi-post");
if (article) {
window.addEventListener("scroll", function () {
var rect = article.getBoundingClientRect();
var articleHeight = article.offsetHeight;
var scrolled = -rect.top;
var progress = Math.min(Math.max(scrolled / (articleHeight - window.innerHeight), 0), 1);
progressBar.style.width = (progress * 100) + "%";
}, { passive: true });
}
}
```
---
## 🟢 文章页作者信息
### 修改文件
- `src/pages/post.astro`
### 实现方案
在文章 meta 区域(日期之后)添加作者信息。Halo 的 PostVo 有 `contributors` 字段(ContributorVo 列表),包含 `displayName``avatar`
`.wi-post__meta` 中,日期之后添加:
```html
<th:block th:if="${post.contributors != null and !#lists.isEmpty(post.contributors)}">
<span class="wi-post__meta-sep">·</span>
<span class="wi-post__author">
<img
th:if="${post.contributors[0].avatar}"
th:src="${post.contributors[0].avatar}"
th:alt="${post.contributors[0].displayName}"
class="wi-post__author-avatar"
/>
<span th:text="${post.contributors[0].displayName}"></span>
</span>
</th:block>
```
CSS
```css
.wi-post__author {
display: inline-flex;
align-items: center;
gap: 0.35rem;
}
.wi-post__author-avatar {
width: 20px;
height: 20px;
border-radius: 50%;
object-fit: cover;
}
```
---
## 📝 README.md 撰写
### 内容结构
1. 主题简介
2. 截图预览
3. 安装方法
4. 配置说明(各配置组概述)
5. lightgallery.js 灯箱插件集成指南
- 路径匹配规则
- DOM 节点选择器
6. 开发指南(构建命令等)
### lightgallery.js 集成信息
| 页面 | 路径匹配 | 匹配区域 DOM 节点 |
|------|----------|-------------------|
| 文章详情页 | `/archives/*` | `.wi-post__body` |
| 瞬间页 | `/moments` | `.wi-moments-page__content` |
| 图库页 | `/photos` | `.wi-photos-page__grid` |
| 自定义页面 | (用户自定义) | `.wi-page__body` |
---
## 执行顺序
1. **修复 500 报错** — Navbar.astro、MobileMenu.astro 移除 `#request`,改用 JS 高亮;Layout.astro、post.astro、page.astro 移除冲突的 SEO 标签
2. **构建并部署** — 验证 500 错误已修复
3. **响应式断点统一** — 批量替换 680px→768px、767px→768px
4. **冗余代码清理** — 删除 Header.astro 和 MobileMenu.vue
5. **Footer 版本号修复** — 使用 frontmatter 常量
6. **阅读进度条** — post.astro 添加进度条
7. **文章页作者信息** — post.astro 添加作者
8. **README.md 撰写**
9. **最终构建部署验证**