Подтвердить что ты не робот

Локализовать строки в Javascript

В настоящее время я использую файлы .resx для управления ресурсами на стороне сервера для .NET.

приложение, с которым я имею дело, также позволяет разработчикам подключать JavaScript к различным обработчикам событий для проверки на стороне клиента и т.д. Каков наилучший способ для локализации моих сообщений и строк JavaScript?

В идеале я хотел бы сохранить строки в файлах .resx, чтобы сохранить их с остальными локализованными ресурсами.

Я открыт для предложений.

4b9b3361

Ответ 1

Основной объект JavaScript является ассоциативным массивом, поэтому его можно легко использовать для хранения пар ключ/значение. Поэтому, используя JSON, вы можете создать объект для каждой строки, которая будет локализована следующим образом:

var localizedStrings={
    confirmMessage:{
        'en/US':'Are you sure?',
        'fr/FR':'Est-ce que vous êtes certain?',
        ...
    },

    ...
}

Затем вы можете получить локальную версию каждой строки следующим образом:

var locale='en/US';
var confirm=localizedStrings['confirmMessage'][locale];

Ответ 2

Вдохновленный SproutCore Вы можете установить свойства строки:

'Hello'.fr = 'Bonjour';
'Hello'.es = 'Hola';

а затем просто выплюнуть правильную локализацию на основе вашей локали:

var locale = 'en';
alert( message[locale] );

Ответ 3

После многократного Googling и не удовлетворенного большинством представленных решений, я только что нашел удивительное/универсальное решение, которое использует T4 templates. Полный пост Йохен ван Уайлик вы можете прочитать здесь:

Использование T4 для локализации ресурсов JavaScript на основе файлов .resx

Основные преимущества:

  • Имеет только 1 место, где управляются ресурсы (а именно .resx файлы)
  • Поддержка нескольких культур
  • Использование IntelliSense - возможность завершения кода

Недостатки:

Недостатки этого решения, конечно, состоят в том, что размер .js может стать довольно большим. Однако, поскольку он кэшируется браузером, мы не рассматриваем эту проблему для нашего приложения. Однако - это кэширование также может привести к тому, что браузер не найдет ресурс, вызванный из кода.


Как это работает?

В основном он определил шаблон T4, который указывает на ваши .resx файлы. С помощью некоторого кода на С# он пересекает каждую строку ресурсов и добавляет ее в свойства свойства чистого ключа JavaScript, которые затем выводятся в одном файле JavaScript под названием Resources.js (вы можете настроить имена, если хотите).


Шаблон T4 [изменить, соответственно, указывать на расположение файлов .resx]

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ assembly name="System.Windows.Forms" #>
<#@ import namespace="System.Resources" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.IO" #>
<#@ output extension=".js"#>
<#
 var path = Path.GetDirectoryName(Host.TemplateFile) + "/../App_GlobalResources/";
 var resourceNames = new string[1]
 {
  "Common"
 };

#>
/**
* Resources
* ---------
* This file is auto-generated by a tool
* 2012 Jochen van Wylick
**/
var Resources = {
 <# foreach (var name in resourceNames) { #>
 <#=name #>: {},
 <# } #>
};
<# foreach (var name in resourceNames) {
 var nlFile = Host.ResolvePath(path + name + ".nl.resx" );
 var enFile = Host.ResolvePath(path + name + ".resx" );
 ResXResourceSet nlResxSet = new ResXResourceSet(nlFile);
 ResXResourceSet enResxSet = new ResXResourceSet(enFile);
#>

<# foreach (DictionaryEntry item in nlResxSet) { #>
Resources.<#=name#>.<#=item.Key.ToString()#> = {
 'nl-NL': '<#= ("" + item.Value).Replace("\r\n", string.Empty).Replace("'","\\'")#>',
 'en-GB': '<#= ("" + enResxSet.GetString(item.Key.ToString())).Replace("\r\n", string.Empty).Replace("'","\\'")#>'
 };
<# } #>
<# } #>

В стороне формы/вида

Чтобы получить правильный перевод, добавьте его в свой мастер, если вы используете WebForms:

<script type="text/javascript">

    var locale = '<%= System.Threading.Thread.CurrentThread.CurrentCulture.Name %>';

</script>

<script type="text/javascript" src="/Scripts/Resources.js"></script>

Если вы используете ASP.NET MVC (например, я), вы можете сделать это:

<script type="text/javascript">

    // Setting Locale that will be used by JavaScript translations
    var locale = $("meta[name='accept-language']").attr("content");

</script>

<script type="text/javascript" src="/Scripts/Resources.js"></script>

Помощник MetaAcceptLanguage, который я получил от этого замечательного поста Скотта Гензельмана:

Глобализация, интернационализация и локализация в ASP.NET MVC 3, JavaScript и jQuery - часть 1

public static IHtmlString MetaAcceptLanguage<T>(this HtmlHelper<T> html)
{
     var acceptLanguage =
         HttpUtility.HtmlAttributeEncode(
                     Thread.CurrentThread.CurrentUICulture.ToString());

      return new HtmlString(
      String.Format("<meta name=\"{0}\" content=\"{1}\">", "accept-language",
                    acceptLanguage));
 }

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

var msg = Resources.Common.Greeting[locale];
alert(msg);

Ответ 4

Я бы использовал обозначение объекта/массива:

var phrases={};
phrases['fatalError'] ='On no!';

Затем вы можете просто поменять файл JS или использовать вызов Ajax для переопределения списка фраз.

Ответ 5

Со спутниковой сборкой (вместо файла resx) вы можете перечислить все строки на сервере, где вы знаете язык, создавая таким образом объект Javascript только с строками для правильного языка.

