mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-04-20 14:56:17 -04:00
chore(i18n): tool scoped locales (#471)
This commit is contained in:
parent
ec4c533718
commit
1b038c7826
6 changed files with 35 additions and 45 deletions
|
@ -1,3 +1,4 @@
|
||||||
home:
|
home:
|
||||||
categories:
|
categories:
|
||||||
newestTools: "Newest tools"
|
newestTools: Newest tools
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,11 @@ const head = computed<HeadObject>(() => ({
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
useHead(head);
|
useHead(head);
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const i18nKey = computed<string>(() => route.path.trim().replace('/', ''));
|
||||||
|
const toolTitle = computed<string>(() => t(`tools.${i18nKey.value}.title`, String(route.meta.name)));
|
||||||
|
const toolDescription = computed<string>(() => t(`tools.${i18nKey.value}.description`, String(route.meta.description)));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -31,7 +36,7 @@ useHead(head);
|
||||||
<div class="tool-header">
|
<div class="tool-header">
|
||||||
<div flex flex-nowrap items-center justify-between>
|
<div flex flex-nowrap items-center justify-between>
|
||||||
<n-h1>
|
<n-h1>
|
||||||
{{ route.meta.name }}
|
{{ toolTitle }}
|
||||||
</n-h1>
|
</n-h1>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
@ -42,7 +47,7 @@ useHead(head);
|
||||||
<div class="separator" />
|
<div class="separator" />
|
||||||
|
|
||||||
<div class="description">
|
<div class="description">
|
||||||
{{ route.meta.description }}
|
{{ toolDescription }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,50 +1,15 @@
|
||||||
import type { App } from 'vue';
|
import type { App } from 'vue';
|
||||||
import { createI18n } from 'vue-i18n';
|
import { createI18n } from 'vue-i18n';
|
||||||
import type { Locale } from 'vue-i18n';
|
import messages from '@intlify/unplugin-vue-i18n/messages';
|
||||||
|
|
||||||
const i18n = createI18n({
|
const i18n = createI18n({
|
||||||
legacy: false,
|
legacy: false,
|
||||||
locale: '',
|
locale: 'en',
|
||||||
messages: {},
|
messages,
|
||||||
});
|
});
|
||||||
|
|
||||||
const localesMap = Object.fromEntries(
|
|
||||||
Object.entries(import.meta.glob('../../locales/*.yml'))
|
|
||||||
.map(([path, loadLocale]) => [path.match(/([\w-]*)\.yml$/)?.[1], loadLocale]),
|
|
||||||
) as Record<Locale, () => Promise<{ default: Record<string, string> }>>;
|
|
||||||
|
|
||||||
export const availableLocales = Object.keys(localesMap);
|
|
||||||
|
|
||||||
const loadedLanguages: string[] = [];
|
|
||||||
|
|
||||||
function setI18nLanguage(lang: Locale) {
|
|
||||||
i18n.global.locale.value = lang as any;
|
|
||||||
if (typeof document !== 'undefined') {
|
|
||||||
document.querySelector('html')?.setAttribute('lang', lang);
|
|
||||||
}
|
|
||||||
return lang;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function loadLanguageAsync(lang: string): Promise<Locale> {
|
|
||||||
if (i18n.global.locale.value === lang) {
|
|
||||||
return setI18nLanguage(lang);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loadedLanguages.includes(lang)) {
|
|
||||||
return setI18nLanguage(lang);
|
|
||||||
}
|
|
||||||
|
|
||||||
const messages = await localesMap[lang]();
|
|
||||||
|
|
||||||
i18n.global.setLocaleMessage(lang, messages.default);
|
|
||||||
loadedLanguages.push(lang);
|
|
||||||
|
|
||||||
return setI18nLanguage(lang);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const i18nPlugin = {
|
export const i18nPlugin = {
|
||||||
install: (app: App) => {
|
install: (app: App) => {
|
||||||
app.use(i18n);
|
app.use(i18n);
|
||||||
loadLanguageAsync('en');
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
9
src/tools/token-generator/locales/en.yml
Normal file
9
src/tools/token-generator/locales/en.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
tools:
|
||||||
|
token-generator:
|
||||||
|
title: Token generator
|
||||||
|
description: Generate random string with the chars you want, uppercase or lowercase letters, numbers and/or symbols.
|
||||||
|
|
||||||
|
uppercase: Uppercase (ABC...)
|
||||||
|
lowercase: Lowercase (abc...)
|
||||||
|
numbers: Numbers (123...)
|
||||||
|
symbols: Symbols (!-;...)
|
9
src/tools/token-generator/locales/fr.yml
Normal file
9
src/tools/token-generator/locales/fr.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
tools:
|
||||||
|
token-generator:
|
||||||
|
title: Générateur de token
|
||||||
|
description: Génère une chaîne aléatoire avec les caractères que vous voulez, lettres majuscules ou minuscules, chiffres et/ou symboles.
|
||||||
|
|
||||||
|
uppercase: Majuscules (ABC...)
|
||||||
|
lowercase: Minuscules (abc...)
|
||||||
|
numbers: Chiffres (123...)
|
||||||
|
symbols: Symboles (!-;...)
|
|
@ -9,6 +9,7 @@ const withUppercase = useQueryParam({ name: 'uppercase', defaultValue: true });
|
||||||
const withLowercase = useQueryParam({ name: 'lowercase', defaultValue: true });
|
const withLowercase = useQueryParam({ name: 'lowercase', defaultValue: true });
|
||||||
const withNumbers = useQueryParam({ name: 'numbers', defaultValue: true });
|
const withNumbers = useQueryParam({ name: 'numbers', defaultValue: true });
|
||||||
const withSymbols = useQueryParam({ name: 'symbols', defaultValue: false });
|
const withSymbols = useQueryParam({ name: 'symbols', defaultValue: false });
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
const [token, refreshToken] = computedRefreshable(() =>
|
const [token, refreshToken] = computedRefreshable(() =>
|
||||||
createToken({
|
createToken({
|
||||||
|
@ -29,21 +30,21 @@ const { copy } = useCopy({ source: token, text: 'Token copied to the clipboard'
|
||||||
<n-form label-placement="left" label-width="140">
|
<n-form label-placement="left" label-width="140">
|
||||||
<div flex justify-center>
|
<div flex justify-center>
|
||||||
<div>
|
<div>
|
||||||
<n-form-item label="Uppercase (ABC...)">
|
<n-form-item :label="t('tools.token-generator.uppercase')">
|
||||||
<n-switch v-model:value="withUppercase" />
|
<n-switch v-model:value="withUppercase" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
|
||||||
<n-form-item label="Lowercase (abc...)">
|
<n-form-item :label="t('tools.token-generator.lowercase')">
|
||||||
<n-switch v-model:value="withLowercase" />
|
<n-switch v-model:value="withLowercase" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<n-form-item label="Numbers (012...)">
|
<n-form-item :label="t('tools.token-generator.numbers')">
|
||||||
<n-switch v-model:value="withNumbers" />
|
<n-switch v-model:value="withNumbers" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
|
||||||
<n-form-item label="Symbols (;-!...)">
|
<n-form-item :label="t('tools.token-generator.symbols')">
|
||||||
<n-switch v-model:value="withSymbols" />
|
<n-switch v-model:value="withSymbols" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue