Лучшая практика для локализации и глобализации строк и меток

Я член команды с более чем 20 разработчиками. Каждый разработчик работает на отдельном модуле (около 10 модулей). В каждом модуле мы можем иметь не менее 50 форм CRUD, что означает, что в настоящее время у нас есть около 500 кнопок добавлять, кнопки, редактировать и др.

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

То, что мы делали до сих пор, заключается в том, что для каждого представления в пользовательском интерфейсе или слое представления у нас есть словарь пар ключей/значений переводов. Затем при визуализации представления мы переводим требуемые тексты и строки с помощью этого словаря. Однако, этот подход, мы получили около 500 добавить в 500 словарей. Это означает, что мы нарушили DRY принципала.

С другой стороны, если мы централизуем общие строки, например, помещаем добавить в одном месте и просим разработчиков использовать его везде, мы сталкиваемся с проблемой не уверенности в том, что строка уже определена в централизованном словаре или нет.

Еще один вариант может заключаться в отсутствии переводческого словаря и использовании услуг онлайн-перевода, таких как Google Translate, Bing Translator и т.д.

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

Какова наилучшая практика или наиболее известный метод глобализации и локализации строковых ресурсов приложения?

Ответ 1

Насколько я знаю, есть хорошая библиотека под названием localeplanet для локализации и интернационализации в JavaScript. Кроме того, я считаю, что он является родным и не имеет зависимостей от других библиотек (например, jQuery)

Здесь находится веб-сайт библиотеки: http://www.localeplanet.com/

Также посмотрите на эту статью Mozilla, вы можете найти очень хороший метод и алгоритмы для перевода на стороне клиента: http://blog.mozilla.org/webdev/2011/10/06/i18njs-internationalize-your-javascript-with-a-little-help-from-json-and-the-server/

Общая часть всех этих статей/библиотек заключается в том, что они используют метод i18n и get (в некотором смысле также определяя меньшее имя функции, например _) для извлечения/преобразования key к value. В объяснении key означает, что строка, которую вы хотите перевести, и value означает переведенную строку.
Тогда вам просто нужен документ JSON для хранения key и value.

Например:

var _ = document.webL10n.get;
alert(_('test'));

И вот JSON:

{ test: "blah blah" }

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

Ответ 2

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

  • Концептуализировать конкретную проблему как набор меньших под-проблем.
  • Решите каждую меньшую проблему.
  • Объедините результаты в решение конкретной проблемы.

Но "разделить и победить" - это не единственная возможная стратегия. Мы также можем использовать более общий подход:

  • Концептуализировать конкретную проблему как частный случай более общей проблемы.
  • Как-то решить общую проблему.
  • Адаптировать решение общей проблемы к конкретной проблеме.

- Эрик Липперт

Я считаю, что многие решения уже существуют для этой проблемы на серверных языках, таких как ASP.Net/C#.

Я изложил некоторые из основных аспектов проблемы.

  • Проблема: нам нужно загружать данные только для желаемого языка

    Решение. Для этого мы сохраняем данные в отдельных файлах для каждого языка.

ех. res.de.js, res.fr.js, res.en.js, res.js(для языка по умолчанию)

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

    Решение. Мы можем использовать некоторые инструменты, которые уже существуют как https://github.com/rgrove/lazyload

  • Проблема: нам нужна структура пары ключ/значение, чтобы сохранить наши данные

    Решение. Я предлагаю объект javascript вместо струнного/струнного воздуха. Мы можем извлечь выгоду из intellisense из IDE

  • Проблема: общие члены должны храниться в общедоступном файле, и все страницы должны обращаться к ним

    Решение. Для этого я создаю папку в корневом каталоге веб-приложения Global_Resources и папку для хранения глобального файла для каждой подпапки, которую мы назвали "Local_Resources"

  • Проблема: каждый член подсистем/подпапок/модулей должен переопределять члены Global_Resources в своей области

    Решение. Я рассмотрел файл для каждого

Структура приложения

root/
    Global_Resources/
        default.js
        default.fr.js
    UserManagementSystem/
        Local_Resources/
            default.js
            default.fr.js
            createUser.js
        Login.htm
        CreateUser.htm

Соответствующий код для файлов:

Global_Resources/default.js

var res = {
    Create : "Create",
    Update : "Save Changes",
    Delete : "Delete"
};

Global_Resources/default.fr.js

var res = {
    Create : "créer",
    Update : "Enregistrer les modifications",
    Delete : "effacer"
};

Файл ресурсов для нужного языка должен быть загружен на страницу, выбранную из Global_Resource. Это должен быть первый файл, загруженный на все страницы.

UserManagementSystem/Local_Resources/default.js

res.Name = "Name";
res.UserName = "UserName";
res.Password = "Password";

UserManagementSystem/Local_Resources/default.fr.js

res.Name = "nom";
res.UserName = "Nom d'utilisateur";
res.Password = "Mot de passe";

UserManagementSystem/Local_Resources/createUser.js

// Override res.Create on Global_Resources/default.js
res.Create = "Create User"; 

UserManagementSystem/Local_Resources/createUser.fr.js

// Override Global_Resources/default.fr.js
res.Create = "Créer un utilisateur";

файл manager.js (этот файл должен быть загружен последним)

res.lang = "fr";

var globalResourcePath = "Global_Resources";
var resourceFiles = [];

var currentFile = globalResourcePath + "\\default" + res.lang + ".js" ;

if(!IsFileExist(currentFile))
    currentFile = globalResourcePath + "\\default.js" ;
if(!IsFileExist(currentFile)) throw new Exception("File Not Found");

resourceFiles.push(currentFile);

// Push parent folder on folder into folder
foreach(var folder in parent folder of current page)
{
    currentFile = folder + "\\Local_Resource\\default." + res.lang + ".js";

    if(!IsExist(currentFile))
        currentFile = folder + "\\Local_Resource\\default.js";
    if(!IsExist(currentFile)) throw new Exception("File Not Found");

    resourceFiles.push(currentFile);
}

for(int i = 0; i < resourceFiles.length; i++) { Load.js(resourceFiles[i]); }

// Get current page name
var pageNameWithoutExtension = "SomePage";

currentFile = currentPageFolderPath + pageNameWithoutExtension + res.lang + ".js" ;

if(!IsExist(currentFile))
    currentFile = currentPageFolderPath + pageNameWithoutExtension + ".js" ;
if(!IsExist(currentFile)) throw new Exception("File Not Found");

Надеюсь, это поможет:)

Ответ 3

jQuery.i18n - это легкий плагин jQuery для обеспечения интернационализации на ваших веб-страницах. Он позволяет упаковывать пользовательские строки ресурсов в файлы .properties, как и в Java Resource Bundles. Он загружает и анализирует пакеты ресурсов (.properties) на основе предоставленного языка или языка, сообщенных браузером.

чтобы узнать больше об этом, посмотрите Как интернационализировать ваши страницы с помощью JQuery?