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

Internationalization is one of the core features of CMintS. The idea behind is to use common structure and syntax in content pages, themes and provide additional helpers for multilanguage website management.

Структура директории locales

Locale files should be located in the locales directory:

locales
├── de
│   ├── about.json
│   └── news.json
├── en
│   ├── about.json
│   ├── header.json
│   └── news.json
└── ru
    ├── about
    │   └── team.json
    ├── about.json
    ├── documentation
    │   ├── getting-started
    │   │   └── configuration.json
    │   └── i18n
    │       └── index.json
    ├── header.json
    ├── index.json
    └── news.json

Каталоги верхнего уровня в locales являются кодами локали(locale). Структура каталогов отражает путь к странице, например, переводы для about/teams.md страницы должны быть расположен в файле /de/about/teams.json, чтобы быть доступным через путь /de/about/teams сайта

Default locale

Before strating to use i18n features user needs to also specify default locale which will be used as the source language. In order to do that, defaultLocale needs to be added to i18n options in the config.js:

const i18nOptions = {
  defaultLocale: "en"
};

module.exports = {i18nOptions};

Файл локалей

Файлы локалей содержат список переводимых строк, строки перевода состоят из stringid, сообщения и необязательного описания.

{
  "heading-main": {
    "description": "Heading of the main page",
    "message": "Заголовок"
  },
  ...
}

Строки перевода

Строки перевода могут быть определены в исходных файлах, помещая их внутри открывающих и закрывающих фигурных скобок. Строка перевода состоит из stringId, необязательное описание и исходный текст

{stringId[Description] Source text}

Например, рассмотрим локаль ru в Локальном файле и строку перевода ниже:

{heading-main[Heading of the main page] Heading}

Будут преобразованы в Heading для языка по умолчанию и в Заголовок для русского языка.

Определение пути

Чтобы использовать строку перевода из определенного пути, а не определять исходного текста в содержимом страницы, можно определить путь к файлу рядом с stringID:

{menu-item-about(menu/header)}

Вышеприведенное выражение означает использование строки с идентификатором menu-item-about из файла %locale%/menu/header.json:

/* /en/menu/header.json */
{
  "menu-item-about": {
    "description": "Menu item label",
    "message": "about us"
  }
}
/* /ru/menu/header.json */
{
  "menu-item-about": {
    "description": "Menu item label",
    "message": "о нас"
  }
}
// Translation expression
{menu-item-about(menu/header)}

Учитывая en и ru языков выше, перевод выражения будут преобразованы в about us для en языка и о нас для ru локали.

Использование тегов

Текущие теги a, img, p, span, div, em, i, b, strong могут использоваться по умолчанию в переводе строки, на пример:

{stringId[Description] My awesome <em>source text</em> goes here}

<a>

When a relative URL is used with starting / path locale and hreflang attributes are being generated automatically depending on the target page language regardless whether <a> tag is declared inside or outside of a translation string. root configuration can be used for specifing root directory for the website if needed.

Порядок ссылок внутри строк перевода может быть различным в зависимости на языке, поэтому порядок в строке файла языкового стандарта должен быть , поэтому рассмотрим строку перевода ниже:

{paragraph-1 This is <a href="https://www.example1.com">first link</a>, <a href="/random1">second link</a> and <a href="/random2">third link</a>}

И файл Locale со строкой перевода

{
 "paragraph-1": {
   "description": "Paragraph with several links",
   "message": "Это <a2>вторая ссылка</a2>, <a1>первая</a1> и <a3>третья ссылка</a3>"
 },
 ...
}

Результат будет:

Это <a href="/en/random1" hreflang="en">вторая ссылка</a>, <a href="https://www.example1.com">первая</a> и <a href="/en/random2" hreflang="en">третья ссылка</a>

<fix>

Некоторые слова не надо переводить на веб-сайте (например, название бренда), для этого можно использовать тег <fix>:

{fixed-id <fix>CMintS</fix> uses <fix>fix</fix> tag}

и локали ниже:

"fixed-id": {
 "message": "<fix2> тэг используется <fix1>-ом"
}

Получится:

fix тэг используется CMintS-ом

<img>

Подобно тегам <a> и <fix> тег <img> также должен сохранять порядок в строках перевода:

{test-img1 This is <img href="/first.png"> and <img href="/second.png"> image}

и локали ниже:

"test-img1": {
   "description": "Test images order",
   "message": "Это <img2> картинка и <img1>"
}

Получится:

Это <img href="/second.png"> картинка и <img href="/first.png">

атрибуты title и alt

Некоторые атрибуты также должны быть переведены на разные языки, поэтому эти атрибуты также могут использоваться в тегах строки перевода:

{test-attribute1 <div title="Website Logo" id="logo"><img src="/random/path" alt="Jumping puma" />Picture</div>}

и локали ниже:

"test-img1": {
   "description": "Test images order",
   "message": "<div1 title='Логотип сайта'><img1 alt='Пума в прыжке'>Картинка</div1>"
}

Получится:

<div title="Логотип сайта" id="logo"><img src="/random/path" alt="Пума в прыжке" />Картинка</div>

prefix, postfix

It's also possible to specify custom prefix and postfix for i18n strings in the config.js, it can be useful for fixing incompatibilities with other syntaxes:

Consider:

/* config.js */

const i18nOptions = {
  defaultLocale: "en",
  prefix: "{{",
  postfix: "}}"
};

module.exports = {i18nOptions};

For the configuration specified above, you could use the syntax below:

{{stringId[Description] Source text}}