Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i18n / Интернационализация #257

Open
aeifn opened this issue Nov 12, 2020 · 15 comments · May be fixed by #620
Open

i18n / Интернационализация #257

aeifn opened this issue Nov 12, 2020 · 15 comments · May be fixed by #620
Labels
i18n Internationalization Infrastructure *** site infrastructure issues UI All features with changing of User Interface

Comments

@aeifn
Copy link
Member

aeifn commented Nov 12, 2020

Представляется логичным перенести языковую составляющую в мастер ветку, тем самым избавиться от необходимости синхронизировать ветку en с мастером.

Зачатки такого подхода наблюдаются, например, здесь:
image

И здесь:
image

Как вариант, можно подставлять перевод на этапе сборки.

@aeifn aeifn added i18n Internationalization UI All features with changing of User Interface labels Nov 12, 2020
@mkgrgis
Copy link
Contributor

mkgrgis commented Nov 12, 2020

Что если хранить такие вещи в статической ветке Монги с разметкой согласно ISO 639 ?
about_title_text: { ..., eng:"About", rus: "О проекте" ... }
Для начала хорошо бы вынести в JSON файл или файлы, где рядом вести ряды на доступных языках в одинаковом порядке по латинскому алфавиту языковых кодов.
Другой вариант - доверится средствам ОС и работать с gettext через пакет. Только преимуществ простоты редактирования в таком случае нет.

@paul-k-pastvu
Copy link

paul-k-pastvu commented Nov 12, 2020

На самом деле, не нужно вообще так уж держаться за эти строки и пытаться что-то организовать у себя.
Гораздо лучше всё вынести в языковые .po файлы и поднять любую систему перевода (хоть вот MediaWiki с расширением перевода). Или подключиться к https://translatewiki.net или https://www.transifex.com/ - что во всех смыслах было бы эффективнее.

@mkgrgis
Copy link
Contributor

mkgrgis commented Nov 13, 2020

лучше всё вынести в языковые .po файлы

Так это и есть gettext вариант в чистом виде, см. В таком случае пакета не избежать.

@paul-k-pastvu paul-k-pastvu added CI/CD Continued Integration / Continued Development Infrastructure *** site infrastructure issues labels Nov 16, 2020
@aeifn aeifn removed the CI/CD Continued Integration / Continued Development label Dec 4, 2020
@aeifn aeifn added this to To do in Internationalization via automation Dec 4, 2020
@aeifn
Copy link
Member Author

aeifn commented Dec 4, 2020

лучше всё вынести в языковые .po файлы

Так это и есть gettext вариант в чистом виде, см. В таком случае пакета не избежать.

Gettext представляется отличным выбором, и внедрить его технически совсем не трудно. Но потребуется кропотливая работа по аккуратной замене сообщений на соответствующие функции и подготовке языковых файлов.
Предлагаю подключить пакет и попробовать перевести отдельную небольшую часть приложения для пробы.

@aeifn
Copy link
Member Author

aeifn commented Dec 4, 2020

Лучше использовать этот пакет: https://www.npmjs.com/package/node-gettext
Он более популярен и поддерживается

@anvaruk
Copy link
Collaborator

anvaruk commented Dec 6, 2020

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

я могу заняться если инструкцию дадите

@mkgrgis
Copy link
Contributor

mkgrgis commented Dec 6, 2020

@anvaruk сначала нужно попробовать просто добиться в изолированной node js работы пакета с переводом и перевести 1-2 сообщения через создание файлов .po на 2-3 языка. Если получтся, то @aeifn должен определить какие вызовы с формированеим надписей подлежат первоочередной замене на вызовы getText. А там только .po дополняй и наращивай.

@aeifn
Copy link
Member Author

aeifn commented Dec 7, 2020

Доступность функции gettext в шаблонах можно обеспечить отсюда:

pastvu/app.js

Lines 92 to 98 in c47487f

// Set an object which properties will be available from all pug-templates as global variables
Object.assign(app.locals, {
pretty: false, // Adds whitespace to the resulting html to make it easier for a human to read
compileDebug: false, // Include the function source in the compiled template for better error messages
debug: false, // If set to true, the tokens and function body is logged to stdoutl (in development).
config,
});

@kabalin
Copy link
Member

kabalin commented Dec 8, 2020

Лучше использовать этот пакет: https://www.npmjs.com/package/node-gettext
Он более популярен и поддерживается

На что нужно обратить внимание:

  • Как формировать JSON для использования на бэкэнде - компилировать отдельной задачей в grunt (и включать в сборку) или компилировать при каждом запуске приложения?
  • Как передавать JSON c набором строк клиенту - через вебсервис подгружать для выбранной локали или компилировать отдельной задачей в grunt и включать в сборку в поддиректорию в public? Вероятно делать это при сборке оптимальный вариант (как считает @aeifn), для разработчика альтернативный способ компиляции будет ручной запуск команды grunt po2json.
  • Со стороны клиента у помимо js, еще есть шаблоны:
    • В шаблонах есть статический текст (типа такого), его нужно как-то преобразовывать.
    • В шаблонах есть knockout, где текст является частью data-bind (типа такого), здесь нужен отдельный обработчик для knockout (этот для примера, и еще один для i18next, там можно подчерпнуть идеи как встроить gettext в knockout).