Что-то вроде этого работает для нас (код VB.NET):

Dim rm As New ResourceManager([resource name], [your assembly])
Dim rs As ResourceSet = 
    rm.GetResourceSet(Thread.CurrentThread.CurrentCulture, True, True)
For Each kvp As DictionaryEntry In rs
    [Write out kvp.Key and kvp.Value]
Next

Однако мы пока не нашли способ сделать это для файлов .resx, к сожалению.

Ответ 6

JSGettext выполняет отличную работу - динамическую загрузку файлов GNU Gettext.po, используя практически любой язык на бэкэнд. Google для "Динамической Javascript-локализации с Gettext и PHP", чтобы найти пошаговое руководство для JSGettext с PHP (я бы опубликовал ссылку, но этот глупый сайт не позволит мне вздохнуть...)

Изменить: этот должен быть ссылкой

Ответ 7

Там есть библиотека для локализации приложений JavaScript: https://github.com/wikimedia/jquery.i18n

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

Строки хранятся в файлах JSON.

Единственное требование - jQuery.

Ответ 8

Я сделал следующее, чтобы локализовать JavaScript для мобильного приложения, использующего HTML5:

1. Создал набор файлов ресурсов для каждого языка, называя их как "en.js" для английского. Каждый из них содержал различные строки приложения следующим образом:


        var localString = {
        appName: "your app name",
        message1: "blah blah"
      };

2.Used Lazyload для загрузки соответствующего файла ресурсов на основе языка языка приложения: https://github.com/rgrove/lazyload

3.Уставьте код языка через строку запроса (поскольку я запускаю html файл с Android с помощью PhoneGap)

4. Затем я написал следующий код для динамического загрузки соответствующего файла ресурсов:


var lang = getQueryString("language");
localization(lang);
function localization(languageCode) {
    try {
        var defaultLang = "en";
        var resourcesFolder = "values/";
        if(!languageCode || languageCode.length == 0)
            languageCode = defaultLang;
        // var LOCALIZATION = null;
        LazyLoad.js(resourcesFolder + languageCode + ".js", function() {
            if( typeof LOCALIZATION == 'undefined') {
                LazyLoad.js(resourcesFolder + defaultLang + ".js", function() {
                    for(var propertyName in LOCALIZATION) {
                        $("#" + propertyName).html(LOCALIZATION[propertyName]);
                    }
                });
            } else {
                for(var propertyName in LOCALIZATION) {
                    $("#" + propertyName).html(LOCALIZATION[propertyName]);
                }
            }
        });
    } catch (e) {
        errorEvent(e);
    }
}
function getQueryString(name)
{
  name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
  var regexS = "[\\?&]" + name + "=([^]*)";
  var regex = new RegExp(regexS);
  var results = regex.exec(window.location.href);
  if(results == null)
    return "";
  else
    return decodeURIComponent(results[1].replace(/\+/g, " "));
}

5. Из html файла я ссылаюсь на строки следующим образом:


    span id="appName"

Ответ 9

Хорошо, я думаю, что вы можете это рассмотреть. Английский-испанский пример:

Напишите 2 скрипта Js, например:

en-GB.js
lang = {
    date_message: 'The start date is incorrect',
    ...
};
es-ES.js
lang = {
    date_message: 'Fecha de inicio incorrecta',
    ...
};

Серверная сторона - код позади:

Protected Overrides Sub InitializeCulture()
    Dim sLang As String 
    sLang = "es-ES" 

    Me.Culture = sLang
    Me.UICulture = sLang
    Page.ClientScript.RegisterClientScriptInclude(sLang & ".js", "../Scripts/" & sLang & ".js")

    MyBase.InitializeCulture()
End Sub

Где sLang может быть "en-GB", вы знаете, в зависимости от текущего выбора пользователя...

Javascript-вызовы:

alert (lang.date_message);

И это работает, очень легко, я думаю.

Ответ 10

Разверните на diodeus.myopenid.com ответ: попросите свой код записать файл, содержащий массив JS со всеми необходимыми строками, затем загрузите соответствующий файл / script перед другим JS-кодом.

Ответ 11

MSDN способ сделать это, в основном это:

Вы создаете отдельный файл script для каждого поддерживаемого языка и культуры. В каждом файле script вы включаете объект в формате JSON, который содержит значения локализованных ресурсов для этого языка и культуры.

Я не могу сказать вам лучшее решение для вашего вопроса, но ИМХО это худший способ сделать это. По крайней мере теперь вы знаете, как НЕ делать это.

Ответ 12

Мы используем MVC и просто создали действие контроллера, чтобы вернуть локализованную строку. Мы поддерживаем культуру пользователя в сеансе и устанавливаем культуру потока перед любым вызовом для извлечения языковой строки AJAX или иным образом. Это означает, что мы всегда возвращаем локализованную строку.

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

Global.asax.cs

protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
    if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState)
    {
        // Set the current thread culture
        var culture = (CultureInfo)Session["CultureInfo"];
        if (culture != null)
        {
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = culture;
        }
    }
}

Действие контроллера

public string GetString(string key)
{
    return Language.ResourceManager.GetString(key);
}

Javascript

/*
    Retrieve a localized language string given a lookup key.
    Example use:
      var str = language.getString('MyString');
*/
var language = new function () {
    this.getString = function (key) {
        var retVal = '';
        $.ajax({
            url: rootUrl + 'Language/GetString?key=' + key,
            async: false,
            success: function (results) {
                retVal = results;
            }
        });
        return retVal;
    }
};