chore(i18n): refactor and cleanup ()

* checkpoint

* finish

* docs
This commit is contained in:
Jacky Zhao 2024-02-04 20:57:10 -08:00 committed by GitHub
parent dff4b06313
commit 36e4cc41a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 326 additions and 211 deletions

View file

@ -1,37 +0,0 @@
import en from "./locales/en.json"
import fr from "./locales/fr.json"
const TRANSLATION = {
"en-US": en,
"fr-FR": fr,
} as const
type TranslationOptions = {
[key: string]: string
}
export const i18n = (lang = "en-US", key: string, options?: TranslationOptions) => {
const locale =
Object.keys(TRANSLATION).find(
(key) =>
key.toLowerCase() === lang.toLowerCase() || key.toLowerCase().includes(lang.toLowerCase()),
) ?? "en-US"
const getTranslation = (key: string) => {
const keys = key.split(".")
let translationString: string | Record<string, unknown> =
TRANSLATION[locale as keyof typeof TRANSLATION]
keys.forEach((key) => {
// @ts-ignore
translationString = translationString[key]
})
return translationString
}
if (options) {
let translationString = getTranslation(key).toString()
Object.keys(options).forEach((key) => {
translationString = translationString.replace(`{{${key}}}`, options[key])
})
return translationString
}
return getTranslation(key).toString()
}

11
quartz/i18n/index.ts Normal file
View file

@ -0,0 +1,11 @@
import { Translation } from "./locales/definition"
import en from "./locales/en-US"
import fr from "./locales/fr-FR"
export const TRANSLATIONS = {
"en-US": en,
"fr-FR": fr,
} as const
export const i18n = (locale: ValidLocale): Translation => TRANSLATIONS[locale]
export type ValidLocale = keyof typeof TRANSLATIONS

View file

@ -0,0 +1,63 @@
import { FullSlug } from "../../util/path"
export interface Translation {
propertyDefaults: {
title: string
description: string
}
components: {
backlinks: {
title: string
noBacklinksFound: string
}
themeToggle: {
lightMode: string
darkMode: string
}
explorer: {
title: string
}
footer: {
createdWith: string
}
graph: {
title: string
}
recentNotes: {
title: string
seeRemainingMore: (variables: { remaining: number }) => string
}
transcludes: {
transcludeOf: (variables: { targetSlug: FullSlug }) => string
linkToOriginal: string
}
search: {
title: string
searchBarPlaceholder: string
}
tableOfContents: {
title: string
}
}
pages: {
rss: {
recentNotes: string
lastFewNotes: (variables: { count: number }) => string
}
error: {
title: string
notFound: string
}
folderContent: {
folder: string
itemsUnderFolder: (variables: { count: number }) => string
}
tagContent: {
tag: string
tagIndex: string
itemsUnderTag: (variables: { count: number }) => string
showingFirst: (variables: { count: number }) => string
totalTags: (variables: { count: number }) => string
}
}
}

View file

@ -0,0 +1,65 @@
import { Translation } from "./definition"
export default {
propertyDefaults: {
title: "Untitled",
description: "No description provided",
},
components: {
backlinks: {
title: "Backlinks",
noBacklinksFound: "No backlinks found",
},
themeToggle: {
lightMode: "Light mode",
darkMode: "Dark mode",
},
explorer: {
title: "Explorer",
},
footer: {
createdWith: "Created with",
},
graph: {
title: "Graph View",
},
recentNotes: {
title: "Recent Notes",
seeRemainingMore: ({ remaining }) => `See ${remaining} more →`,
},
transcludes: {
transcludeOf: ({ targetSlug }) => `Transclude of ${targetSlug}`,
linkToOriginal: "Link to original",
},
search: {
title: "Search",
searchBarPlaceholder: "Search for something",
},
tableOfContents: {
title: "Table of Contents",
},
},
pages: {
rss: {
recentNotes: "Recent notes",
lastFewNotes: ({ count }) => `Last ${count} notes`,
},
error: {
title: "Not Found",
notFound: "Either this page is private or doesn't exist.",
},
folderContent: {
folder: "Folder",
itemsUnderFolder: ({ count }) =>
count === 1 ? "1 item under this folder" : `${count} items under this folder.`,
},
tagContent: {
tag: "Tag",
tagIndex: "Tag Index",
itemsUnderTag: ({ count }) =>
count === 1 ? "1 item with this tag" : `${count} items with this tag.`,
showingFirst: ({ count }) => `Showing first ${count} tags.`,
totalTags: ({ count }) => `Found ${count} total tags.`,
},
},
} as const satisfies Translation

