summaryrefslogtreecommitdiff
path: root/src/components/Translations.astro
diff options
context:
space:
mode:
authorJoão Augusto Costa Branco Marado Torres <torres.dev@disroot.org>2025-06-24 12:08:41 -0300
committerJoão Augusto Costa Branco Marado Torres <torres.dev@disroot.org>2025-06-24 12:50:43 -0300
commitf9a77c5c27aede4e5978eb55d9b7af781b680a1d (patch)
treed545e325ba1ae756fc2eac66fac1001b6753c40d /src/components/Translations.astro
feat!: initial commit
Signed-off-by: João Augusto Costa Branco Marado Torres <torres.dev@disroot.org>
Diffstat (limited to 'src/components/Translations.astro')
-rw-r--r--src/components/Translations.astro107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/components/Translations.astro b/src/components/Translations.astro
new file mode 100644
index 0000000..b0164bb
--- /dev/null
+++ b/src/components/Translations.astro
@@ -0,0 +1,107 @@
+---
+import type { CollectionEntry } from "astro:content";
+import {
+ getFlagEmojiFromLocale,
+ getLanguageNameFromLocale,
+} from "../utils/lang";
+import { getEntries } from "astro:content";
+
+interface Props {
+ lang: string;
+ translations?: CollectionEntry<"blog">["data"]["translations"];
+}
+
+const { lang } = Astro.props;
+
+const translations = await getEntries(Astro.props.translations ?? []).then(
+ (translations) =>
+ translations.sort((x, y) => x.data.lang.localeCompare(y.data.lang)),
+);
+---
+
+{
+ /* TODO: What about <https://schema.org/translationOfWork> and <https://schema.org/translator>? */
+}
+
+{
+ translations.length > 0 && (
+ <aside>
+ <nav>
+ <p>Traduções:</p>
+ <ul class="translations">
+ {
+ translations.map(async (
+ { data, collection, id },
+ ) => {
+ const active = lang.localeCompare(data.lang) === 0;
+ return (
+ <li
+ itemprop={active ? undefined : "workTranslation"}
+ itemscope={!active}
+ itemtype={active ? undefined : "http://schema.org/BlogPosting"}
+ itemid={active
+ ? undefined
+ : new URL(`${collection}/read/${id}`, Astro.site).href}
+ >
+ <a
+ href={`/${collection}/read/${id}`}
+ class:list={[{ active }]}
+ rel={active ? undefined : "alternate"}
+ hreflang={active ? undefined : data.lang}
+ type="text/html"
+ title={data.title}
+ ><span class="emoji">{getFlagEmojiFromLocale(data.lang)}</span>
+ {getLanguageNameFromLocale(data.lang)} (<span
+ itemprop="inLanguage"
+ >{data.lang}</span>)</a>
+ </li>
+ );
+ })
+ }
+ </ul>
+ </nav>
+ </aside>
+ )
+}
+
+<style>
+ .translations {
+ list-style-type: none;
+ padding-inline-start: 0;
+ }
+
+ .translations > li {
+ display: inline;
+ }
+
+ .translations > li > a > .emoji {
+ text-decoration: none;
+ font-family: var(--ff-icons);
+ }
+
+ .translations > li > a.active {
+ font-weight: bolder;
+ text-decoration: underline;
+ color: var(--color-active);
+ }
+
+ nav:has(.translations) {
+ display: flex;
+ gap: 1rem;
+ }
+
+ nav:has(.translations) > * {
+ font-size: smaller;
+ }
+
+ .translations > li:not(:first-child)::before {
+ content: "|";
+ margin-inline: 0.5em;
+ }
+
+ @media print {
+ aside {
+ display: none;
+ }
+ }
+</style>