Internationalization
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 directory structure
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
Top level directories in the locales
are the locale codes.
Actual directory structure reflects the page path, so for example translations
for the about/teams.md
page translations
should be located in /de/about/teams.json
file to be accessible
through /de/about/teams
website path.
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};
Locale file
Locale files hold list of the translations strings, the translation strings consist of stringid, message and optional description.
{
"heading-main": {
"description": "Heading of the main page",
"message": "Заголовок"
},
...
}
Translation strings
The translation strings can be defined in the source files by placing them inside of opening and closing curly braces. Translation string consist of stringId, optional description and source text:
{stringId[Description] Source text}
So for example considering the ru locale in Locale file and translation string below:
{heading-main[Heading of the main page] Heading}
Will be converted to Heading
for the source(default) locale and to
Заголовок
for the russian locale.
Defining the path
In order to use translation string from a specific path rather than defining source text in the page content, it's possible to define the file path next to the stringID:
{menu-item-about(menu/header)}
The expression above means - use string with the ID menu-item-about
from the %locale%/menu/header.json
files:
/* /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)}
Considering the en and ru locales above, the
translation expression will be converted to about us
for the
en locale and to the о нас
for the ru
locale.
Using tags
Current tags a, img, p, span, div, em, i, b, strong
can be used by
default in the translation strings, ex:
{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.
Order of the links inside of the translaton strings can be different depending on the language, for that reason the order in the locale file string need to be defined, so considering the translation string below:
{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>}
And Locale file with the translation string:
{
"paragraph-1": {
"description": "Paragraph with several links",
"message": "Это <a2>вторая ссылка</a2>, <a1>первая</a1> и <a3>третья ссылка</a3>"
},
...
}
The result will be the one below:
Это <a href="/en/random1" hreflang="en">вторая ссылка</a>, <a href="https://www.example1.com">первая</a> и <a href="/en/random2" hreflang="en">третья ссылка</a>
<fix>
Some words do not suppose to be translated in the website(ex: brand names), for
that reason <fix>
tag can be used:
{fixed-id <fix>CMintS</fix> uses <fix>fix</fix> tag}
and the locales below:
"fixed-id": {
"message": "<fix2> тэг используется <fix1>-ом"
}
Will result into:
fix тэг используется CMintS-ом
<img>
Similar to the <a>
and <fix>
tags <img>
tag also should keep it's order in the translation strings, so for:
{test-img1 This is <img href="/first.png"> and <img href="/second.png"> image}
and the locales below:
"test-img1": {
"description": "Test images order",
"message": "Это <img2> картинка и <img1>"
}
will result into:
Это <img href="/second.png"> картинка и <img href="/first.png">
title and alt attributes
Some attributes are also suppose to be translated in different languages, so that attributes can also be used in the translation string tags:
{test-attribute1 <div title="Website Logo" id="logo"><img src="/random/path" alt="Jumping puma" />Picture</div>}
and the locales below:
"test-attribute1": {
"description": "Test images order",
"message": "<div1 title='Логотип сайта'><img1 alt='Пума в прыжке'>Картинка</div1>"
}
will result into:
<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}}