Интернационализация универсальных приложений

Занятие 15

Профессия
Node.js & React.js developer
продвинутый курс

  • Интернационализация
  • Component-like паттерн для шаблонизации

План

1

Интернационализация

Наследование и модульная архитектура

Что такое Интернационализация

  1. Internationalization (i18n)

  2. Localization (l10n)

  3. Globalization (g11n)

  4. Localizability (l12y)

 Кому может быть полезно

  1. Приложения с множественными языками
  2. Приложения с 1 языком, и отдельной командой копиратеров
  3. Несколько программистов на проекте, и только 1 отвечает за тексты

 i18n - это как MVC

MVC - внутри отображений, где

 

V - это текст шаблона
 C - это место, где вызывается шаблон

M - функция интерполяции

Вывод:
Онлайн 26 пользователей

Шаблоны:
{
  'online_1': 'Онлайн {{count}} пользователь',
  'online_2': 'Онлайн {{count}} пользователя',
  'online_3': 'Онлайн {{count}} пользователей'
}
render():

<div>
  {t('online', { count: users.length })}
</div>

Своими руками

function t(key) {
  const maps = {
    'users': 'пользователи',
    'slides': 'слайды',
  }
  return maps[key] || key;
}
  1. поддержка нескольких языков
  2. хранение ключей в файлах (чанки)
  3. асинхронное подгрузка ключей
  4. интерполяция (шаблонизация)
  5. вложенные ключи: page1.slide2.subtitle
  6. специфичные правила для некоторых языков
  7. fallback в случае отсутствия ключа в языке

Инфрастуктура для переводов

  1. Таблица с переводами
  2. Утилита экспорта переводов
  3. Оповещения при двойном использовании ключа
  4. Оповещение при использовании отсутствующего ключа

Приоритеты локалей

  1. Ищем локаль в параметрах GET
  2. Ищем локаль, в профиле пользователя
  3. Ищем локаль в куках и сторах
  4. Ищем локаль в запросе (браузер)
  5. Берем локаль по умолчанию

Сложности

Переводы должны работать

  1. В роутерах Express
  2. В компонентах React
  3. В браузере без uapp
  4. На сервере без req
  5. В персональных оповещениях (емейлах)

Реализация на сервере

{
   console.log(this.t('errors.lowMemory'));
}

{
   this.tbot.notify(ctx.t('errors.lowMemory'));
}

Реализация в роутерах

async (req) {

   return {
     ...,
     message: req.t('hello.world'),
   }
}

async (req) {
  throw req.t('errors.lowMemory');
}

Реализация в uapp

getLocale

Реализация в uapp

 

@inject('t')
@importcss(require('./AuthPage.css'))
export class SocialButton extends Component {
  render() {
    const { name, t } = this.props;
    const value = buttons[name];
    return (
      <Button {...this.props} styleName="button" block>
        <span styleName="icon" style={{ color: value.color }}>{value.icon}</span>
        <span styleName="title">{t('auth.signInWith', { name: value.title })}</span>
      </Button>
    );
  }
}

Советы

1. Прокидывайте сложные объекты, вложенность решайте в интерполяции

<div>

{t('welcome', {  name: user.name, company: user.profile.company, phone: user.profile.contacts.phone })}

vs

{t('welcome', { user })}

</div>

Советы

2. Дублируйте переводы все в экселе

<div>

{t('page1.welcome', { user })}

{t('page2.welcome', { user })}

</div>

3. лучше сразу прокинуть переводы и потом перевести

Скоро в lsk-example2

2

Component-like

паттерн для шаблонизации

3

Оффтоп

или как программитам живется на Кипре

Игорь Суворов

Thanks!

any questions?

программист-предприниматель

Интернационализация универсальных приложений

By Igor Suvorov

Интернационализация универсальных приложений

  • 1,018