- Add translation field to schema + auto-match by zh/ prefix - BaseLayout accepts per-page switchHref; post page resolves translation link - Falls back to section landing (/ or /zh/) when no translation exists
This commit is contained in:
1 parent
677fc7cb20
commit
6b56c1f4db
3 files changed
+20
-3
No files matched your search
@@ -21,6 +21,9 @@ const posts = defineCollection({
|
||||
// lang is NOT set in frontmatter anymore — it's derived from the folder:
|
||||
// posts/hello-world.md -> en (flat)
|
||||
// posts/zh/hello-world.md -> zh (subfolder)
|
||||
// Explicit link to the other-language version (its full slug, e.g. "zh/how-i-host-this-blog").
|
||||
// When absent, the language switch falls back to the section landing page (/ or /zh/).
|
||||
translation: z.string().optional(),
|
||||
ogImage: z.string().optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -10,6 +10,10 @@ interface Props {
|
||||
lang?: string;
|
||||
ogImage?: string;
|
||||
type?: 'website' | 'article';
|
||||
// Optional: direct URL of this page's translation (the other-language version).
|
||||
// When provided, the language switch links to it; otherwise it falls back to
|
||||
// the section landing page (/ for EN, /zh/ for ZH).
|
||||
switchHref?: string;
|
||||
article?: {
|
||||
publishedTime: string;
|
||||
modifiedTime?: string;
|
||||
@@ -24,6 +28,7 @@ const {
|
||||
lang = SITE.lang,
|
||||
ogImage = '/og-default.png',
|
||||
type = 'website',
|
||||
switchHref,
|
||||
article,
|
||||
} = Astro.props;
|
||||
|
||||
@@ -31,9 +36,9 @@ const canonical = new URL(Astro.url.pathname, SITE.url).href;
|
||||
const ogImageUrl = new URL(ogImage, SITE.url).href;
|
||||
|
||||
// Language switcher: opposite of current page lang.
|
||||
// English pages link to /zh/ (Chinese landing); Chinese pages link back to /.
|
||||
// If a per-page translation link is provided, use it; else fall back to the section landing.
|
||||
const isZh = lang === 'zh';
|
||||
const switchHref = isZh ? '/' : '/zh/';
|
||||
const resolvedSwitchHref = switchHref ?? (isZh ? '/' : '/zh/');
|
||||
const switchLabel = isZh ? 'EN' : '中文';
|
||||
---
|
||||
|
||||
@@ -127,7 +132,7 @@ const switchLabel = isZh ? 'EN' : '中文';
|
||||
<a href="/categories/">categories</a>
|
||||
<a href="/about/">about</a>
|
||||
<a href="/rss.xml" title="RSS feed">rss</a>
|
||||
<a class="lang-switch" href={switchHref} aria-label={isZh ? 'Switch to English' : '切换到中文'}>{switchLabel}</a>
|
||||
<a class="lang-switch" href={resolvedSwitchHref} aria-label={isZh ? 'Switch to English' : '切换到中文'}>{switchLabel}</a>
|
||||
<button class="theme-toggle" id="theme-toggle" aria-label="Toggle theme">◐</button>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
@@ -37,6 +37,14 @@ const related = all
|
||||
.sort((a, b) => b.score - a.score)
|
||||
.slice(0, 3)
|
||||
.map((r) => r.post);
|
||||
|
||||
// Translation link for the language switch:
|
||||
// 1. Explicit `translation` field wins.
|
||||
// 2. Else auto-match the other-language slug (strip/add the `zh/` prefix).
|
||||
const otherLangSlug = lang === 'en' ? `zh/${post.slug}` : post.slug.replace(/^zh\//, '');
|
||||
const translation = post.data.translation
|
||||
?? (all.some((p) => p.slug === otherLangSlug) ? otherLangSlug : undefined);
|
||||
const switchHref = translation ? `/posts/${translation}/` : undefined;
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
@@ -45,6 +53,7 @@ const related = all
|
||||
lang={lang}
|
||||
ogImage={post.data.ogImage ?? '/og-default.png'}
|
||||
type="article"
|
||||
switchHref={switchHref}
|
||||
article={{
|
||||
publishedTime: post.data.pubDate.toISOString(),
|
||||
modifiedTime: post.data.updatedDate?.toISOString(),
|
||||
|
||||
Reference in new issue
Block a user