diff --git a/.trae/documents/article-reading-experience-ref-optimization.md b/.trae/documents/article-reading-experience-ref-optimization.md new file mode 100644 index 0000000..5ac8c69 --- /dev/null +++ b/.trae/documents/article-reading-experience-ref-optimization.md @@ -0,0 +1,123 @@ +# 参考页面排版优化文章详情页阅读体验 + +## 参考页面分析(nxxy335.top/archives/c2KWtzf4) + +通过浏览器截图和 JS 提取的样式数据,参考页面的排版特征如下: + +| 属性 | 参考页面 | 我们当前 | 差异分析 | +|------|----------|----------|----------| +| 内容区域宽度 | 704px | 800px | 我们更宽,但参考页面更聚焦阅读 | +| 正文字号 | 16px | 17px (1.0625rem) | 我们略大 | +| 正文行高 | 27.6px (~1.725) | 1.85 | 我们行高更大 | +| h2 字号 | 24px | 未设置(继承) | 参考页面 h2 有明确字号 | +| h2 margin-top | 32px | 3em (~51px) | 我们标题上方留白过大 | +| h2 margin-bottom | 8px | 1.2em (~20px) | 参考页面标题下方更紧凑 | +| 段落间距 | 16px | 1.6em (~27px) | 我们段落间距偏大 | +| 图片圆角 | 0px(无圆角) | 12px | 参考页面图片无圆角 | +| 图片 margin-bottom | 0px | var(--space-xl) 2rem | 参考页面图片紧贴文字 | +| 字体 | 系统字体栈 | var(--font-sans) | 类似 | + +### 参考页面的设计理念 +- **紧凑但不拥挤**:段落间距适中(16px),标题上方留白适中(32px),整体节奏感好 +- **内容宽度适中**:704px 是经典的阅读宽度,适合单栏长文阅读 +- **标题层级清晰**:h2 有明确的 24px 字号,上方 32px 留白,下方仅 8px,让标题和下方正文紧密关联 +- **图片融入正文**:无圆角,无额外间距,图片像段落一样自然融入文字流 +- **行高适中**:1.725 的行高在中文阅读中既不拥挤也不松散 + +--- + +## 优化方案 + +### 1. 缩小内容区域宽度 +- 将 `.wi-content-wrap` 的 `max-width` 从 `800px` 改为 `720px` +- 这是阅读体验最核心的改进——过宽的内容行会导致视线追踪困难 + +### 2. 调整正文字号和行高 +- 字号:保持 `1rem`(16px),与参考页面一致 +- 行高:从 `1.85` 调整为 `1.75`,与参考页面的 1.725 接近 + +### 3. 优化标题间距 +- h2:`margin-top: 2em`(从 3em 降低),`margin-bottom: 0.5em`(从 1.2em 降低) +- h3-h6:`margin-top: 1.8em`(从 2.5em 降低),`margin-bottom: 0.5em`(从 1em 降低) +- 核心理念:标题上方留白适中,下方紧凑,让标题和正文紧密关联 + +### 4. 优化段落间距 +- 从 `1.6em` 调整为 `1.2em`,与参考页面的 16px(1em)接近但略宽松 + +### 5. 优化图片样式 +- 圆角:从 `12px` 改为 `8px`(保留微圆角但不突兀) +- 间距:从 `margin-block: var(--space-xl)` 改为 `margin-block: 1.5em` + +### 6. 为 h2 添加明确字号 +- h2:`font-size: 1.5rem`(24px) +- h3:`font-size: 1.25rem`(20px) + +--- + +## 涉及文件 + +1. **`src/styles/main.scss`**:修改 `.wi-content-wrap` 的 `max-width` 从 800px 到 720px +2. **`src/pages/post.astro`**:修改 `.wi-post__body` 及子元素的排版样式 + +--- + +## 具体修改 + +### main.scss +```css +.wi-content-wrap { + max-width: 720px; /* 从 800px 缩小到 720px */ + margin: 0 auto; + padding-inline: clamp(1rem, 3vw, 2rem); +} +``` + +### post.astro CSS 修改 + +```css +.wi-post__body { + width: 100%; + max-width: 100%; + margin: 0 auto; + font-size: 1rem; /* 从 1.0625rem 改为 1rem (16px) */ + line-height: 1.75; /* 从 1.85 改为 1.75 */ + color: #3d3530; + overflow-wrap: break-word; + word-wrap: break-word; +} + +.wi-post__body :is(h1, h2, h3, h4, h5, h6) { + font-family: var(--font-sans); + margin-top: 1.8em; /* 从 2.5em 降低 */ + margin-bottom: 0.5em; /* 从 1em 降低 */ + scroll-margin-top: 80px; +} + +.wi-post__body h2 { + font-size: 1.5rem; /* 新增:明确 h2 字号 */ + margin-top: 2em; /* 从 3em 降低 */ + margin-bottom: 0.5em; /* 从 1.2em 降低 */ +} + +.wi-post__body h3 { + font-size: 1.25rem; /* 新增:明确 h3 字号 */ +} + +.wi-post__body p { + margin-block-end: 1.2em; /* 从 1.6em 降低 */ +} + +.wi-post__body img { + border-radius: 8px; /* 从 12px 降低 */ + margin-block: 1.5em; /* 从 var(--space-xl) 改为 1.5em */ +} +``` + +--- + +## 实施步骤 + +1. 修改 `src/styles/main.scss`:`.wi-content-wrap` 的 `max-width` 从 800px 改为 720px +2. 修改 `src/pages/post.astro`:调整 `.wi-post__body` 及子元素排版样式 +3. 构建并部署到 Halo 容器 +4. 浏览器验证效果 diff --git a/.trae/documents/content-width-and-hero-optimization.md b/.trae/documents/content-width-and-hero-optimization.md new file mode 100644 index 0000000..79a3498 --- /dev/null +++ b/.trae/documents/content-width-and-hero-optimization.md @@ -0,0 +1,127 @@ +# 内容区域宽度改回 800px & 优化首页 Hero 背景颜色 + +## 任务概述 + +1. 将 `.wi-content-wrap` 的 `max-width` 从 `720px` 改回 `800px` +2. 优化首页 Hero 区域的背景颜色,使其更有层次感和视觉吸引力 + +--- + +## 任务一:内容区域宽度改回 800px + +### 修改文件 +- `src/styles/main.scss` + +### 具体改动 +将 `.wi-content-wrap` 的 `max-width: 720px` 改为 `max-width: 800px` + +```scss +// 修改前 +.wi-content-wrap { + max-width: 720px; + margin: 0 auto; + padding-inline: clamp(1rem, 3vw, 2rem); +} + +// 修改后 +.wi-content-wrap { + max-width: 800px; + margin: 0 auto; + padding-inline: clamp(1rem, 3vw, 2rem); +} +``` + +> 注:`_variables.scss` 中已定义 `$content-max: 800px`,此处改回 800px 与变量定义一致。 + +--- + +## 任务二:优化首页 Hero 背景颜色 + +### 当前问题分析 + +当前 Hero 背景方案: +- **主背景**:`linear-gradient(160deg, var(--bg) 0%, color-mix(in srgb, var(--bg) 92%, var(--accent) 8%) 50%, var(--bg) 100%)` — 渐变非常微弱,几乎看不出色调变化 +- **光球 1**:`rgba(212, 118, 78, 0.35)` — 暖橙色,420px +- **光球 2**:`rgba(240, 180, 160, 0.3)` — 浅粉色,350px +- **光球 3**:`rgba(200, 150, 100, 0.25)` — 棕黄色,300px + +问题: +1. 主背景渐变太弱(仅 8% accent 混合),几乎看不到渐变效果 +2. 三个光球颜色过于接近暖棕色调,缺乏色彩层次 +3. 整体偏"平",缺少深度和氛围感 +4. 暗色模式下没有单独的背景颜色适配 + +### 优化方案 + +#### 1. 增强主背景渐变 +- 将渐变从 8% accent 提升到 15%,使背景有更明显的色调过渡 +- 添加中间色调节点,让渐变更丰富 + +```css +background: linear-gradient( + 160deg, + var(--bg) 0%, + color-mix(in srgb, var(--bg) 85%, var(--accent) 15%) 40%, + color-mix(in srgb, var(--bg) 90%, var(--mist-pink) 10%) 70%, + var(--bg) 100% +); +``` + +#### 2. 优化光球颜色 — 增加色彩层次 +- **光球 1**(右上):保持暖橙色调,但稍微增加饱和度和大小,作为主视觉焦点 +- **光球 2**(左下):改为偏粉/玫瑰色调,与暖橙形成互补色对比 +- **光球 3**(中央):改为偏紫/薰衣草色调,增加神秘感和深度 + +```css +.hero__orb--1 { + /* 暖橙 — 增强饱和度 */ + background: radial-gradient(circle, rgba(212, 118, 78, 0.4) 0%, transparent 70%); +} + +.hero__orb--2 { + /* 玫瑰粉 — 从浅粉改为带玫瑰色调 */ + background: radial-gradient(circle, rgba(220, 140, 160, 0.3) 0%, transparent 70%); +} + +.hero__orb--3 { + /* 薰衣草紫 — 从棕黄改为淡紫,增加深度 */ + background: radial-gradient(circle, rgba(180, 150, 200, 0.2) 0%, transparent 70%); +} +``` + +#### 3. 添加暗色模式适配 +暗色模式下光球需要不同的颜色表现: + +```css +html.dark .hero { + background: linear-gradient( + 160deg, + var(--bg) 0%, + color-mix(in srgb, var(--bg) 85%, var(--accent) 12%) 40%, + var(--bg) 100% + ); +} + +html.dark .hero__orb--1 { + background: radial-gradient(circle, rgba(232, 149, 95, 0.25) 0%, transparent 70%); +} + +html.dark .hero__orb--2 { + background: radial-gradient(circle, rgba(200, 120, 140, 0.18) 0%, transparent 70%); +} + +html.dark .hero__orb--3 { + background: radial-gradient(circle, rgba(160, 130, 180, 0.12) 0%, transparent 70%); +} +``` + +### 修改文件 +- `src/components/HeroSection.astro` + +--- + +## 执行步骤 + +1. 修改 `src/styles/main.scss` — 将 `.wi-content-wrap` 的 `max-width` 从 `720px` 改为 `800px` +2. 修改 `src/components/HeroSection.astro` — 优化 Hero 背景渐变和光球颜色,添加暗色模式适配 +3. 构建主题并部署到 Docker 容器验证效果 diff --git a/.trae/documents/five-theme-improvements.md b/.trae/documents/five-theme-improvements.md new file mode 100644 index 0000000..939f80c --- /dev/null +++ b/.trae/documents/five-theme-improvements.md @@ -0,0 +1,391 @@ +# 主题五大改进实施计划 + +## 任务一:Footer 配置组缺失 + +### 问题 +[Footer.astro](file:///c:/Users/Zhang/Documents/Halo/WarmIsland/src/components/Footer.astro) 引用了 `theme.config?.footer?.footer_copyright`、`footer_icp`、`footer_socials`、`footer_show_powered`、`footer_show_theme`、`footer_custom_html` 等配置项,但 [settings.yaml](file:///c:/Users/Zhang/Documents/Halo/WarmIsland/settings.yaml) 中没有定义 footer 配置组,用户在后台无法设置页脚内容。 + +### 修改文件 +- `settings.yaml` — 新增 footer 配置组 + +### 具体改动 +在 settings.yaml 的 `comment` 配置组之后新增 `footer` 配置组: + +```yaml +- group: footer + label: 页脚 + formSchema: + - $formkit: text + name: footer_copyright + label: 版权信息(留空则使用默认格式 © 年份 站点标题) + - $formkit: text + name: footer_icp + label: ICP 备案号 + - $formkit: repeater + name: footer_socials + label: 社交链接 + children: + - $formkit: text + name: platform + label: 平台名称 + - $formkit: text + name: icon + label: 图标类名(如 fa-brands fa-github) + - $formkit: url + name: url + label: 链接地址 + - $formkit: switch + name: footer_show_powered + label: 显示 "Powered by Halo" + value: true + - $formkit: switch + name: footer_show_theme + label: 显示主题版本 + value: true + - $formkit: code + name: footer_custom_html + label: 自定义 HTML(统计代码等) + language: html +``` + +--- + +## 任务二:SEO Meta 标签严重缺失 + +### 问题 +[Layout.astro](file:///c:/Users/Zhang/Documents/Halo/WarmIsland/src/layouts/Layout.astro) 的 `` 中只有全站 description,缺少 og 标签、canonical URL、RSS 链接等。文章页应使用文章摘要作为 description。 + +### 修改文件 +- `src/layouts/Layout.astro` — 在 `` 中添加 SEO meta 标签 +- `src/pages/post.astro` — 在 head slot 中添加文章页专属 SEO 标签 +- `src/pages/page.astro` — 在 head slot 中添加页面专属 SEO 标签 + +### 具体改动 + +#### Layout.astro — 全局 SEO 标签 +在现有 `` 之后添加: + +```html + + + + + + + + + +``` + +#### post.astro — 文章页专属 SEO 标签 +在 `` 中,`` 之后添加: + +```html +<meta name="description" th:content="${post.spec.excerpt ?: site.seo?.description}" /> +<link rel="canonical" th:href="${post.status.permalink}" /> +<meta property="og:type" content="article" /> +<meta property="og:title" th:content="${post.spec.title}" /> +<meta property="og:description" th:content="${post.spec.excerpt ?: site.seo?.description}" /> +<meta property="og:url" th:href="@{${post.status.permalink}}" /> +<meta property="og:image" th:if="${post.spec.cover}" th:content="${post.spec.cover}" /> +<meta property="article:published_time" th:content="${post.spec.publishTime}" /> +<meta name="twitter:card" content="summary_large_image" th:if="${post.spec.cover}" /> +<meta name="twitter:card" content="summary" th:unless="${post.spec.cover}" /> +<meta name="twitter:title" th:content="${post.spec.title}" /> +<meta name="twitter:description" th:content="${post.spec.excerpt ?: site.seo?.description}" /> +<meta name="twitter:image" th:if="${post.spec.cover}" th:content="${post.spec.cover}" /> +``` + +#### page.astro — 自定义页面专属 SEO 标签 +在 `<Fragment slot="head">` 中,`<title>` 之后添加: + +```html +<meta name="description" th:content="${singlePage.spec.excerpt ?: site.seo?.description}" /> +<link rel="canonical" th:href="${singlePage.status.permalink}" /> +<meta property="og:type" content="website" /> +<meta property="og:title" th:content="${singlePage.spec.title}" /> +<meta property="og:description" th:content="${singlePage.spec.excerpt ?: site.seo?.description}" /> +<meta property="og:url" th:href="@{${singlePage.status.permalink}}" /> +``` + +--- + +## 任务三:导航当前页面无高亮 + +### 问题 +[Navbar.astro](file:///c:/Users/Zhang/Documents/Halo/WarmIsland/src/components/Navbar.astro) 中 CSS 已定义 `.wi-navbar__link--active` 样式,但模板中没有为当前页面的导航链接添加 active 类名。 + +### 修改文件 +- `src/components/Navbar.astro` + +### 具体改动 +在导航链接 `<a>` 标签上添加 `th:classappend` 条件判断,通过比较当前请求路径与菜单项链接来判断是否高亮: + +```html +<a + th:each="menuItem : ${menu.menuItems}" + th:href="@{${menuItem.status.href}}" + th:target="${menuItem.spec.target}" + th:text="${menuItem.status.displayName}" + class="wi-navbar__link" + th:classappend="${#strings.equals(#request.requestURI, menuItem.status.href)} ? 'wi-navbar__link--active'" +> +</a> +``` + +同时需要在 MobileMenu.astro 中也添加同样的高亮逻辑。MobileMenu.astro 第 16-22 行的导航链接结构与 Navbar 相同: + +```html +<a + th:each="menuItem : ${menu.menuItems}" + th:href="@{${menuItem.status.href}}" + th:target="${menuItem.spec.target}" + th:text="${menuItem.status.displayName}" + class="wi-mobile-menu__link" + th:classappend="${#strings.equals(#request.requestURI, menuItem.status.href)} ? 'wi-mobile-menu__link--active'" +></a> +``` + +并在 MobileMenu.astro 的 `<style>` 中添加 active 样式: + +```css +.wi-mobile-menu__link--active { + color: var(--accent); + background: var(--bg-raised); + font-weight: 600; +} +``` + +--- + +## 任务四:移动端文章目录不可用(浮动目录按钮) + +### 问题 +[post.astro](file:///c:/Users/Zhang/Documents/Halo/WarmIsland/src/pages/post.astro) 中 TOC 仅在 `min-width: 1280px` 时显示,移动端没有任何替代方案。 + +### 修改文件 +- `src/pages/post.astro` + +### 具体改动 + +#### 1. 添加移动端浮动 TOC 按钮 +在文章 `<article>` 内添加一个浮动按钮,仅在 `max-width: 1279px` 时显示: + +```html +<button + th:if="${theme.config?.article?.article_show_toc ?: true}" + class="wi-toc-fab" + id="wi-toc-fab" + type="button" + aria-label="打开目录" +> + <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="8" x2="21" y1="6" y2="6"/><line x1="8" x2="21" y1="12" y2="12"/><line x1="8" x2="21" y1="18" y2="18"/><line x1="3" x2="3.01" y1="6" y2="6"/><line x1="3" x2="3.01" y1="12" y2="12"/><line x1="3" x2="3.01" y1="18" y2="18"/></svg> +</button> +``` + +#### 2. 添加移动端 TOC 抽屉面板 +在浮动按钮之后添加一个从底部滑出的抽屉面板: + +```html +<div + th:if="${theme.config?.article?.article_show_toc ?: true}" + class="wi-toc-drawer" + id="wi-toc-drawer" +> + <div class="wi-toc-drawer__overlay"></div> + <div class="wi-toc-drawer__panel"> + <div class="wi-toc-drawer__header"> + <span class="wi-toc-drawer__title">目录</span> + <button class="wi-toc-drawer__close" type="button" aria-label="关闭目录"> + <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg> + </button> + </div> + <nav class="wi-toc-drawer__nav" id="wi-toc-drawer-nav"></nav> + </div> +</div> +``` + +#### 3. 添加 CSS 样式 +```css +.wi-toc-fab { + display: none; + position: fixed; + bottom: 1.5rem; + right: 1.5rem; + width: 44px; + height: 44px; + border-radius: 50%; + border: 1px solid var(--rule); + background: var(--bg-raised); + color: var(--ink-2); + cursor: pointer; + z-index: 20; + align-items: center; + justify-content: center; + box-shadow: var(--shadow-md); + transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease; +} + +.wi-toc-fab:hover { + color: var(--accent); + border-color: var(--accent); +} + +@media (max-width: 1279px) { + .wi-toc-fab { + display: inline-flex; + } +} + +.wi-toc-drawer { + display: none; +} + +.wi-toc-drawer--open { + display: block; +} + +.wi-toc-drawer__overlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.4); + z-index: 50; +} + +.wi-toc-drawer__panel { + position: fixed; + bottom: 0; + left: 0; + right: 0; + max-height: 60vh; + background: var(--bg); + border-top: 1px solid var(--rule); + border-radius: 16px 16px 0 0; + padding: 1.25rem; + z-index: 51; + overflow-y: auto; + transform: translateY(0); + transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1); +} + +.wi-toc-drawer__header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 0.75rem; + padding-bottom: 0.75rem; + border-bottom: 1px solid var(--rule); +} + +.wi-toc-drawer__title { + font-family: var(--font-sans); + font-size: var(--text-sm); + font-weight: 600; + color: var(--ink); +} + +.wi-toc-drawer__close { + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border: none; + background: none; + color: var(--ink-3); + cursor: pointer; +} + +.wi-toc-drawer__close:hover { + color: var(--accent); +} + +.wi-toc-drawer__nav { + display: flex; + flex-direction: column; + gap: 2px; +} + +.wi-toc-drawer__nav .wi-toc__link { + font-size: var(--text-sm); + padding: 6px 0; +} +``` + +#### 4. 添加 JS 逻辑 +在现有 `<script is:inline>` 中,TOC 构建逻辑之后,添加移动端抽屉逻辑: + +```javascript +var tocFab = document.getElementById("wi-toc-fab"); +var tocDrawer = document.getElementById("wi-toc-drawer"); +var tocDrawerNav = document.getElementById("wi-toc-drawer-nav"); + +if (tocFab && tocDrawer && tocDrawerNav && tocNav) { + tocDrawerNav.innerHTML = tocNav.innerHTML; + + tocFab.addEventListener("click", function () { + tocDrawer.classList.add("wi-toc-drawer--open"); + document.body.style.overflow = "hidden"; + }); + + var drawerClose = tocDrawer.querySelector(".wi-toc-drawer__close"); + var drawerOverlay = tocDrawer.querySelector(".wi-toc-drawer__overlay"); + + function closeDrawer() { + tocDrawer.classList.remove("wi-toc-drawer--open"); + document.body.style.overflow = ""; + } + + if (drawerClose) drawerClose.addEventListener("click", closeDrawer); + if (drawerOverlay) drawerOverlay.addEventListener("click", closeDrawer); + + tocDrawerNav.querySelectorAll(".wi-toc__link").forEach(function (link) { + link.addEventListener("click", function () { + closeDrawer(); + }); + }); +} +``` + +--- + +## 任务五:404/500 页面深色模式不生效 + +### 问题 +[404.html](file:///c:/Users/Zhang/Documents/Halo/WarmIsland/public/error/404.html) 和 [500.html](file:///c:/Users/Zhang/Documents/Halo/WarmIsland/public/error/500.html) 是纯静态页面,没有读取 localStorage 中的主题偏好,首次直接访问错误页面时深色模式不会生效。 + +### 修改文件 +- `public/error/404.html` +- `public/error/500.html` + +### 具体改动 +在两个文件的 `<head>` 中,`<style>` 标签之前,添加与 Layout.astro 相同的主题检测脚本(简化版,仅检测 localStorage 和系统偏好): + +```html +<script> + (function () { + var stored = localStorage.getItem("wi-theme"); + var prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; + var isDark = stored === "dark" || (!stored && prefersDark); + if (isDark) { + document.documentElement.classList.add("dark"); + } + })(); +</script> +``` + +这段脚本会在页面渲染前检测用户的主题偏好并添加 `dark` 类名,确保 CSS 变量正确切换。 + +--- + +## 执行顺序 + +1. **settings.yaml** — 新增 footer 配置组 +2. **Layout.astro** — 添加全局 SEO meta 标签 +3. **post.astro** — 添加文章页 SEO 标签 + 移动端 TOC 浮动按钮和抽屉 +4. **page.astro** — 添加页面 SEO 标签 +5. **Navbar.astro** — 添加导航当前页面高亮 +6. **MobileMenu.astro** — 添加导航当前页面高亮(需先确认结构) +7. **404.html** — 添加深色模式检测脚本 +8. **500.html** — 添加深色模式检测脚本 +9. 构建并部署到 Docker 验证 diff --git a/.trae/documents/fix-500-and-optimizations.md b/.trae/documents/fix-500-and-optimizations.md new file mode 100644 index 0000000..c1a4a5a --- /dev/null +++ b/.trae/documents/fix-500-and-optimizations.md @@ -0,0 +1,308 @@ +# 主题全面修复与优化计划 + +## 🔴 紧急:修复 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}|"> + +``` + +#### 5. page.astro(第 8-13 行) +移除手动添加的页面 SEO 标签,仅保留 ``: + +```html +<!-- 修改后 --> +<Fragment slot="head"> + <title th:text="|${singlePage.spec.title} - ${site.title}|"> + +``` + +--- + +## 🟡 响应式断点统一 + +### 当前问题 +各组件使用的断点不一致: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 + +WarmIsland v1.0.0 + + +WarmIsland v1.0.0 +``` + +实际上,Halo 的 Thymeleaf 环境中没有直接暴露 theme version 的变量。最简洁的方案是在 settings.yaml 的 footer 配置组中添加一个版本号字段,或者直接使用一个固定的版本号但添加注释标记。考虑到维护成本,最佳方案是: + +在 Footer.astro 的 frontmatter 中定义版本号常量,模板中引用: + +```astro +--- +const THEME_VERSION = "1.0.0"; +const today = new Date(); +--- +... +WarmIsland v{THEME_VERSION} +``` + +这样只需在一处修改版本号。 + +--- + +## 🟢 顶部阅读进度条 + +### 修改文件 +- `src/pages/post.astro` + +### 实现方案 +在文章详情页顶部添加一个固定定位的进度条,随滚动进度填充: + +#### HTML +在 `
` 之前添加: +```html +
+``` + +#### 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 +在现有 ` + 页面走丢了 - 暖屿 + + + +
+

404

+

页面走丢了

+

你寻找的页面似乎不在这个小岛上

+ +
+ + diff --git a/public/error/500.html b/public/error/500.html new file mode 100644 index 0000000..7129fa0 --- /dev/null +++ b/public/error/500.html @@ -0,0 +1,130 @@ + + + + + + + 服务器开小差了 - 暖屿 + + + +
+

500

+

服务器开小差了

+

小岛遇到了一些问题,稍后再来看看吧

+ +
+ + diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..cdd8492 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/fragments/post-list.html b/public/fragments/post-list.html index 5947964..3e42353 100644 --- a/public/fragments/post-list.html +++ b/public/fragments/post-list.html @@ -1,19 +1,21 @@ -