.resx
現在、.NET のサーバー側リソースを管理するためにファイルを使用しています。
私が扱っているアプリケーションでは、開発者が JavaScript をさまざまなイベント ハンドラーにプラグインして、クライアント側の検証などを行うこともできます。JavaScript メッセージと文字列をローカライズするための最良の方法は何ですか?
理想的には、文字列を.resx
ファイルに保存して、残りのローカライズされたリソースと一緒に保持したいと考えています。
私は提案を受け入れます。
.resx
現在、.NET のサーバー側リソースを管理するためにファイルを使用しています。
私が扱っているアプリケーションでは、開発者が JavaScript をさまざまなイベント ハンドラーにプラグインして、クライアント側の検証などを行うこともできます。JavaScript メッセージと文字列をローカライズするための最良の方法は何ですか?
理想的には、文字列を.resx
ファイルに保存して、残りのローカライズされたリソースと一緒に保持したいと考えています。
私は提案を受け入れます。
基本的な 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];
SproutCoreに触発されて文字列のプロパティを設定できます。
'Hello'.fr = 'Bonjour';
'Hello'.es = 'Hola';
次に、ロケールに基づいて適切なローカリゼーションを吐き出すだけです。
var locale = 'en';
alert( message[locale] );
グーグルで何度も検索し、提示されたソリューションの大部分に満足できなかった後、T4 テンプレートを使用する驚くべき/汎用的なソリューションを見つけました。Jochen van Wylickによる完全な投稿は、ここで読むことができます。
.resx ファイルに基づく JavaScript リソースのローカライズに T4 を使用する
主な利点は次のとおりです。
短所:
もちろん、このソリューションの欠点は、.js ファイルのサイズが非常に大きくなる可能性があることです。ただし、ブラウザによってキャッシュされるため、これはアプリケーションの問題とは見なされません。ただし、このキャッシュにより、ブラウザがコードから呼び出されたリソースを見つけられなくなる可能性もあります。
これはどのように機能しますか?
基本的に、彼は .resx ファイルを指す T4 テンプレートを定義しました。いくつかの C# コードを使用して、すべてのリソース文字列をトラバースし、それを 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("'","\\'")#>'
};
<# } #>
<# } #>
フォーム/ビュー側
正しい翻訳を取得するには、Web フォームを使用している場合はマスターにこれを追加します。
<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
Scott Hanselman によるこの素晴らしい投稿から得たヘルパー:
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);
オブジェクト/配列表記を使用します。
var phrases={};
phrases['fatalError'] ='On no!';
次に、JS ファイルを交換するか、Ajax 呼び出しを使用してフレーズ リストを再定義します。
サテライト アセンブリ (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 ファイルに対してこれを行う方法はまだ見つかっていません。
JSGettext は優れた仕事をします。バックエンドでほぼすべての言語を使用して、GNU Gettext .po ファイルを動的にロードします。Google で「Gettext と PHP を使用した動的な Javascript ローカリゼーション」を検索して、PHP を使用した JSGettext のウォークスルーを見つけてください (リンクを投稿したいのですが、このばかげたサイトでは許可されません、ため息...)
編集:これはリンクである必要があります
JavaScript アプリケーションをローカライズするためのライブラリがあります: https://github.com/wikimedia/jquery.i18n
パラメーターの置換を行うことができ、性別 (巧妙な彼/彼女の処理)、数値 (複数形を複数持つ言語を含む巧妙な複数形の処理)、および一部の言語で必要なカスタム文法規則をサポートしています。
文字列は JSON ファイルに保存されます。
唯一の要件は jQuery です。
なるほど、これはご検討いただければと思います。英語とスペイン語の例:
次のように、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);
そして、それは非常に簡単に機能すると思います。
HTML5 を実行するモバイル アプリ用に JavaScript をローカライズするために、次のことを行いました。
1.英語の「en.js」のように、各言語のリソース ファイルのセットを作成します。各アプリには、次のように異なる文字列が含まれていました。
var localString = {
appName: "your app name",
message1: "blah blah"
};
2. Lazyload を使用して、アプリのロケール言語に基づいて適切なリソース ファイルをロードしました: https://github.com/rgrove/lazyload
3.クエリ文字列を介して言語コードを渡します(PhoneGapを使用してAndroidからhtmlファイルを起動しているため)
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"
dious.myopenid.com の回答を拡張します。必要なすべての文字列を含む JS 配列を含むファイルをコードに書き出させてから、他の JS コードの前に適切なファイル/スクリプトをロードします。
それMSDN
を行う方法は、基本的には次のとおりです。
サポートされている言語とカルチャごとに個別のスクリプトファイルを作成します。各スクリプトファイルには、その言語とカルチャのローカライズされたリソース値を含むJSON形式のオブジェクトを含めます。
私はあなたの質問に対する最善の解決策をあなたに言うことはできませんが、私見これはそれを行うための最悪の方法です。少なくとも今、あなたはそれをしない方法を知っています。