Skip to content

Commit 26ce1e4

Browse files
authored
feat: layout i18n (#32)
* feat: layout i18n * refactor: add alternate urls
1 parent 874aa62 commit 26ce1e4

File tree

10 files changed

+111
-23
lines changed

10 files changed

+111
-23
lines changed

src/components/Share.astro

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ import ShareButton from "../components/ShareButton.astro";
33
44
type Props = {
55
title: string;
6+
shareText?: string;
67
};
78
8-
const { title } = Astro.props;
9+
const { title, shareText } = Astro.props;
910
---
1011

1112
<aside class="share">
12-
<span>Share</span>
13+
<span>{shareText ?? "Share"}</span>
1314
<div>
1415
<ShareButton type="x" title={title} />
1516
<ShareButton type="reddit" title={title} />

src/components/Topbar.astro

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,17 @@ import { Icon } from "astro-icon/components";
33
import Logo from "./Logo.astro";
44
import ByLogto from "./ByLogto.astro";
55
import SolidA from "./SolidA.astro";
6+
import { defaultLocale, getLocale } from "astro-i18n-aut";
7+
8+
const locale = getLocale(Astro.url);
69
---
710

811
<div class="topbar">
9-
<a class="home" href="/" aria-label="Go to homepage">
12+
<a
13+
class="home"
14+
href={locale === defaultLocale ? "/" : `/${locale}`}
15+
aria-label="Go to homepage"
16+
>
1017
<Logo />
1118
</a>
1219
<div class="actions">

src/layouts/Layout.astro

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
---
22
import { AstroSeo } from "@astrolib/seo";
3-
import { getLocale } from "astro-i18n-aut";
3+
import {
4+
defaultLocale,
5+
getLocale,
6+
getLocaleUrl,
7+
locales,
8+
} from "astro-i18n-aut";
9+
import { getPhrases } from "../phrases";
410
511
type Props = {
612
title?: string;
@@ -10,10 +16,9 @@ type Props = {
1016
const { props } = Astro;
1117
1218
const locale = getLocale(Astro.url);
19+
const phrases = getPhrases(locale);
1320
const title = props.title ? `${props.title} · Auth Wiki` : "Auth Wiki";
14-
const description =
15-
props.description ??
16-
"Auth Wiki is a comprehensive collection of articles, tutorials, and resources about authentication and authorization. Learn about OAuth 2.0, OpenID Connect, SAML, and more.";
21+
const description = props.description ?? phrases.site.description;
1722
const canonical = new URL(Astro.url.pathname, Astro.site).href;
1823
---
1924

@@ -31,6 +36,19 @@ const canonical = new URL(Astro.url.pathname, Astro.site).href;
3136
url: canonical,
3237
site_name: "Auth Wiki",
3338
}}
39+
languageAlternates={[
40+
...Object.keys(locales).map((lang) => ({
41+
hreflang: lang,
42+
href: new URL(getLocaleUrl(Astro.url.pathname, lang), Astro.url).href,
43+
})),
44+
{
45+
hreflang: "x-default",
46+
href: new URL(
47+
getLocaleUrl(Astro.url.pathname, defaultLocale),
48+
Astro.url,
49+
).href,
50+
},
51+
]}
3452
/>
3553
<meta name="viewport" content="width=device-width, initial-scale=1" />
3654
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />

src/mdx-components/Resources.astro

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
---
22
import ogs from "open-graph-scraper";
3+
import { getPhrases } from "../phrases";
4+
import { getLocale } from "astro-i18n-aut";
35
46
/** Type to override the default metadata for the page. */
57
type UrlMetadata = {
@@ -47,10 +49,13 @@ const results = await Promise.all(
4749
return { url, result };
4850
}),
4951
);
52+
53+
const locale = getLocale(Astro.url);
54+
const phrases = getPhrases(locale);
5055
---
5156

