feat: 完善主题功能并适配插件 (v1.1.5)

功能新增
- 新增页面布局契约 templates/layout.html,插件前台页面可复用主题外观,避免回退到 Halo fallback 布局
- 新增微信读书页面模板 (weread.html),集成 halo-weread-plugin 书架
- 新增订阅页面模板 (page_subscriptions.html)
- 新增欢迎弹窗组件(IP 地理定位,多 API 容错)
- 新增点击特效组件(9 种效果)
- 页脚新增全站统计,支持开关与统计项配置,默认开启

插件适配
- 适配 extra-api:文章字数改服务端统计、正文可选中英混排与服务端代码高亮
- 修正各页面插件应用市场链接与插件名

修复
- 修复文章正文图片/视频无法居中(正文样式移至全局,scoped 样式对 Thymeleaf 注入内容无效)
- 修复正文 H1-H6 字号过大,重排层级与移动端断点
- 修复 th: 属性中文字符串缺少引号导致的 Thymeleaf 解析异常(/links、/moments 500)
- 修复 JS 内联表达式与 Thymeleaf 内联语法冲突,全部内联脚本加 th:inline="none"
- 修复移除 i18n 后 steam 页 Elvis 表达式回归问题
- 修正订阅页 th:attr 引号嵌套错误

优化
- Hero 移除灰色遮罩,下滑箭头改为可点击平滑滚动
- 优化目录样式:移除圆点与下拉箭头,支持两行显示,修复长目录截断
- 移除 i18n 多语言支持

清理
- 移除未使用的 Vue/图标依赖与废弃脚本、重复资源
This commit is contained in:
2026-09-26 11:18:52 +08:00
parent 9d0bfcfb4f
commit 430d107d44
78 changed files with 2959 additions and 36075 deletions
+25 -9
View File
@@ -4,18 +4,22 @@ import ThemeSwitcher from "./ThemeSwitcher.astro";
<header class="wi-navbar-wrapper" id="wi-navbar" th:classappend="${theme.config?.navbar?.navbar_style == 'minimal'} ? 'wi-navbar--minimal' : (${theme.config?.navbar?.navbar_style == 'float'} ? 'wi-navbar--float' : 'wi-navbar--glass')">
<div class="wi-navbar__capsule">
<a class="wi-navbar__brand" th:href="@{/}">
<a
class="wi-navbar__brand"
th:href="@{/}"
th:with="brandType=${theme.config?.navbar?.navbar_brand_type}, logoUrl=${!#strings.isEmpty(theme.config?.navbar?.navbar_logo) ? theme.config?.navbar?.navbar_logo : theme.config?.basic?.logo}, logoRadius=${theme.config?.navbar?.navbar_logo_radius}"
>
<img
th:if="${theme.config?.basic?.logo}"
th:src="${theme.config?.basic?.logo}"
th:if="${brandType == 'logo' and !#strings.isEmpty(logoUrl)}"
th:src="${logoUrl}"
alt=""
class="wi-navbar__logo"
th:class="${'wi-navbar__logo wi-navbar__logo--' + (logoRadius != null ? logoRadius : 'rounded')}"
loading="eager"
decoding="async"
onerror="this.style.display='none';this.nextElementSibling&&this.nextElementSibling.classList.add('wi-navbar__title')"
onerror="this.style.display='none'"
/>
<span
th:if="${#strings.isEmpty(theme.config?.basic?.logo)}"
th:if="${brandType != 'logo' or #strings.isEmpty(logoUrl)}"
class="wi-navbar__title"
th:text="${site.title}"
></span>
@@ -47,14 +51,14 @@ import ThemeSwitcher from "./ThemeSwitcher.astro";
th:if="${pluginFinder.available('PluginSearchWidget') and theme.config?.navbar?.navbar_show_search != false}"
class="wi-navbar__action-btn wi-navbar__search-btn"
type="button"
th:aria-label="${theme.config?.basic?.label_search ?: #messages.msg('common.search')}"
th:aria-label="${theme.config?.basic?.label_search ?: '搜索'}"
onclick="SearchWidget.open()"
>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
</button>
<th:block th:if="${theme.config?.navbar?.navbar_show_theme_switch != false}">
<span th:attr="data-label=${theme.config?.basic?.label_theme_switch ?: #messages.msg('common.themeSwitch')}" style="display:inline-flex">
<span th:attr="data-label=${theme.config?.basic?.label_theme_switch ?: '切换主题'}" style="display:inline-flex">
<ThemeSwitcher />
</span>
</th:block>
@@ -70,7 +74,7 @@ import ThemeSwitcher from "./ThemeSwitcher.astro";
</div>
</header>
<script is:inline>
<script is:inline th:inline="none">
const navbar = document.getElementById("wi-navbar");
let lastScrollY = window.scrollY;
let ticking = false;
@@ -218,6 +222,18 @@ import ThemeSwitcher from "./ThemeSwitcher.astro";
object-fit: contain;
}
.wi-navbar__logo--square {
border-radius: 0;
}
.wi-navbar__logo--rounded {
border-radius: 8px;
}
.wi-navbar__logo--circle {
border-radius: 50%;
}
.wi-navbar__title {
font-family: var(--font-sans);
font-weight: 700;