web-dev-qa-db-ja.com

JavaScriptで文字列をローカライズする

現在、.NETのサーバー側リソースを管理するために.resxファイルを使用しています。

私が扱っているアプリケーションでは、JavaScriptをクライアント側検証などのさまざまなイベントハンドラーにプラグインすることもできます。JavaScriptメッセージと文字列をローカライズするための最良の方法は何ですか?

理想的には、文字列を.resxファイルに格納して、ローカライズされた残りのリソースと一緒に保持したいと考えています。

私は提案を受け入れます。

38
SaaS Developer

基本的な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];
26
Joel Anair

SproutCore に触発されて、文字列のプロパティを設定できます。

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

そして、単にあなたのロケールに基づいて適切なローカリゼーションを吐き出します:

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

たくさんグーグルして、提示されたソリューションの大部分に満足していない後、私は T4テンプレート を使用する驚くべき/一般的なソリューションを見つけました。 Jochen van Wylick による完全な投稿はここで読むことができます:

。resxファイルに基づいてJavaScriptリソースをローカライズするためのT4の使用

主な利点は次のとおりです。

  1. リソースが管理される場所が1つだけある(つまり、.resxファイル)
  2. 複数の文化のサポート
  3. IntelliSenseの活用-コード補完を可能にする

短所:

このソリューションの欠点は、もちろん、.jsファイルのサイズが非常に大きくなる可能性があることです。ただし、ブラウザによってキャッシュされるため、これはアプリケーションの問題とは見なされません。ただし、このキャッシュにより、ブラウザがコードから呼び出されたリソースを見つけられなくなる可能性もあります。


これはどのように機能しますか?

基本的に、彼は.resxファイルを指すT4テンプレートを定義しました。いくつかのC#コードを使用して、すべてのリソース文字列をトラバースし、それをJavaScriptの純粋なキー値プロパティに追加し、Resources.jsと呼ばれる単一のJavaScriptファイルに出力します(必要に応じて名前を調整できます)。


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>

Scott Hanselmanによるこの素晴らしい投稿から得た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);
10

JSGettextは優れた仕事をします-GNUバックエンドでほとんどすべての言語を使用するGettext .poファイルの動的ロード。JSGettextのウォークスルーを見つけるための「GettextとPHPによる動的Javascriptローカリゼーション」のためのGoogle with PHP(リンクを投稿しますが、このばかげたサイトは私に聞かせません、ため息...)

Editthis はリンクである必要があります

4
Jani Patokallio

私はオブジェクト/配列表記を使用します:

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ファイルに対してこれを行う方法はまだ見つかりません。

4
Erik Hesselink

JavaScriptアプリケーションをローカライズするためのライブラリがあります: https://github.com/wikimedia/jquery.i18n

これは、パラメーターの置換を行うことができ、性別(巧妙な彼/彼女の処理)、数(巧妙な複数処理、複数の複数形を持つ言語を含む)、および一部の言語に必要なカスタム文法規則をサポートします。

文字列はJSONファイルに保存されます。

唯一の要件はjQueryです。

3
Amir E. Aharoni

HTML5を実行するモバイルアプリのJavaScriptをローカライズするために、次のことを行いました。

1.英語の「en.js」のように、言語ごとにリソースファイルのセットを作成します。次のように、それぞれにアプリに異なる文字列が含まれています。


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

2.Lazyloadを使用して、アプリのロケール言語に基づいて適切なリソースファイルを読み込みます: https://github.com/rgrove/lazyload

3.クエリ文字列を介して言語コードを渡します(Android PhoneGapを使用して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"
2
Jaime Botero

ええと、あなたはこれを考慮できると思います。英語-スペイン語の例:

このように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);

そして、それはとても簡単に機能すると思います。

1
Caveman

Diodes.myopenid.comの答えを拡張する:コードに、必要なすべての文字列を含むJS配列を含むファイルを書き出してから、他のJSコードの前に適切なファイル/スクリプトをロードします。

0
Lasar