Skip to content

Commit

Permalink
feat: layout i18n (#32)
Browse files Browse the repository at this point in the history
* feat: layout i18n

* refactor: add alternate urls
  • Loading branch information
gao-sun authored Nov 6, 2024
1 parent 874aa62 commit 26ce1e4
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 23 deletions.
5 changes: 3 additions & 2 deletions src/components/Share.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import ShareButton from "../components/ShareButton.astro";
type Props = {
title: string;
shareText?: string;
};
const { title } = Astro.props;
const { title, shareText } = Astro.props;
---

<aside class="share">
<span>Share</span>
<span>{shareText ?? "Share"}</span>
<div>
<ShareButton type="x" title={title} />
<ShareButton type="reddit" title={title} />
Expand Down
9 changes: 8 additions & 1 deletion src/components/Topbar.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,17 @@ import { Icon } from "astro-icon/components";
import Logo from "./Logo.astro";
import ByLogto from "./ByLogto.astro";
import SolidA from "./SolidA.astro";
import { defaultLocale, getLocale } from "astro-i18n-aut";
const locale = getLocale(Astro.url);
---

<div class="topbar">
<a class="home" href="/" aria-label="Go to homepage">
<a
class="home"
href={locale === defaultLocale ? "/" : `/${locale}`}
aria-label="Go to homepage"
>
<Logo />
</a>
<div class="actions">
Expand Down
26 changes: 22 additions & 4 deletions src/layouts/Layout.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
---
import { AstroSeo } from "@astrolib/seo";
import { getLocale } from "astro-i18n-aut";
import {
defaultLocale,
getLocale,
getLocaleUrl,
locales,
} from "astro-i18n-aut";
import { getPhrases } from "../phrases";
type Props = {
title?: string;
Expand All @@ -10,10 +16,9 @@ type Props = {
const { props } = Astro;
const locale = getLocale(Astro.url);
const phrases = getPhrases(locale);
const title = props.title ? `${props.title} · Auth Wiki` : "Auth Wiki";
const description =
props.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.";
const description = props.description ?? phrases.site.description;
const canonical = new URL(Astro.url.pathname, Astro.site).href;
---

Expand All @@ -31,6 +36,19 @@ const canonical = new URL(Astro.url.pathname, Astro.site).href;
url: canonical,
site_name: "Auth Wiki",
}}
languageAlternates={[
...Object.keys(locales).map((lang) => ({
hreflang: lang,
href: new URL(getLocaleUrl(Astro.url.pathname, lang), Astro.url).href,
})),
{
hreflang: "x-default",
href: new URL(
getLocaleUrl(Astro.url.pathname, defaultLocale),
Astro.url,
).href,
},
]}
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
Expand Down
7 changes: 6 additions & 1 deletion src/mdx-components/Resources.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
import ogs from "open-graph-scraper";
import { getPhrases } from "../phrases";
import { getLocale } from "astro-i18n-aut";
/** Type to override the default metadata for the page. */
type UrlMetadata = {
Expand Down Expand Up @@ -47,10 +49,13 @@ const results = await Promise.all(
return { url, result };
}),
);
const locale = getLocale(Astro.url);
const phrases = getPhrases(locale);
---