View file

@ -1,37 +0,0 @@
{
"404": "Either this page is private or doesn't exist.",
"backlinks": {
"backlinks": "Backlinks",
"noBacklinksFound": "No backlinks found"
},
"common": {
"item": "item"
},
"darkmode": {
"lightMode": "Light mode"
},
"folderContent": {
"underThisFolder": "under this folder"
},
"footer": {
"createdWith": "Created with"
},
"graph": {
"graphView": "Graph View"
},
"head": {
"noDescriptionProvided": "No description provided",
"untitled": "Untitled"
},
"recentNotes": {
"seeRemainingMore": "See {{remaining}} more"
},
"search": "Search",
"tableOfContent": "Table of Contents",
"tagContent": {
"showingFirst": "Showing first",
"totalTags": "total tags",
"withThisTag": "with this tag",
"found": "Found"
}
}

View file

@ -0,0 +1,65 @@
import { Translation } from "./definition"
export default {
propertyDefaults: {
title: "Sans titre",
description: "Aucune description fournie",
},
components: {
backlinks: {
title: "Liens retour",
noBacklinksFound: "Aucun lien retour trouvé",
},
themeToggle: {
lightMode: "Mode clair",
darkMode: "Mode sombre",
},
explorer: {
title: "Explorateur",
},
footer: {
createdWith: "Créé avec",
},
graph: {
title: "Vue Graphique",
},
recentNotes: {
title: "Notes Récentes",
seeRemainingMore: ({ remaining }) => `Voir ${remaining} de plus →`,
},
transcludes: {
transcludeOf: ({ targetSlug }) => `Transclusion de ${targetSlug}`,
linkToOriginal: "Lien vers l'original",
},
search: {
title: "Recherche",
searchBarPlaceholder: "Rechercher quelque chose",
},
tableOfContents: {
title: "Table des Matières",
},
},
pages: {
rss: {
recentNotes: "Notes récentes",
lastFewNotes: ({ count }) => `Les dernières ${count} notes`,
},
error: {
title: "Pas trouvé",
notFound: "Cette page est soit privée, soit elle n'existe pas.",
},
folderContent: {
folder: "Dossier",
itemsUnderFolder: ({ count }) =>
count === 1 ? "1 élément sous ce dossier" : `${count} éléments sous ce dossier.`,
},
tagContent: {
tag: "Étiquette",
tagIndex: "Index des étiquettes",
itemsUnderTag: ({ count }) =>
count === 1 ? "1 élément avec cette étiquette" : `${count} éléments avec cette étiquette.`,
showingFirst: ({ count }) => `Affichage des premières ${count} étiquettes.`,
totalTags: ({ count }) => `Trouvé ${count} étiquettes au total.`,
},
},
} as const satisfies Translation

View file

@ -1,38 +0,0 @@
{
"404": "Soit cette page est privée, soit elle n'existe pas.",
"backlinks": {
"backlinks": "Rétroliens",
"noBacklinksFound": "Aucun rétrolien trouvé"
},
"common": {
"item": "fichier"
},
"darkmode": {
"darkmode": "Thème sombre",
"lightMode": "Thème clair"
},
"folderContent": {
"underThisFolder": "dans ce dossier"
},
"footer": {
"createdWith": "Créé avec"
},
"graph": {
"graphView": "Vue Graphique"
},
"head": {
"noDescriptionProvided": "Aucune description n'a été fournie",
"untitled": "Sans titre"
},
"recentNotes": {
"seeRemainingMore": "Voir {{remaining}} plus"
},
"search": "Rechercher",
"tableOfContent": "Table des Matières",
"tagContent": {
"showingFirst": "Afficher en premier",
"totalTags": "tags totaux",
"withThisTag": "avec ce tag",
"found": "Trouvé"
}
}