NPM-пакет для интернационализации i18n используется на фронтэнде для создания мультиязычных вебсайтов очень часто. Перевод текста в нем содержится обычно в json или в js файлах, и требует дальнейшей обработки, чтобы с ним с комфортом могли работать контент-редакторы. В статье описывается как максимально упростить и сделать удобным хранение и внесение изменений в перевод.

Работа с переводом

Есть (наверно) специальные программы для этого, но наиболее удобным мне показалось хранение перевода в Google spreadsheet

В первой колонке идет i18n ключ. Во второй - текст на основном языке. В ячейке С4 находится следующее:

=GOOGLETRANSLATE(B4, "en", "es")

Автоматический перевод с английского на испанский соответствующего текста. Формульное значение данной ячейки копируется на весь столбец. Аналогично поступаем с другими колонками/языками.

При редактировании какой либо ячейки вручную, измененный текст уже не будет перезаписываться Google Translate-ом.

Преобразование для i18n

Для начала загрузим наш Google spreadsheet локально: File -> Download -> Tab Separated Values (.tsv)

В i18n у меня разные переводы хранятся в разных json файлах - en.json, es.json etc. Основной (en.json) билдится с фронтэндом, остальные подгружаются с бэка по запросу, поэтому должны быть отправлены туда

en.json
{
  "account": {
    "2fa": "Two Factor Authorisation (2FA)",
    "2fa_optional": "Two Factor Authorisation (2FA)",
    "2fa_placeholder": "Insert here your Two Factor Authorisation",
    "2fa_add": "Add 2FA",
    "2fa_add_details": "Copy this code <b>{code}</b> and add to a compatible Google Authenticator app or scan the QRCode bellow with Google Authenticator.",
    "2fa_enabled": "2FA is successfully enabled",
    "2fa_is_enabled": "2FA is currently enabled on your account",
...

Следующий node.js код распарсивает экспортированные из Google spreadsheet данные по джейсонам и раскладывает их куда надо:

parseTsv.js
"use strict";

const fs = require("fs");

const rawdata = fs.readFileSync("./src/resources/lang/translation.tsv");
let content = rawdata.toString();
let lines = content.split("\r\n");
let columns = lines[1].split("\t");
lines = lines.splice(3);
for (let i = 1; i < columns.length; i++) {
  const lang = columns[i];
  const data = {};

  lines.forEach(line => {
    const trs = line.split("\t");
    const val = trs[0].split(".");
    if (val.length > 1) {
      if (!data[val[0]]) {
        data[val[0]] = {};
      }
      data[val[0]][val[1]] = trs[i];
    } else {
      data[trs[0]] = trs[i];
    }
  });
  fs.writeFileSync(
    "../backend/public/assets/lang/" + lang + ".json",
    JSON.stringify(data, null, 2)
  );
}
fs.copyFile(
  "../backend/public/assets/lang/en.json",
  "./src/resources/lang/en.json",
  err => {
    if (err) throw err;
  }
);

Всё.

Google API

У Google есть API, которое позволяет программно скачать Google spreadsheet (включая авторизацию). Если есть желание и время его интегрировать, то можно еще более автоматизировать данный процесс и даже сделать его частью CI/CD. Но и в описанном выше варианте внедрение сделанных редактором изменений в перевод занимает 20 секунд.

Комментарии (6)


  1. dimakey
    00.00.0000 00:00

    Какого размера таблица в итоге (сколько строк/столбцов)? Используем похожий подход для перевода в ios/android и столкнулись с проблемами уже на 1000 строк для 12 языков - приходится разбивать на несколько таблиц.


    1. gmtd Автор
      00.00.0000 00:00

      400 строк на 10 языков

      1000 строк даже для удобства тематически на таблицы разбивать имеет смысл, конечно


  1. BoberMod
    00.00.0000 00:00
    +3

    Есть (наверно) специальные программы для этого

    crowdin.com


  1. Ekseft
    00.00.0000 00:00
    +1

    Все переводу по одному языку хранятся в одном файле? Для больших сайтов эти JSON файлы будут чересчур большими. i18next поддерживает namespace'ы, что позволяет разделить переводы по страницам/компонентам и подгружать только нужные.

    А сервисы, которые помогают с переводами, и правда есть, например, раз и два.


    1. gmtd Автор
      00.00.0000 00:00

      Ну я говорю про перевод самого сайта - "статичной" оболочки. Для этого один JSON - самое то. Человек в него не лазит, общий объем в бандле не сильно увеличивает.

      Если есть еще какой-то достаточно большой контент (динамичный?), требующий перевода, то к нему наверно лучше применить какой-нибудь другой подход

      А сервисы, которые помогают с переводами, и правда есть, например, раз и два.

      Ну да, конечно есть, но сложность их и времязатраты на внедрение адекватны наверно только для очень больших проектов и соответствующих требований. Google spreadsheet в иной категории. Кроме того, да, это совсем не "программы", а сервисы с различными услугами, что выходит за рамки темы статьи.


  1. BasiC2k
    00.00.0000 00:00

    В самом Google Apps Script перевод слов и фраз можно выполнить с помощью этого API:

    var message = LanguageApp.translate(phrase, currLocale, locale);

    В своё время я написал скрипт из 50 строк, который выполняет перевод 20 фраз на все языки, с формированием json файлов.

    https://script.google.com/home/projects/1jr7o_LRXoNpzkKS3uIHtQ0uXKX9tLHK8PcfKtuRBLww1wAiBXFigB7i2/edit

    Возможно кому-то пригодится.