<aside>
<h2>Resources and references</h2>
<h2>{phrases.content.resources_and_references}</h2>
{
results.map(({ url, result }) => (
<a href={url} class="resource" target="_blank" rel="noopener">
Expand Down
7 changes: 6 additions & 1 deletion src/mdx-components/SeeAlso.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
import { getLocale } from "astro-i18n-aut";
import Ref from "./Ref.astro";
import { getPhrases } from "../phrases";
type Props = {
/**
Expand All @@ -15,9 +17,12 @@ const { slugs } = Astro.props;
if (slugs.length === 0) {
throw new Error('The "slugs" prop must contain at least one slug.');
}
const locale = getLocale(Astro.url);
const phrases = getPhrases(locale);
---

<h2>See also</h2>
<h2>{phrases.content.see_also}</h2>
<ul class="list">
{
slugs.map((slug) => (
Expand Down
11 changes: 8 additions & 3 deletions src/pages/[slug].astro
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Icon } from "astro-icon/components";
import { getCollection } from "astro:content";
import { getEntry } from "astro:content";
import { defaultLocale, getLocale } from "astro-i18n-aut";
import { getPhrases } from "../phrases";
export async function getStaticPaths() {
// Only the default locale is needed for generating paths. Other locales will be handled by
Expand Down Expand Up @@ -53,6 +54,8 @@ const { headings, Content } = await entry.render();
if (headings.some(({ depth }) => depth === 1)) {
throw new Error("The article must not contain a top-level heading.");
}
const phrases = getPhrases(locale);
---

<Layout title={title} description={description}>
Expand All @@ -70,22 +73,22 @@ if (headings.some(({ depth }) => depth === 1)) {
{description}
</p>
<div class="actions">
<Share title={title} />
<Share title={title} shareText={phrases.general.share} />
<a
class="edit"
href={`https://github.com/logto-io/auth-wiki/edit/master/src/content/${entry.collection}/${entry.slug}.mdx`}
target="_blank"
rel="noopener"
>
<Icon name="github" />
<span>Edit on GitHub</span>
<span>{phrases.content.edit_on_github}</span>
</a>
</div>
</div>
</header>
<div class="content">
<nav class="toc">
<h2>Table of Contents</h2>
<h2>{phrases.content.table_of_contents}</h2>
<ul>
{
headings
Expand Down Expand Up @@ -120,6 +123,7 @@ if (headings.some(({ depth }) => depth === 1)) {
position: relative;
}
header div.background {
z-index: -1;
position: absolute;
background: linear-gradient(180deg, #6225cc 0%, rgb(179, 3, 255) 100%);
top: -100px;
Expand All @@ -128,6 +132,7 @@ if (headings.some(({ depth }) => depth === 1)) {
right: 0;
}
.background-cells {
z-index: -1;
position: absolute;
right: 12px;
top: 100px;
Expand Down
19 changes: 8 additions & 11 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Topbar from "../components/Topbar.astro";
import Footer from "../components/Footer.astro";
import BackgroundBanner from "../components/BackgroundBanner.astro";
import Share from "../components/Share.astro";
import { getPhrases } from "../phrases";
import { getCollection } from "astro:content";
import { defaultLocale, getLocale } from "astro-i18n-aut";
Expand Down Expand Up @@ -44,6 +45,8 @@ const sections = entries
},
{} as Record<string, typeof entries>,
);
const phrases = getPhrases(locale);
---

<Layout>
Expand All @@ -59,14 +62,8 @@ const sections = entries
<li>OAuth 2.0</li>
<li>SAML</li>
</ul>
<p>
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>.
</p>
<Share title="Auth Wiki" />
<p set:html={phrases.home.description} />
<Share title="Auth Wiki" shareText={phrases.general.share} />
</div>
</header>
<div class="content">
Expand Down Expand Up @@ -132,11 +129,11 @@ const sections = entries
line-height: 36px;
margin: 0;
}
header p a {
header p :global(a) {
color: #f1e8ff;
text-decoration: none;
}
header p a:hover {
header p :global(a:hover) {
text-decoration: underline 1.5px;
text-underline-offset: 2px;
}
Expand Down Expand Up @@ -202,7 +199,7 @@ const sections = entries
header div.background {
display: none;
}
header p a {
header p :global(a) {
color: #cabeff;
}
}
Expand Down
17 changes: 17 additions & 0 deletions src/phrases/en.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const en = Object.freeze({
general: {
share: 'Share',
},
site: {
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.',
},
home: {
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>.'
},
content: {
edit_on_github: 'Edit on GitHub',
table_of_contents: 'Table of Contents',
see_also: 'See also',
resources_and_references: 'Resources and references',
}
});
16 changes: 16 additions & 0 deletions src/phrases/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export * from './en';
export * from './zh';

import { en } from './en';
import { zh } from './zh';

export const getPhrases = (locale: string) => {
switch (locale) {
case 'zh':
return zh;
case 'en':
return en;
default:
throw new Error(`Unsupported locale: ${locale}`);
}
}
17 changes: 17 additions & 0 deletions src/phrases/zh.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const zh = Object.freeze({
general: {
share: '分享',
},
site: {
description: 'Auth Wiki 是一个关于身份验证和授权的全面文章、教程和资源集合。了解 OAuth 2.0、OpenID Connect、SAML 等内容。'
},
home: {
description: '探索并找到与身份验证、授权和身份管理相关的关键术语的清晰定义。使用诸如 <a href="/openid-connect">OpenID Connect</a>、<a href="/oauth-2.0">OAuth 2.0</a> 和 <a href="/saml">SAML</a> 等开放标准。'
},
content: {
edit_on_github: '在 GitHub 上编辑',
table_of_contents: '目录',
see_also: '另请参阅',
resources_and_references: '资源和参考',
}
});

0 comments on commit 26ce1e4

Please sign in to comment.