This commit is contained in:
2026-06-21 20:01:20 +08:00
parent 62732ba348
commit 42516257e0
9 changed files with 179 additions and 18 deletions
+3 -1
View File
@@ -20,7 +20,9 @@
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-10">
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6">
<p class="text-sm text-gray-500 uppercase tracking-wider">{{index .Tr "dash_posts"}}</p>
<p class="text-3xl font-bold text-gray-900 mt-1">0</p>
<p class="text-3xl font-bold text-gray-900 mt-1">{{.PostCount}}
<span class="text-sm font-normal text-gray-400">({{.PublishedCount}} {{index .Tr "dash_published"}})</span>
</p>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6">
<p class="text-sm text-gray-500 uppercase tracking-wider">{{index .Tr "dash_pages"}}</p>
+10
View File
@@ -0,0 +1,10 @@
{{define "article_not_found"}}
{{template "header" .}}
<section class="max-w-3xl mx-auto px-4 py-24 text-center">
<h1 class="text-3xl font-bold text-gray-900 mb-3">{{index .Tr "article_not_found"}}</h1>
<a href="/" class="inline-block mt-4 bg-blue-600 text-white px-6 py-3 rounded-lg font-medium hover:bg-blue-700 transition-colors">
{{index .Tr "article_back_home"}}
</a>
</section>
{{template "footer" .}}
{{end}}
+39
View File
@@ -0,0 +1,39 @@
{{define "article"}}
{{template "header" .}}
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<section class="max-w-3xl mx-auto px-4 py-12">
<a href="/" class="inline-flex items-center gap-1 text-sm text-gray-500 hover:text-blue-600 transition-colors mb-6">
← {{index .Tr "article_back_home"}}
</a>
<article>
<h1 class="text-4xl font-extrabold text-gray-900 mb-3">{{.Article.Title}}</h1>
<div class="flex items-center gap-3 text-sm text-gray-500 mb-8">
{{if .Article.Author.Avatar}}
<img src="/uploads/avatars/{{.Article.Author.Avatar}}" alt="avatar" class="w-7 h-7 rounded-full object-cover">
{{end}}
<span class="font-medium text-gray-700">{{.AuthorName}}</span>
{{if .PublishedAt}}<span>·</span><span>{{.PublishedAt}}</span>{{end}}
</div>
{{if .Article.Cover}}
<div class="rounded-xl overflow-hidden mb-8">
<img src="{{.Article.Cover}}" alt="{{.Article.Title}}" class="w-full max-h-96 object-cover">
</div>
{{end}}
<div id="articleBody" class="prose max-w-none text-gray-800"></div>
</article>
</section>
<script>
// {{.Article.Content}} is emitted by html/template as a JSON-encoded JS
// string, safely handling quotes, newlines, and HTML special characters.
var md = {{.Article.Content}};
document.getElementById('articleBody').innerHTML = marked.parse(md);
</script>
{{template "footer" .}}
{{end}}
+19 -12
View File
@@ -20,18 +20,25 @@
<section class="max-w-5xl mx-auto px-4 py-16">
<h2 class="text-3xl font-bold text-gray-900 mb-8 text-center">{{index .Tr "home_latest"}}</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6">
<h3 class="text-lg font-semibold text-gray-800 mb-2">{{index .Tr "home_post1_tit"}}</h3>
<p class="text-gray-500 text-sm">{{index .Tr "home_post1_dsc"}}</p>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6">
<h3 class="text-lg font-semibold text-gray-800 mb-2">{{index .Tr "home_post2_tit"}}</h3>
<p class="text-gray-500 text-sm">{{index .Tr "home_post2_dsc"}}</p>
</div>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6">
<h3 class="text-lg font-semibold text-gray-800 mb-2">{{index .Tr "home_post3_tit"}}</h3>
<p class="text-gray-500 text-sm">{{index .Tr "home_post3_dsc"}}</p>
</div>
{{range .Articles}}
<a href="/article/{{.Slug}}"
class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden hover:shadow-md transition-shadow flex flex-col">
{{if .Cover}}
<div class="aspect-video w-full overflow-hidden bg-gray-100">
<img src="{{.Cover}}" alt="{{.Title}}" class="w-full h-full object-cover">
</div>
{{end}}
<div class="p-6 flex flex-col flex-1">
<h3 class="text-lg font-semibold text-gray-800 mb-2">{{.Title}}
{{if .IsTop}}<span class="align-middle text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded ml-1">{{index $.Tr "article_is_top"}}</span>{{end}}
</h3>
{{if .Summary}}<p class="text-gray-500 text-sm line-clamp-2">{{.Summary}}</p>{{end}}
<span class="mt-4 text-sm text-blue-600 font-medium">{{index $.Tr "home_read_more"}} →</span>
</div>
</a>
{{else}}
<div class="col-span-full text-center text-gray-500 py-12">{{index .Tr "home_no_posts"}}</div>
{{end}}
</div>
</section>
{{template "footer" .}}