Узнайте, как можно добавить интернационализацию (i18n) в свое приложение Preact с помощью preact-i18n.
中 中文 中 (китайская версия): https://medium.com/@limhenry/how-to-add-i18n-to-preact-chinese-b49cfaf3a07b
Что такое интернационализация (i18n)?
Интернационализация - это проектирование и разработка содержания продукта, приложения или документа, которое позволяет легко локализовать его для целевой аудитории, которая различается по культуре, региону или языку.
В этой статье вы собираетесь использовать библиотеку preact-i18n
для добавления интернационализации в ваше приложение Preact.
Шаг 1. Настройка Preact CLI и создание нового проекта
Боковое примечание: если вы уже знакомы с Preact, вы можете перейти к следующему шагу.
Если вы не установили Preact CLI на свой компьютер, используйте следующую команду для установки CLI. Убедитесь, что у вас установлен Node.js 6.x или выше.
$ npm install -g preact-cli
После установки Preact CLI давайте создадим новый проект, используя default
template, и назовем его my-project
.
$ preact create default my-project
Запустите сервер разработки с помощью следующей команды:
$ cd my-project && npm run start
Теперь откройте свой браузер и перейдите в http://localhost:8080
, и вы должны увидеть что-то вроде этого на своем экране:
Шаг 2. Добавьте preact-i18n
библиотеку
Установите библиотеку preact-i18n
в свой проект, используя следующую команду:
$ npm install --save preact-i18n
preact-i18n
очень прост в использовании и, что наиболее важно, очень мал - около 1,3 КБ после сжатия с помощью gzip. Вы можете узнать больше о библиотеке здесь:
Шаг 3. Создайте файл определения
После того, как вы установили библиотеку, вам нужно будет создать файл определения, в котором вы будете хранить все строки перевода в файле JSON.
В этом случае вам нужно будет сохранить этот файл в src/i18n/zh-tw.json
:
{ "home": { "title": "主頁", "text": "這是個Home組件。" } }
Шаг 4. Импортируйте IntlProvider и файл определения
Затем откройте файл app.js
, который находится в папке src/components
. Затем импортируйте IntlProvider
и ваш definition
файл в app.js
file:
import { IntlProvider } from 'preact-i18n'; import definition from '../i18n/zh-tw.json';
Шаг 5. Разместите определение с помощью ‹IntlProvider›
После этого вам нужно будет открыть файл определения всему приложению через <IntlProvider>
. Сделав это, вы сможете читать файл определения повсюду в приложении.
render() { return( <IntlProvider definition={definition}> <div id="app" /> </IntlProvider> ); }
В настоящий момент ваш app.js
файл должен выглядеть следующим образом:
import { h, Component } from 'preact'; import { Router } from 'preact-router'; import Header from './header'; import Home from '../routes/home'; import Profile from '../routes/profile'; // Import IntlProvider and the definition file. import { IntlProvider } from 'preact-i18n'; import definition from '../i18n/zh-tw.json'; export default class App extends Component { handleRoute = e => { this.currentUrl = e.url; }; render() { return ( // Expose the definition to your whole app via <IntlProvider> <IntlProvider definition={definition}> <div id="app"> <Header /> <Router onChange={this.handleRoute}> <Home path="/" /> <Profile path="/profile/" user="me" /> <Profile path="/profile/:user" /> </Router> </div> </IntlProvider> ); } }
Шаг 6. Используйте ‹Text› для перевода строковых литералов
Вы почти закончили, теперь вам просто нужно заменить текст на странице на <Text>
. В этом случае вам нужно будет обновить содержимое домашней страницы (src/routes/home/index.js
), добавив <Text>
внутри тегов <h1>
и <p>
.
import { Text } from 'preact-i18n'; const Home = () => ( <div> <h1> <Text id="home.title">Home</Text> </h1> <p> <Text id="home.text">This is the Home component.</Text> </p> </div> ); export default Home;
Резервный текст
Чтобы предотвратить отображение пустого текста на странице, вы должны установить резервный текст на <Text>
. Если вы не включили определение для unknown.definition
, библиотека отобразит любой текст, содержащийся в <Text>…</Text>
, как резервный текст:
<Text id="unknown.definition">This is a fallback text.</Text> // It will render this text: "This is a fallback text."
‹Localizer› и ‹MarkupText›
Если вы хотите перевести текст значения атрибута HTML (например: placeholder=""
, title=""
и т. Д.), Вам нужно будет использовать <Localizer>
вместо <Text>
.
Однако, если вы хотите включить разметку HTML в отображаемую строку, вам нужно будет использовать <MarkupText>
. С помощью этого компонента ваш текст будет отображаться в теге <span>
.
В приведенном ниже примере вы собираетесь добавить еще несколько строк кода в свой файл определения. first_name
и last_name
будут использоваться для примера <Localizer>
, а link
- для примера для <MarkupText>
.
{ "first_name": "名", "last_name": "姓", "link": "這是個<a href='https://www.google.com'>連結</a>" }
При этом вы сможете использовать на странице <Localizer>
и <MarkupText>
. Обратите внимание, что вам необходимо импортировать Localizer
и MarkupText
в файл src/routes/home/index.js
.
import { Text, Localizer, MarkupText
} from 'preact-i18n';
const Home = () => (
<div>
<Localizer>
<input placeholder={<Text id="first_name" />} />
</Localizer>
<Localizer>
<input placeholder={<Text id="last_name" />} />
</Localizer>
<MarkupText id="link">
This is a <a href="https://www.google.com">link</a>
</MarkupText>
</div>
);
export default Home;
Шаблоны
Если вы хотите добавить в определение настраиваемую строку или значение, вы можете сделать это с помощью fields
props.
Во-первых, вам нужно обновить файл определения с помощью заполнителя {{field}}
. Заполнитель будет заменен согласованными ключами в объекте, который вы передали в fields
реквизитах.
{ "page": "{{count}} / {{total}} 頁" }
Затем вам нужно будет добавить атрибут fields
вместе со значением в <Text />
. В результате ваш код должен выглядеть так:
import { Text } from 'preact-i18n'; const Home = () => ( <div> <h2> <Text id="page" fields={{ count: 5, total: 10 }}> 5 / 10 Pages </Text> </h2> </div> ); export default Home;
Плюрализация
С preact-i18n
у вас есть 3 способа указать значения множественного числа:
"key": { "singular":"apple", "plural":"apples" }
"key": { "none":"no apples", "one":"apple", "many":"apples" }
"key": ["apples", "apple"]
В следующем примере вы объедините множественное число и шаблоны. Во-первых, вам нужно будет обновить файл определения с помощью приведенного ниже кода:
{ "apple": { "singular": "Henry has {{count}} apple.", "plural":"Henry has {{count}} apples." } }
Затем вы обновите домашнюю страницу (src/routes/home/index.js
) следующим кодом:
import { Text } from 'preact-i18n'; const Home = () => ( <div> <p> <Text id="apple" plural={1} fields={{ count: 1 }} /> </p> <p> <Text id="apple" plural={100} fields={{ count: 100 }} /> </p> </div> ); export default Home;
С помощью описанного выше метода вы сможете добавить плюрализацию и шаблоны в свое приложение Preact.
Динамически импортировать файл определения языка
В реальном сценарии вы хотели бы установить язык сайта на основе выбора пользователя, который либо основан на navigator.language
, либо пользователь может изменить язык сайта самостоятельно.
Однако, чтобы предотвратить импорт всех ненужных файлов определений в проект, вы можете динамически импортировать файл определения языка с помощью import()
. Сделав это, вы можете импортировать файл определения языка в зависимости от выбора пользователя.
import { Component } from 'preact'; import { IntlProvider } from 'preact-i18n'; import defaultDefinition from '../i18n/zh-tw.json'; export default class App extends Component { state = { definition: defaultDefinition } changeLanguage = (lang) => { // Call this function to change language import(`../i18n/${lang}.json`) .then(definition => this.setState({ definition })); }; render({ }, { definition }) { return ( <IntlProvider definition={definition}> <div id="app" /> </IntlProvider> ); } }
В этом случае вы можете вызвать функцию this.changeLanguage('zh-TW')
, чтобы изменить язык сайта.
Кто использует preact-i18n?
Я использую preact-i18n
для своего побочного проекта: Remote for Slides.
Remote for Slides - это прогрессивное веб-приложение + расширение Chrome, которое позволяет пользователю управлять своими слайдами Google на любом устройстве удаленно, без необходимости в дополнительном оборудовании.
Прогрессивное веб-приложение Remote for Slides поддерживает более 8 языков, в том числе: катала, английский, испанский, европейский, французский, польский, традиционный китайский и упрощенный китайский.
В этом побочном проекте я использую метод «динамического импорта файла определения языка», о котором я упоминал ранее. Это может помешать веб-приложению загрузить ненужный файл языка определений, что повысит производительность страницы.
Кроме того, прогрессивное веб-приложение Remote for Slides установит язык в зависимости от языка браузера (navigator.language
) или параметра URL (например, s.limhenry.xyz/?hl=zh-tw
), либо пользователь может изменить его на странице настроек.
Вы можете узнать больше о Remote for Slides здесь: