feat: 插件适配页面与系统完善(v0.1.0)

- 修复 /categories、/tags 因变量为 List 误用 .items 导致的 500
- 新增 layout.html 布局契约,消除插件页面 fallback 警告
- 适配 plugin-moments / plugin-photos / plugin-links(含友链申请表单与 RSS 订阅页)
- 适配 halo-weread-plugin(书架页)、留言板单页模板
- 适配 plugin-extra-api 的代码高亮与暗色样式
- 修复暗黑模式评论区不可见(补充 color-scheme 与兜底样式)
- 更新元数据:作者暖心向阳335、版本 0.1.0、requires >=2.26.0
This commit is contained in:
2026-09-28 16:50:09 +08:00
parent 2ed0c768a4
commit 8e6dccbd09
35 changed files with 3986 additions and 301 deletions
+22
View File
@@ -0,0 +1,22 @@
<th:block th:fragment="category-tree(cats)">
<ul class="category-tree">
<li class="category-tree-item" th:each="cat : ${cats}">
<a th:href="@{${cat.status.permalink}}" class="category-tree-link">
<span class="category-tree-name" th:text="${cat.spec.displayName}">Category</span>
<span
class="category-tree-count"
th:text="${cat.postCount}"
th:if="${cat.postCount != null and cat.postCount > 0}"
>0</span
>
</a>
<th:block
th:if="${cat.children != null and !#lists.isEmpty(cat.children)}"
>
<th:block
th:replace="~{modules/category-tree :: category-tree(cats=${cat.children})}"
></th:block>
</th:block>
</li>
</ul>
</th:block>
+37
View File
@@ -0,0 +1,37 @@
<!--
分页导航。
context 为当前列表的路由前缀(如 '/'、'/archives/'、分类或标签 permalink + '/'),
页码链接由 context + 'page/' + n 构造,不硬编码可配置路由。
-->
<nav
class="pagination"
th:fragment="pagination(context, prevUrl, nextUrl, totalPages, page, hasPrevious, hasNext)"
th:if="${hasPrevious || hasNext}"
>
<a
th:if="${hasPrevious}"
th:href="@{${prevUrl}}"
class="pagination-item pagination-prev"
>
<span>←</span>
<span th:text="#{pagination.previous}">Previous</span>
</a>
<span class="pagination-pages">
<a
th:each="i : ${#numbers.sequence(1, totalPages)}"
th:href="@{${i == 1 ? context : (context + 'page/' + i)}}"
th:text="${i}"
class="pagination-item"
th:classappend="${i == page} ? 'active'"
>1</a
>
</span>
<a
th:if="${hasNext}"
th:href="@{${nextUrl}}"
class="pagination-item pagination-next"
>
<span th:text="#{pagination.next}">Next</span>
<span>→</span>
</a>
</nav>
+25
View File
@@ -0,0 +1,25 @@
<!-- 文章列表卡片 -->
<article
class="post"
th:fragment="post-card(post)"
th:classappend="${not #strings.isEmpty(post.spec.cover)} ? 'post-with-thumb'"
>
<div class="post-thumb" th:if="${not #strings.isEmpty(post.spec.cover)}">
<a th:href="@{${post.status.permalink}}">
<img th:src="${post.spec.cover}" th:alt="${post.spec.title}" loading="lazy" />
</a>
</div>
<div class="post-content">
<h2 class="post-title">
<a th:href="@{${post.status.permalink}}" th:text="${post.spec.title}"
>Post title</a
>
</h2>
<p
class="post-excerpt"
th:if="${not #strings.isEmpty(post.status.excerpt)}"
th:text="${post.status.excerpt}"
></p>
<th:block th:replace="~{modules/post-meta :: post-meta(post=${post}, dateClass='post-date')}"></th:block>
</div>
</article>
+26
View File
@@ -0,0 +1,26 @@
<!-- 文章元信息(时间 / 分类 / 浏览量),供列表卡片与详情页复用 -->
<div class="post-meta" th:fragment="post-meta(post, dateClass)">
<time
th:if="${post.spec.publishTime != null}"
th:class="${dateClass}"
th:datetime="${post.spec.publishTime}"
th:text="${#temporals.format(post.spec.publishTime, 'yyyy-MM-dd')}"
data-relative-time
></time>
<th:block th:if="${not #lists.isEmpty(post.categories)}">
<span class="post-meta-sep">·</span>
<span class="post-category">
<a
th:each="cat : ${post.categories}"
th:href="@{${cat.status.permalink}}"
th:text="${cat.spec.displayName}"
></a>
</span>
</th:block>
<th:block th:if="${post.stats != null and post.stats.visit != null and post.stats.visit > 0}">
<span class="post-meta-sep">·</span>
<span class="post-views" th:text="#{post.views(${post.stats.visit})}"
>1 views</span
>
</th:block>
</div>