feat: add localized visual tag filter bar to blog pages

This commit is contained in:
yoma committed 2026-07-07 00:22:33 +08:00
1 parent c85d2cc219
commit fb46d6d4c5
3 files changed
+114 -2

No files matched your search

+8
View File
@@ -48,6 +48,10 @@ export const siteCopy = {
demo: "在线演示",
language: "语言",
languageMenu: "切换语言",
tagAll: "全部",
tagMigration: "迁移教程",
tagMcp: "AI 协同 (MCP)",
tagSelfHosted: "部署自托管",
},
hero: {
slogan: siteTaglines["zh-CN"],
@@ -155,6 +159,10 @@ export const siteCopy = {
demo: "Demo",
language: "Language",
languageMenu: "Change language",
tagAll: "All",
tagMigration: "Migration",
tagMcp: "AI & MCP",
tagSelfHosted: "Deployment",
},
hero: {
slogan: siteTaglines["en-US"],
+53 -1
View File
@@ -3,6 +3,7 @@ import { getCollection } from "astro:content";
import Container from "@/components/container.astro";
import Layout from "@/layouts/Layout.astro";
import { getFormattedDate } from "@/utils/all";
import { getLocalizedPath, getSiteLocale, siteCopy } from "@/i18n";
const selectedTag = Astro.url.searchParams.get("tag");
@@ -16,6 +17,9 @@ const entries = (await getCollection("blog", ({ data }) => {
(a, b) => b.data.publishDate.getTime() - a.data.publishDate.getTime(),
);
const locale = getSiteLocale(Astro.url.pathname);
const copy = siteCopy[locale].nav;
const blogUrl = new URL(Astro.url.pathname, Astro.site).toString();
const blogDescription =
"EdgeEver 官方博客,记录 Cloudflare 自托管部署、印象笔记迁移、产品更新与 AI Agent 工作流。";
@@ -33,13 +37,61 @@ const blogJsonLd = {
<Layout title="博客" description={blogDescription} jsonLd={blogJsonLd}>
<Container>
<main class="mx-auto max-w-4xl py-16 md:py-24">
<div class="mb-10">
<div class="mb-8">
<p class="text-sm font-semibold text-brand-text">EdgeEver Blog</p>
<h1 class="mt-3 text-4xl font-bold tracking-tight text-slate-900 md:text-5xl">
博客
</h1>
</div>
<!-- 标签筛选工具条 -->
<div class="flex flex-wrap gap-2 mb-10 select-none">
<a
href={getLocalizedPath(locale, "/blog")}
class:list={[
"px-4 py-1.5 text-xs font-medium border rounded-full transition-all duration-200 cursor-pointer",
!selectedTag
? "text-brand bg-brand/5 border-brand-border/40 font-semibold shadow-sm"
: "text-slate-600 bg-slate-50 border-slate-200 hover:bg-slate-100 hover:text-slate-900"
]}
>
{copy.tagAll}
</a>
<a
href={`${getLocalizedPath(locale, "/blog")}?tag=migration`}
class:list={[
"px-4 py-1.5 text-xs font-medium border rounded-full transition-all duration-200 cursor-pointer",
selectedTag === "migration"
? "text-brand bg-brand/5 border-brand-border/40 font-semibold shadow-sm"
: "text-slate-600 bg-slate-50 border-slate-200 hover:bg-slate-100 hover:text-slate-900"
]}
>
🏷️ {copy.tagMigration}
</a>
<a
href={`${getLocalizedPath(locale, "/blog")}?tag=mcp`}
class:list={[
"px-4 py-1.5 text-xs font-medium border rounded-full transition-all duration-200 cursor-pointer",
selectedTag === "mcp"
? "text-brand bg-brand/5 border-brand-border/40 font-semibold shadow-sm"
: "text-slate-600 bg-slate-50 border-slate-200 hover:bg-slate-100 hover:text-slate-900"
]}
>
🤖 {copy.tagMcp}
</a>
<a
href={`${getLocalizedPath(locale, "/blog")}?tag=self-hosted`}
class:list={[
"px-4 py-1.5 text-xs font-medium border rounded-full transition-all duration-200 cursor-pointer",
selectedTag === "self-hosted"
? "text-brand bg-brand/5 border-brand-border/40 font-semibold shadow-sm"
: "text-slate-600 bg-slate-50 border-slate-200 hover:bg-slate-100 hover:text-slate-900"
]}
>
☁️ {copy.tagSelfHosted}
</a>
</div>
<div class="grid gap-4">
{
entries.map((entry) => (
+53 -1
View File
@@ -3,6 +3,7 @@ import { getCollection } from "astro:content";
import Layout from "@/layouts/Layout.astro";
import Container from "@/components/container.astro";
import { getFormattedDate } from "@/utils/all";
import { getLocalizedPath, getSiteLocale, siteCopy } from "@/i18n";
const selectedTag = Astro.url.searchParams.get("tag");
@@ -19,6 +20,9 @@ const entries = (await getCollection("blog_en", ({ data }) => {
const blogDescription =
"English EdgeEver notes about Cloudflare self-hosting, Evernote migration, product updates, and AI Agent workflows.";
const locale = getSiteLocale(Astro.url.pathname);
const copy = siteCopy[locale].nav;
const blogUrl = new URL(Astro.url.pathname, Astro.site).toString();
const blogJsonLd = {
"@context": "https://schema.org",
@@ -36,7 +40,55 @@ const blogJsonLd = {
<p class="text-sm font-semibold text-brand-text">EdgeEver Blog</p>
<h1 class="mt-3 text-4xl font-bold tracking-tight text-slate-950 md:text-5xl">Blog</h1>
<div class="mt-10 grid gap-4">
<!-- 标签筛选工具条 -->
<div class="flex flex-wrap gap-2 mt-8 mb-10 select-none">
<a
href={getLocalizedPath(locale, "/blog")}
class:list={[
"px-4 py-1.5 text-xs font-medium border rounded-full transition-all duration-200 cursor-pointer",
!selectedTag
? "text-brand bg-brand/5 border-brand-border/40 font-semibold shadow-sm"
: "text-slate-600 bg-slate-50 border-slate-200 hover:bg-slate-100 hover:text-slate-900"
]}
>
{copy.tagAll}
</a>
<a
href={`${getLocalizedPath(locale, "/blog")}?tag=migration`}
class:list={[
"px-4 py-1.5 text-xs font-medium border rounded-full transition-all duration-200 cursor-pointer",
selectedTag === "migration"
? "text-brand bg-brand/5 border-brand-border/40 font-semibold shadow-sm"
: "text-slate-600 bg-slate-50 border-slate-200 hover:bg-slate-100 hover:text-slate-900"
]}
>
🏷️ {copy.tagMigration}
</a>
<a
href={`${getLocalizedPath(locale, "/blog")}?tag=mcp`}
class:list={[
"px-4 py-1.5 text-xs font-medium border rounded-full transition-all duration-200 cursor-pointer",
selectedTag === "mcp"
? "text-brand bg-brand/5 border-brand-border/40 font-semibold shadow-sm"
: "text-slate-600 bg-slate-50 border-slate-200 hover:bg-slate-100 hover:text-slate-900"
]}
>
🤖 {copy.tagMcp}
</a>
<a
href={`${getLocalizedPath(locale, "/blog")}?tag=self-hosted`}
class:list={[
"px-4 py-1.5 text-xs font-medium border rounded-full transition-all duration-200 cursor-pointer",
selectedTag === "self-hosted"
? "text-brand bg-brand/5 border-brand-border/40 font-semibold shadow-sm"
: "text-slate-600 bg-slate-50 border-slate-200 hover:bg-slate-100 hover:text-slate-900"
]}
>
☁️ {copy.tagSelfHosted}
</a>
</div>
<div class="grid gap-4">
{
entries.map((entry) => (
<a