web-dev-qa-db-ja.com

JavaScriptと多言語のベストプラクティス

javaScriptを使用したDOM操作を使用した多言語Webサイトのベストプラクティスは何ですか? JavaScriptを使用してWebサイトの動的な部分を構築します。最初に考えたのは、インデックスとしてテキスト文字列と言語コードを含む配列を使用することでした。これはいい考えですか?

62
marquies

以前に多言語サイトを構築したとき(あまり大きくないので、これはあまりスケールアップしないかもしれません)、一連の「言語」ファイルを保持します:

  • lang.en.js
  • lang.it.js
  • lang.fr.js

各ファイルは、基本的にWordから言語フレーズへの単なるマップであるオブジェクトを宣言します。

// lang.en.js
lang = {
    greeting : "Hello"
};

// lang.fr.js
lang = {
    greeting : "Bonjour"
};

これらのファイルの1つを動的にロードしてから、マップからキーを参照するだけです。

document.onload = function() {
    alert(lang.greeting);
};

もちろん、これを行う方法は他にもたくさんありますが、このスタイルを実行する方法はたくさんありますが、すべてを関数にカプセル化して、「辞書」から欠落しているフレーズを適切に処理できるようにするか、さらにはすべてを行うこともできますOOPを使用して、ファイルの動的インクルードを管理できるようにすると、言語セレクターを描画することもできます。

var l = new Language('en');
l.get('greeting');
70
nickf

多言語サポートを設計する際に留意すべきことがいくつかあります。

1-データからコードを分離します(つまり、文字列を関数に直接ハードコードしないでください)

2-ローカライズの違いに対処するためのフォーマットフック関数を作成します。書式設定可能な文字列( "{0}")を許可することは、( "Welcome to" + value)、多くの理由:

  • 一部の言語では、数値は1,234,567.00ではなく1.234.678,00のようにフォーマットされます
  • 複数形化は、単数形の末尾に「s」を追加するほど単純ではありません。
  • 文法規則は異なり、物事の順序に影響を与える可能性があるため、変換フックの後に動的データを追加できるようにする必要があります。たとえば、 "Welcome to {0}"は、日本語では "{0}彼youkoso"になります(これはほとんどすべての言語で発生します)。

3-実際に文字列をフォーマットできることを確認してください変換フックの実行後、キーを再利用できるようにします。

4-どんな状況下でも、データベース出力を翻訳ユーティリティにフックしないでください。多言語データがある場合は、データベースに個別のテーブル/行を作成します。私は、人々がこのように簡単な間違いをかなり頻繁に受けるのを見てきました(通常、国や州/フォームの場合)。

5-キーを作成するための明示的なコーディングプラクティスルールを作成します。フォーマッタユーティリティ関数(translate( "hello world")のようになります)は、パラメータとしてキーを取り、わずかなバリエーションのキーがメンテナンスを行います。たとえば、次の例では3つのキーになる場合があります:「名前を入力してください」、「名前を入力してください」、「名前を入力してください」。コードレビューの不一致:誤検知を引き起こす可能性があるため、プログラムでこのフィルタリングを行わないでください。

6-変換テーブルでHTMLマークアップが必要になる可能性があることに注意してください(たとえば、文の中でWordを太字にする必要がある場合、または脚注の医学文献がある場合)。これを広範囲にテストします。

7-言語文字列をインポートする方法はいくつかあります。理想的には、language.lang.jsファイルの複数のバージョンを用意し、それらをサーバー側コードで切り替え、HTMLファイルの下部からファイルを参照する必要があります。 AJAX経由でファイルをプルすることも代替手段ですが、遅延が発生する可能性があります。メインコードファイルへのlanguage.jsのマージは、ファイルキャッシュの利点を失うためお勧めできません。

8-ターゲット言語でテストします。これは馬鹿げたように聞こえますが、プログラマがキーに「é」が存在する。

51
Leo
function Language(lang)
{
    var __construct = function() {
        if (eval('typeof ' + lang) == 'undefined')
        {
            lang = "en";
        }
        return;
    }()

    this.getStr = function(str, defaultStr) {
        var retStr = eval('eval(lang).' + str);
        if (typeof retStr != 'undefined')
        {
            return retStr;
        } else {
            if (typeof defaultStr != 'undefined')
            {
                return defaultStr;
            } else {
                return eval('en.' + str);
            }
        }
    }
}

