(nuxt) dynamically load translations.suml for Translator

This commit is contained in:
Valentyne Stigloher 2025-01-18 01:11:12 +01:00
parent 41b4d6d668
commit 065aa2ae42
2 changed files with 64 additions and 55 deletions

View File

@ -3,15 +3,7 @@ import { defineNuxtPlugin, useCookie, useRouter } from 'nuxt/app';
import type { Pinia } from 'pinia';
import { decodeTime } from 'ulid';
import config from '../data/config.suml';
import translations from '../data/translations.suml';
import baseTranslations from '../locale/_base/translations.suml';
import type { LocaleDescription } from '../locale/locales.ts';
import buildLocaleList from '../src/buildLocaleList.ts';
import type { Pronoun } from '../src/classes.ts';
import { LoadScriptError } from '../src/errors.ts';
import { buildDict } from '../src/helpers.ts';
import { Translator } from '../src/translator.ts';
import { useMainStore } from '../store/index.ts';
declare global {
@ -22,11 +14,6 @@ declare global {
declare module '#app' {
interface NuxtApp {
$translator: Translator;
$t<T extends string | string[] = string>(key: string, params?: Record<string, string | number>, warn?: boolean): NoInfer<T>;
$te(key: string, fallback?: boolean): boolean;
$translateForPronoun(str: string, pronoun: Pronoun | null): string;
$locales: Record<string, LocaleDescription>;
$loadScript(name: string, src: string, nonce?: string, target?: string): Promise<void>;
$loadStylesheet(name: string, src: string): Promise<void>;
$datetime(timestamp: number): string;
@ -37,11 +24,6 @@ declare module '#app' {
declare module 'vue' {
interface ComponentCustomProperties {
$translator: Translator;
$t<T extends string | string[] = string>(key: string, params?: Record<string, string | number>, warn?: boolean): NoInfer<T>;
$te(key: string, fallback?: boolean): boolean;
$translateForPronoun(str: string, pronoun: Pronoun | null): string;
$locales: Record<string, LocaleDescription>;
$loadScript(name: string, src: string, nonce?: string, target?: string): Promise<void>;
$loadStylesheet(name: string, src: string): Promise<void>;
$datetime(timestamp: number): string;
@ -51,37 +33,6 @@ declare module 'vue' {
}
export default defineNuxtPlugin((nuxtApp) => {
const translator = new Translator(translations, baseTranslations, config);
const t = (key: string, params = {}, warn = false): string => translator.translate(key, params, warn);
const te = (key: string, fallback = false): boolean => {
if (translator.has(key)) {
return true;
}
if (fallback && translator.hasFallback(key)) {
return true;
}
return false;
};
const translateForPronoun = (str: string, pronoun: Pronoun | null): string => {
let translation = translator.translate(`flags.${str.replace(/ /g, '_').replace(/'/g, '*')}`, {}, false) || str;
if (pronoun) {
translation = pronoun.format(translation);
}
return translation;
};
const locales = buildDict(function* () {
const locales = buildLocaleList(config.locale);
if (config.locale !== '_') {
yield [config.locale, locales[config.locale]];
}
for (const [locale, localeDescription] of Object.entries(locales)) {
if (locale !== config.locale) {
yield [locale, localeDescription];
}
}
});
const store = useMainStore(nuxtApp.$pinia as Pinia);
const spellingCookie = useCookie('spelling');
store.setSpelling(spellingCookie.value ?? null);
@ -208,11 +159,6 @@ export default defineNuxtPlugin((nuxtApp) => {
return {
provide: {
translator,
t,
te,
translateForPronoun,
locales,
loadScript,
loadStylesheet,
datetime,

View File

@ -1,11 +1,74 @@
import baseTranslations from '~/locale/_base/translations.suml';
import type { Translations } from '~/locale/translations.ts';
import buildLocaleList from '~/src/buildLocaleList.ts';
import type { Pronoun } from '~/src/classes.ts';
import { buildDict } from '~/src/helpers.ts';
import { Translator } from '~/src/translator.ts';
declare module '#app' {
interface NuxtApp {
$t<T extends string | string[] = string>
(key: string, params?: Record<string, string | number>, warn?: boolean): NoInfer<T>;
}
}
declare module 'vue' {
interface ComponentCustomProperties {
$t<T extends string | string[] = string>
(key: string, params?: Record<string, string | number>, warn?: boolean): NoInfer<T>;
}
}
const loadTranslations = async (): Promise<Translations> => {
const runtimeConfig = useRuntimeConfig();
return (await import(`~/locale/${runtimeConfig.public.locale}/translations.suml`)).default;
};
export default defineNuxtPlugin({
enforce: 'pre',
async setup() {
const config = await loadConfig();
const [config, translations] = await Promise.all([loadConfig(), loadTranslations()]);
const translator = new Translator(translations, baseTranslations, config);
const t = (key: string, params = {}, warn = false): string => translator.translate(key, params, warn);
const te = (key: string, fallback = false): boolean => {
if (translator.has(key)) {
return true;
}
if (fallback && translator.hasFallback(key)) {
return true;
}
return false;
};
const translateForPronoun = (str: string, pronoun: Pronoun | null): string => {
let translation = translator.translate(`flags.${str.replace(/ /g, '_').replace(/'/g, '*')}`, {}, false) || str;
if (pronoun) {
translation = pronoun.format(translation);
}
return translation;
};
const locales = buildDict(function* () {
const locales = buildLocaleList(config.locale);
if (config.locale !== '_') {
yield [config.locale, locales[config.locale]];
}
for (const [locale, localeDescription] of Object.entries(locales)) {
if (locale !== config.locale) {
yield [locale, localeDescription];
}
}
});
return {
provide: {
// identifier must be different to config because it is already reserved for Nuxt runtime config
localeConfig: config,
translator,
t,
te,
translateForPronoun,
locales,
},
};
},