Быстрый способ настроить i18n для компонентов Stencil без зависимостей.
Я использовал ту же стратегию для быстрой интернационализации компонентов Stencil без зависимостей в различных проектах. В том числе для проекта Owlly или Bonjour Foundation.
Поскольку все эти проекты имеют открытый код, я поделюсь с вами своим рецептом 🧑🍳.
Цель
Я недавно с помощью сообщества интернационализировал наш проект DeckDeckGo, но цель этой статьи - добавить переводы к относительно небольшому компоненту или набору компонентов без зависимости.
Я использую это решение, когда создаю компоненты, которые содержат несколько slot
со значениями по умолчанию и которые имеют основной рынок нашей прекрасной «четыре языка + английский по умолчанию» в Швейцарии 🇨🇭.
Настраивать
В вашем проекте создайте новую утилиту translations.util.ts
и добавьте объявления.
interface Translation { [key: string]: string; } interface Translations { de: Translation; en: Translation; }
В этом примере я буду использовать «только» немецкий и английский языки. Для практического использования дополните его своими требованиями.
Я объявил interface Translation
, но его можно заменить на TypeScript Record<string, string>
. Результат такой же, как вам больше нравится.
После объявлений добавьте константу для языка по умолчанию (запасного) и список поддерживаемых языков.
const DEFAULT_LANGUAGE: 'en' = 'en'; const SUPPORTED_LANGUAGES: string[] = ['de', 'en'];
Наконец, добавьте эффективные переводы.
const TRANSLATIONS: Translations = { de: { question: 'Wie fühlen Sie sich heute?', super: 'Sehr gut', bad: 'Nicht gut' }, en: { question: 'How do you feel today?', super: 'Super', bad: 'Bad' } };
В этом решении, поскольку моя цель - сделать его быстрым и простым, я кодирую переводы.
Их можно обрабатывать в отдельных json
файлах и import
динамически во время выполнения. Эти две функции я разработал для более сложного случая использования. В конце концов, мне действительно может понадобиться написать об этом в блоге? Напишите мне, если вы думаете, что это будет интересная тема!
Определить языки
Я не изобретал велосипед. Я взглянул на широко используемую библиотеку с открытым исходным кодом ngx-translate и реализовал ее определение языков браузера.
В том же файле добавьте следующую функцию и инициализацию языка по умолчанию.
const initBrowserLang = (): string | undefined => { if (typeof window === 'undefined' || typeof window.navigator === 'undefined') { return undefined; } let browserLang: string | null = window.navigator.languages && window.navigator.languages.length > 0 ? window.navigator.languages[0] : null; // @ts-ignore browserLang = browserLang || window.navigator.language || window.navigator.browserLanguage || window.navigator.userLanguage; if (typeof browserLang === 'undefined') { return undefined; } if (browserLang.indexOf('-') !== -1) { browserLang = browserLang.split('-')[0]; } if (browserLang.indexOf('_') !== -1) { browserLang = browserLang.split('_')[0]; } return browserLang; } const browserLang: string | undefined = initBrowserLang();
Функция
Настройка и обнаружение готовы, нам нужна функция для рендеринга переводов.
export const translate = (key: string, customLang?: 'de' | 'en'): string => { const lang: string | undefined = customLang || browserLang; return TRANSLATIONS[lang !== undefined && SUPPORTED_LANGUAGES.includes(lang) ? lang : DEFAULT_LANGUAGE][key]; };
Он либо использует браузер, либо язык параметров, сравнивает его со списком поддерживаемых языков или возвращается к языку по умолчанию и возвращает соответствующие переводы.
использование
В нашем компоненте указанная выше функция может использоваться для рендеринга перевода.
import {Component, h, Host} from '@stencil/core'; import {translate} from './translations.utils'; @Component({ tag: 'question', shadow: true }) export class Question { render() { return <Host> <p>{translate('question')}</p> <slot name="answer">{translate('super', 'de')}</slot> </Host>; } }
Он отображает текст с указанием языка или без него, а также может использоваться с slot
.
Резюме
Это был мой небольшой быстрый рецепт по настройке i18n на относительно небольшой набор компонентов. Я надеюсь, что это будет полезно, и если вы думаете, что мне стоит поделиться более сложным решением в другом посте, дайте мне знать.
Бесконечность не предел!
Дэйвид
Вы можете связаться со мной в Твиттере или на моем сайте.
Попробуйте DeckDeckGo для следующих слайдов 🤟.