Чтобы с чего-то начать, шаги могут быть следующими:

  1. Взять какой-то один шаблон.
  2. Создать po файл со всеми строками из шаблона (в дириктории ./locales ?).
  3. Прикрутить парсер к Gruntfile (см https://github.com/mikeedwards/po2json и https://www.npmjs.com/package/grunt-po2json)
  4. Сгенерировать json с текстом из po файла.
  5. В шаблоне получить текст из json используя node-gettext и i18n / Интернационализация #257 (comment)

@yuriy-zhilovets2
Copy link
Contributor

Стандартный механизм использования gettext такой:

  1. Все строки в коде заменяются вызовом функции _
    _("Это строка")

  2. Отдельный парсер, запускаемый при изменения в коде, находит эти строки и переносит в каталог строк (отдельный файл)

  3. В специальном редакторе найденные строки переводятся на поддерживаемые языки и сохраняются в файле .po

  4. Редактор компилирует этот файл в формат .mo, файл подкладывается в дерево

  5. Функция _ во время работы читает строки из файла .mo

Тонкости:

  1. Строки могут быть не только в коде .js, но и в других местах. Соответственно, нужен отдельный парсер и механизм вызова
  2. Файлы .mo получаются довольно большого размера, поэтому имеет смысл разделить строки в серверном и в клиентском коде, и в браузер грузить только один файл для клиентских строк

Я могу взяться за перевод строк, но нужно определиться:

  1. Какой пакет будет использоваться
  2. Где еще могут находиться строки (например, в сообщениях об ошибках)

Последовательность действий:

  1. Начать со строк в коде, отметить их через _
  2. Собрать каталог, проверить, что строки транслируются правильно
  3. Добавить английский перевод и код переключения на него
  4. Разобраться с остальными строками

@aeifn
Copy link
Member Author

aeifn commented Nov 15, 2022

  • Строки могут быть не только в коде .js, но и в других местах. Соответственно, нужен отдельный парсер и механизм вызова

По идее, все строки должны быть в js-коде.

  • Файлы .mo получаются довольно большого размера, поэтому имеет смысл разделить строки в серверном и в клиентском коде, и в браузер грузить только один файл для клиентских строк

Возможно, лучше просто собирать несколько версий фронта на разных языках (строки будут подставляться на этапе сборки).

@kabalin
Copy link
Member

kabalin commented Jan 10, 2023

Возможно, лучше просто собирать несколько версий фронта на разных языках (строки будут подставляться на этапе сборки).

Конечно, на самом деле по-другому и не получится, шаблон компилируется на этапе сборки, языковые переменные в шаблоне будут преобразованы в текст.

@aeifn aeifn linked a pull request Sep 6, 2023 that will close this issue
@aeifn
Copy link
Member Author

aeifn commented Sep 6, 2023

Предлагаю использовать этот фреймворк: https://github.com/i18next/i18next

@kabalin
Copy link
Member

kabalin commented Sep 6, 2023

Предлагаю использовать этот фреймворк: https://github.com/i18next/i18next

Идея хорошая, но как я понимаю он заточен под runtime, у нас строки еще и на стороне сервера есть и в клиенте в нескольких вариантах (js, шаблоны). Шаблон компилируется при сборке, там динамически строки менять не получится (если только их не будет подставлять JS библиотека при показе), в общем есть вопросы. Мне кажется встраивание языка на этапе компиляции и отдельные инстансы приложения для разных языков - более понятный вариант.

Отдельно скажу, что я так же не уверен насчет po/mo файлов и gettext. Хороший пример реализации перевода в Docusaurus, там в качестве фреймворка используется formatjs, в качестве формата файлов перевода Chrome.i18n который имеет дополнительное поле description (помогает переводчику) и интеграцию с сервисом Crowdin обеспечивающим интерфейс для переводчика (бесплатно для open source проектов). Мне кажется нужно что-то похожее делать с удобным форматированием и на основе стандартов (у i18next как я понял свой стандарт форматирования для множественного числа, даты, вставки переменных и т.д., а formatjs использует ICU Message syntax поддерживаемый и другими фрейвоками, i18n-node в частности).

В общем вопрос требует изучения.

@klimashkin
Copy link
Member

Согласен, использую formatjs c ICU/CLDR c 2014 года на других проектах.
Это Unocode стандарт для формата строк

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
i18n Internationalization Infrastructure *** site infrastructure issues UI All features with changing of User Interface
Projects
Development

Successfully merging a pull request may close this issue.

7 participants