feat: 初始化 Halo 暗色模式插件
- Halo Plugin 后端(Java/Gradle),含 DarkModePlugin 主类和测试 - Vue 3 + TypeScript 前端 UI,包含主题切换组件和设置页面 - 暗色模式 CSS 变量和覆盖样式(布局/编辑器/表单/滚动条等) - 设计文档和调查文档 - Halo 插件/主题开发 Agent Skills Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
<!doctype html>
|
||||
<html
|
||||
xmlns:th="https://www.thymeleaf.org"
|
||||
th:replace="~{layout :: html(head = null, content = ~{::content})}"
|
||||
>
|
||||
<th:block th:fragment="content">
|
||||
<h1>Archives</h1>
|
||||
<th:block th:each="archive : ${archives.items}">
|
||||
<h2 th:text="${archive.year}"></h2>
|
||||
<th:block th:each="month : ${archive.months}">
|
||||
<h3 th:text="|${archive.year}-${month.month}|"></h3>
|
||||
<ul>
|
||||
<li th:each="post : ${month.posts}">
|
||||
<a th:href="@{${post.status.permalink}}" th:text="${post.spec.title}"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</th:block>
|
||||
</th:block>
|
||||
<nav th:if="${archives.hasPrevious() || archives.hasNext()}">
|
||||
<a th:if="${archives.hasPrevious()}" th:href="@{${archives.prevUrl}}">Previous</a>
|
||||
<span th:text="|${archives.page} / ${archives.totalPages}|"></span>
|
||||
<a th:if="${archives.hasNext()}" th:href="@{${archives.nextUrl}}">Next</a>
|
||||
</nav>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
body {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 1rem;
|
||||
font-family: system-ui, sans-serif;
|
||||
}
|
||||
a {
|
||||
color: #0070f3;
|
||||
}
|
||||
header {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
header a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
nav {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
}
|
||||
footer {
|
||||
margin-top: 2rem;
|
||||
padding-top: 1rem;
|
||||
border-top: 1px solid #eee;
|
||||
color: #666;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
article img {
|
||||
max-width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<!doctype html>
|
||||
<html
|
||||
xmlns:th="https://www.thymeleaf.org"
|
||||
th:replace="~{layout :: html(head = ~{::head}, content = ~{::content})}"
|
||||
>
|
||||
<th:block th:fragment="head">
|
||||
<title th:text="|${author.spec.displayName} - ${site.title}|"></title>
|
||||
</th:block>
|
||||
<th:block th:fragment="content">
|
||||
<h1 th:text="${author.spec.displayName}"></h1>
|
||||
<p th:if="${not #strings.isEmpty(author.spec.bio)}" th:text="${author.spec.bio}"></p>
|
||||
|
||||
<ul>
|
||||
<li th:each="post : ${posts.items}">
|
||||
<a th:href="@{${post.status.permalink}}" th:text="${post.spec.title}"></a>
|
||||
<time th:text="${#temporals.format(post.spec.publishTime, 'yyyy-MM-dd')}"></time>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<nav th:if="${posts.hasPrevious() || posts.hasNext()}">
|
||||
<a th:if="${posts.hasPrevious()}" th:href="@{${posts.prevUrl}}">Previous</a>
|
||||
<span th:text="|${posts.page} / ${posts.totalPages}|"></span>
|
||||
<a th:if="${posts.hasNext()}" th:href="@{${posts.nextUrl}}">Next</a>
|
||||
</nav>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html
|
||||
xmlns:th="https://www.thymeleaf.org"
|
||||
th:replace="~{layout :: html(head = null, content = ~{::content})}"
|
||||
>
|
||||
<th:block th:fragment="content">
|
||||
<h1>Categories</h1>
|
||||
<ul>
|
||||
<li th:each="cat : ${categories.items}">
|
||||
<a
|
||||
th:href="@{${cat.status.permalink}}"
|
||||
th:text="|${cat.spec.displayName} (${cat.postCount})|"
|
||||
></a>
|
||||
</li>
|
||||
</ul>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -0,0 +1,20 @@
|
||||
<!doctype html>
|
||||
<html
|
||||
xmlns:th="https://www.thymeleaf.org"
|
||||
th:replace="~{layout :: html(head = null, content = ~{::content})}"
|
||||
>
|
||||
<th:block th:fragment="content">
|
||||
<h1 th:text="|Category: ${category.spec.displayName}|"></h1>
|
||||
<ul>
|
||||
<li th:each="post : ${posts.items}">
|
||||
<a th:href="@{${post.status.permalink}}" th:text="${post.spec.title}"></a>
|
||||
<time th:text="${#temporals.format(post.spec.publishTime, 'yyyy-MM-dd')}"></time>
|
||||
</li>
|
||||
</ul>
|
||||
<nav th:if="${posts.hasPrevious() || posts.hasNext()}">
|
||||
<a th:if="${posts.hasPrevious()}" th:href="@{${posts.prevUrl}}">Previous</a>
|
||||
<span th:text="|${posts.page} / ${posts.totalPages}|"></span>
|
||||
<a th:if="${posts.hasNext()}" th:href="@{${posts.nextUrl}}">Next</a>
|
||||
</nav>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -0,0 +1,19 @@
|
||||
<!doctype html>
|
||||
<html
|
||||
xmlns:th="https://www.thymeleaf.org"
|
||||
th:replace="~{layout :: html(head = null, content = ~{::content})}"
|
||||
>
|
||||
<th:block th:fragment="content">
|
||||
<ul>
|
||||
<li th:each="post : ${posts.items}">
|
||||
<a th:href="@{${post.status.permalink}}" th:text="${post.spec.title}"></a>
|
||||
<time th:text="${#temporals.format(post.spec.publishTime, 'yyyy-MM-dd')}"></time>
|
||||
</li>
|
||||
</ul>
|
||||
<nav th:if="${posts.hasPrevious() || posts.hasNext()}">
|
||||
<a th:if="${posts.hasPrevious()}" th:href="@{${posts.prevUrl}}">Previous</a>
|
||||
<span th:text="|${posts.page} / ${posts.totalPages}|"></span>
|
||||
<a th:if="${posts.hasNext()}" th:href="@{${posts.nextUrl}}">Next</a>
|
||||
</nav>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
<!doctype html>
|
||||
<html lang="en" xmlns:th="https://www.thymeleaf.org" th:fragment="html (head, content)">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title th:text="${site.title}">Site Title</title>
|
||||
<link rel="stylesheet" th:href="@{/assets/css/style.css?v={v}(v=${theme.spec.version})}" />
|
||||
<th:block th:if="${head != null}">
|
||||
<th:block th:replace="${head}" />
|
||||
</th:block>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<a th:href="@{/}" th:text="${site.title}"></a>
|
||||
<nav th:with="menu = ${menuFinder.getPrimary()}">
|
||||
<a
|
||||
th:each="item : ${menu.menuItems}"
|
||||
th:href="@{${item.status.href}}"
|
||||
th:text="${item.status.displayName}"
|
||||
th:target="${item.spec.target?.value}"
|
||||
></a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<th:block th:replace="${content}" />
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p th:text="${theme.config.basic.custom_footer ?: site.title}"></p>
|
||||
<halo:footer />
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,23 @@
|
||||
<!doctype html>
|
||||
<html
|
||||
xmlns:th="https://www.thymeleaf.org"
|
||||
th:replace="~{layout :: html(head = ~{::head}, content = ~{::content})}"
|
||||
>
|
||||
<th:block th:fragment="head">
|
||||
<title th:text="|${singlePage.spec.title} - ${site.title}|"></title>
|
||||
</th:block>
|
||||
<th:block th:fragment="content">
|
||||
<article>
|
||||
<h1 th:text="${singlePage.spec.title}"></h1>
|
||||
<div th:utext="${singlePage.content.content}"></div>
|
||||
</article>
|
||||
|
||||
<div th:if="${haloCommentEnabled}">
|
||||
<halo:comment
|
||||
group="content.halo.run"
|
||||
kind="SinglePage"
|
||||
th:attr="name=${singlePage.metadata.name}"
|
||||
/>
|
||||
</div>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -0,0 +1,42 @@
|
||||
<!doctype html>
|
||||
<html
|
||||
xmlns:th="https://www.thymeleaf.org"
|
||||
th:replace="~{layout :: html(head = ~{::head}, content = ~{::content})}"
|
||||
>
|
||||
<th:block th:fragment="head">
|
||||
<title th:text="|${post.spec.title} - ${site.title}|"></title>
|
||||
</th:block>
|
||||
<th:block th:fragment="content">
|
||||
<article>
|
||||
<h1 th:text="${post.spec.title}"></h1>
|
||||
<time th:text="${#temporals.format(post.spec.publishTime, 'yyyy-MM-dd')}"></time>
|
||||
<div th:utext="${post.content.content}"></div>
|
||||
<div th:if="${not #lists.isEmpty(post.tags)}">
|
||||
<a
|
||||
th:each="tag : ${post.tags}"
|
||||
th:href="@{${tag.status.permalink}}"
|
||||
th:text="${tag.spec.displayName}"
|
||||
></a>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<nav th:with="cursor = ${postFinder.cursor(post.metadata.name)}">
|
||||
<a
|
||||
th:if="${cursor.hasPrevious()}"
|
||||
th:href="@{${cursor.previous.status.permalink}}"
|
||||
th:text="${cursor.previous.spec.title}"
|
||||
>Previous</a
|
||||
>
|
||||
<a
|
||||
th:if="${cursor.hasNext()}"
|
||||
th:href="@{${cursor.next.status.permalink}}"
|
||||
th:text="${cursor.next.spec.title}"
|
||||
>Next</a
|
||||
>
|
||||
</nav>
|
||||
|
||||
<div th:if="${haloCommentEnabled}">
|
||||
<halo:comment group="content.halo.run" kind="Post" th:attr="name=${post.metadata.name}" />
|
||||
</div>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -0,0 +1,20 @@
|
||||
<!doctype html>
|
||||
<html
|
||||
xmlns:th="https://www.thymeleaf.org"
|
||||
th:replace="~{layout :: html(head = null, content = ~{::content})}"
|
||||
>
|
||||
<th:block th:fragment="content">
|
||||
<h1 th:text="|Tag: ${tag.spec.displayName}|"></h1>
|
||||
<ul>
|
||||
<li th:each="post : ${posts.items}">
|
||||
<a th:href="@{${post.status.permalink}}" th:text="${post.spec.title}"></a>
|
||||
<time th:text="${#temporals.format(post.spec.publishTime, 'yyyy-MM-dd')}"></time>
|
||||
</li>
|
||||
</ul>
|
||||
<nav th:if="${posts.hasPrevious() || posts.hasNext()}">
|
||||
<a th:if="${posts.hasPrevious()}" th:href="@{${posts.prevUrl}}">Previous</a>
|
||||
<span th:text="|${posts.page} / ${posts.totalPages}|"></span>
|
||||
<a th:if="${posts.hasNext()}" th:href="@{${posts.nextUrl}}">Next</a>
|
||||
</nav>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html
|
||||
xmlns:th="https://www.thymeleaf.org"
|
||||
th:replace="~{layout :: html(head = null, content = ~{::content})}"
|
||||
>
|
||||
<th:block th:fragment="content">
|
||||
<h1>Tags</h1>
|
||||
<ul>
|
||||
<li th:each="tag : ${tags.items}">
|
||||
<a th:href="@{${tag.status.permalink}}" th:text="${tag.spec.displayName}"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</th:block>
|
||||
</html>
|
||||
Reference in New Issue
Block a user