5257
<aside>
53-
<h2>Resources and references</h2>
58+
<h2>{phrases.content.resources_and_references}</h2>
5459
{
5560
results.map(({ url, result }) => (
5661
<a href={url} class="resource" target="_blank" rel="noopener">

src/mdx-components/SeeAlso.astro

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
---
2+
import { getLocale } from "astro-i18n-aut";
23
import Ref from "./Ref.astro";
4+
import { getPhrases } from "../phrases";
35
46
type Props = {
57
/**
@@ -15,9 +17,12 @@ const { slugs } = Astro.props;
1517
if (slugs.length === 0) {
1618
throw new Error('The "slugs" prop must contain at least one slug.');
1719
}
20+
21+
const locale = getLocale(Astro.url);
22+
const phrases = getPhrases(locale);
1823
---
1924

20-
<h2>See also</h2>
25+
<h2>{phrases.content.see_also}</h2>
2126
<ul class="list">
2227
{
2328
slugs.map((slug) => (

src/pages/[slug].astro

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { Icon } from "astro-icon/components";
1515
import { getCollection } from "astro:content";
1616
import { getEntry } from "astro:content";
1717
import { defaultLocale, getLocale } from "astro-i18n-aut";
18+
import { getPhrases } from "../phrases";
1819
1920
export async function getStaticPaths() {
2021
// Only the default locale is needed for generating paths. Other locales will be handled by
@@ -53,6 +54,8 @@ const { headings, Content } = await entry.render();
5354
if (headings.some(({ depth }) => depth === 1)) {
5455
throw new Error("The article must not contain a top-level heading.");
5556
}
57+
58+
const phrases = getPhrases(locale);
5659
---
5760

5861
<Layout title={title} description={description}>
@@ -70,22 +73,22 @@ if (headings.some(({ depth }) => depth === 1)) {
7073
{description}
7174
</p>
7275
<div class="actions">
73-
<Share title={title} />
76+
<Share title={title} shareText={phrases.general.share} />
7477
<a
7578
class="edit"
7679
href={`https://github.com/logto-io/auth-wiki/edit/master/src/content/${entry.collection}/${entry.slug}.mdx`}
7780
target="_blank"
7881
rel="noopener"
7982
>
8083
<Icon name="github" />
81-
<span>Edit on GitHub</span>
84+
<span>{phrases.content.edit_on_github}</span>
8285
</a>
8386
</div>
8487
</div>
8588
</header>
8689
<div class="content">
8790
<nav class="toc">
88-
<h2>Table of Contents</h2>
91+
<h2>{phrases.content.table_of_contents}</h2>
8992
<ul>
9093
{
9194
headings
@@ -120,6 +123,7 @@ if (headings.some(({ depth }) => depth === 1)) {
120123
position: relative;
121124
}
122125
header div.background {
126+
z-index: -1;
123127
position: absolute;
124128
background: linear-gradient(180deg, #6225cc 0%, rgb(179, 3, 255) 100%);
125129
top: -100px;
@@ -128,6 +132,7 @@ if (headings.some(({ depth }) => depth === 1)) {
128132
right: 0;
129133
}
130134
.background-cells {
135+
z-index: -1;
131136
position: absolute;
132137
right: 12px;
133138
top: 100px;

src/pages/index.astro

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Topbar from "../components/Topbar.astro";
55
import Footer from "../components/Footer.astro";
66
import BackgroundBanner from "../components/BackgroundBanner.astro";
77
import Share from "../components/Share.astro";
8+
import { getPhrases } from "../phrases";
89
import { getCollection } from "astro:content";
910
import { defaultLocale, getLocale } from "astro-i18n-aut";
1011
@@ -44,6 +45,8 @@ const sections = entries
4445
},
4546
{} as Record<string, typeof entries>,
4647
);
48+
49+
const phrases = getPhrases(locale);
4750
---
4851

4952
<Layout>
@@ -59,14 +62,8 @@ const sections = entries
5962
<li>OAuth 2.0</li>
6063
<li>SAML</li>
6164
</ul>
62-
<p>
63-
Explore and find clear definitions of key glossaries related to
64-
authentication, authorization, and identity management. Work with
65-
open-standards like <a href="/openid-connect">OpenID Connect</a>, <a
66-
href="/oauth-2.0">OAuth 2.0</a
67-
>, and <a href="/saml">SAML</a>.
68-
</p>
69-
<Share title="Auth Wiki" />
65+
<p set:html={phrases.home.description} />
66+
<Share title="Auth Wiki" shareText={phrases.general.share} />
7067
</div>
7168
</header>
7269
<div class="content">
@@ -132,11 +129,11 @@ const sections = entries
132129
line-height: 36px;
133130
margin: 0;
134131
}
135-
header p a {
132+
header p :global(a) {
136133
color: #f1e8ff;
137134
text-decoration: none;
138135
}
139-
header p a:hover {
136+
header p :global(a:hover) {
140137
text-decoration: underline 1.5px;
141138
text-underline-offset: 2px;
142139
}
@@ -202,7 +199,7 @@ const sections = entries
202199
header div.background {
203200
display: none;
204201
}
205-
header p a {
202+
header p :global(a) {
206203
color: #cabeff;
207204
}
208205
}

src/phrases/en.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export const en = Object.freeze({
2+
general: {
3+
share: 'Share',
4+
},
5+
site: {
6+
description: 'Auth Wiki is a comprehensive collection of articles, tutorials, and resources about authentication and authorization. Learn about OAuth 2.0, OpenID Connect, SAML, and more.',
7+
},
8+
home: {
9+
description: 'Explore and find clear definitions of key glossaries related to authentication, authorization, and identity management. Work with open-standards like <a href="/openid-connect">OpenID Connect</a>, <a href="/oauth-2.0">OAuth 2.0</a>, and <a href="/saml">SAML</a>.'
10+
},
11+
content: {
12+
edit_on_github: 'Edit on GitHub',
13+
table_of_contents: 'Table of Contents',
14+
see_also: 'See also',
15+
resources_and_references: 'Resources and references',
16+
}
17+
});

src/phrases/index.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export * from './en';
2+
export * from './zh';
3+
4+
import { en } from './en';
5+
import { zh } from './zh';
6+
7+
export const getPhrases = (locale: string) => {
8+
switch (locale) {
9+
case 'zh':
10+
return zh;
11+
case 'en':
12+
return en;
13+
default:
14+
throw new Error(`Unsupported locale: ${locale}`);
15+
}
16+
}

src/phrases/zh.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export const zh = Object.freeze({
2+
general: {
3+
share: '分享',
4+
},
5+
site: {
6+
description: 'Auth Wiki 是一个关于身份验证和授权的全面文章、教程和资源集合。了解 OAuth 2.0、OpenID Connect、SAML 等内容。'
7+
},
8+
home: {
9+
description: '探索并找到与身份验证、授权和身份管理相关的关键术语的清晰定义。使用诸如 <a href="/openid-connect">OpenID Connect</a>、<a href="/oauth-2.0">OAuth 2.0</a> 和 <a href="/saml">SAML</a> 等开放标准。'
10+
},
11+
content: {
12+
edit_on_github: '在 GitHub 上编辑',
13+
table_of_contents: '目录',
14+
see_also: '另请参阅',
15+
resources_and_references: '资源和参考',
16+
}
17+
});

0 commit comments

Comments
 (0)