これをページに追加したら、次のように操作できます。

var en = {
    SelPlace:"Select this place?",
    Save:"Saved."
};

var tr = {
    SelPlace:"Burayı seçmek istiyor musunuz?"
};

var translator = new Language("en");
alert(translator.getStr("SelPlace")); // result: Select this place?
alert(translator.getStr("Save")); // result: Saved.
alert(translator.getStr("DFKASFASDFJK", "Default string for non-existent string")); // result: Default string for non-existent string

var translator = new Language("tr");
alert(translator.getStr("SelPlace")); // result: Burayı seçmek istiyor musunuz?
alert(translator.getStr("Save")); // result: Saved. (because it doesn't exist in this language, borrowed from english as default)
alert(translator.getStr("DFKASFASDFJK", "Default string for non-existent string")); // result: Default string for non-existent string

定義していない言語でクラスを呼び出すと、英語(en)が選択されます。

12
Nail

JavaScriptでi18nに関する素敵な記事を見つけました。
http://24ways.org/2007/javascript-internationalisation

I18n + javascriptを使用した単純なGoogle検索では、多くの選択肢が明らかになります。

最終的には、どのようにするかdeepに依存します。いくつかの言語では、単一のファイルで十分です。

Jquery のようなフレームワークを使用し、スパンを使用してテキスト(クラスを含む)を識別し、各スパンのIDを使用して、選択した言語で対応するテキストを検索できます。
1行のJquery、完了。

5
Berzemus

NickfとLeoのすばらしい回答を読んだ後、次のCommonJSスタイルのlanguage.jsを作成して、すべての文字列を管理します(オプションで Mustache をフォーマットします)。

var Mustache = require('mustache');

var LANGUAGE = {
    general: {
        welcome: "Welcome {{name}}!"
    }
};

function _get_string(key) {
    var parts = key.split('.');
    var result = LANGUAGE, i;
    for (i = 0; i < parts.length; ++i) {
        result = result[parts[i]];
    }
    return result;
}

module.exports = function(key, params) {
    var str = _get_string(key);
    if (!params || _.isEmpty(params)) {
        return str;
    }
    return Mustache.render(str, params);
};

そして、これは私が文字列を取得する方法です:

var L = require('language');
var the_string = L('general.welcome', {name='Joe'});
5
Tzach

従来のJSコンポーネントで行われたことを確認する必要があります。Dojo、Ext、FCKEditor、TinyMCEなどを使用してください。多くの優れたアイデアが見つかります。

通常は、タグに設定した何らかの属性になり、属性の値に基づいて、タグのコンテンツを翻訳ファイルで見つかった翻訳に置き換えます。

心に留めておくべきことの1つは、言語セットの進化です(コードが進化するとき、全体を再翻訳する必要があるかどうか)。翻訳はPOファイル(Gnu Gettext)に保存され、POファイルをすぐに使用できるJSファイルに変換するスクリプトがあります。

加えて:

  • 常にUTF-8を使用してください-これはばかげて聞こえますが、最初からutf-8を使用していない場合(HTMLヘッド+ JSエンコーディング)、すぐに破綻します。
  • 英語の文字列を翻訳のキーとして使用します-このようにすると、次のような結果になりません:lang.Greeting = 'Hello world'-but lang ['Hello world'] = 'Hello world';
1
Bertrand Gorge

SpringバンドルとJavaScriptの場合、単純な解決策があります。テンプレート(例:JSP)でi18n配列を生成し、JavaScriptで使用します。

JSP:

<html>
<script type="text/javascript">
    var i18n = [];
    <c:forEach var='key' items='<%=new String[]{"common.deleted","common.saved","common.enabled","common.disabled","...}%>'>
        i18n['${key}'] = '<spring:message code="${key}"/>';
    </c:forEach>
</script>
</html>

そしてJSで:

alert(i18n["common.deleted"]);

i18n国際化のためのjavascriptのspring:messagesの解決 も参照してください。

0
GKislin