Локализовать строки в Javascript
В настоящее время я использую файлы .resx
для управления ресурсами на стороне сервера для .NET.
приложение, с которым я имею дело, также позволяет разработчикам подключать JavaScript к различным обработчикам событий для проверки на стороне клиента и т.д. Каков наилучший способ для локализации моих сообщений и строк JavaScript?
В идеале я хотел бы сохранить строки в файлах .resx
, чтобы сохранить их с остальными локализованными ресурсами.
Я открыт для предложений.
Ответы
Ответ 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;
}
};