文字列とラベルのローカライズとグローバリゼーションのベストプラクティス[終了]


124

私は20人以上の開発者がいるチームのメンバーです。各開発者は個別のモジュール(10モジュールに近いもの)で作業します。各モジュールには少なくとも50のCRUDフォームがある可能性があります。つまり、現在、500近くの追加ボタン保存ボタン編集ボタンなどがあります

ただし、アプリケーションをグローバル化したいので、アプリケーション内のテキストを翻訳できる必要があります。たとえば、フランス語のユーザーにとっては、どこでも「追加」という単語が重要になります。

これまでに行ったことは、UIまたはプレゼンテーションレイヤーのビューごとに、翻訳のキーと値のペアのディクショナリがあることです。次に、ビューのレンダリング中に、この辞書を使用して必要なテキストと文字列を翻訳します。ただし、このアプローチでは、500の辞書に500 近くの追加ができるようになりました。これは、DRYプリンシパルに違反したことを意味します。

一方、addを1か所に配置するなど、共通の文字列を集中化し、開発者にそれをどこでも使用するように依頼すると、集中化された辞書で文字列がすでに定義されているかどうかわからないという問題が発生します。

他の1つのオプションは、翻訳辞書を持たず、Google翻訳、Bingトランスレータなどのオンライン翻訳サービスを使用することです。

私たちが遭遇したもう1つの問題は、プロジェクトを予定どおりに納品するというストレスの下にいる一部の開発者が翻訳キーを思い出せないことです。たとえば、追加ボタンのテキストの場合、開発者はaddを使用し、別の開発者はnewを使用しています。

アプリケーションの文字列リソースのグローバリゼーションとローカリゼーションのベストプラクティス、または最もよく知られている方法は何ですか?


2
によるアレックス・セクストントピックに関するクライアント側の国際 JS EU会議からは良いスタートです。
Minko Gechev 2013年

回答:


51

私の知る限りlocaleplanet、JavaScriptのローカリゼーションとインターナショナリゼーションのために呼ばれる優れたライブラリーがあります。さらに、それはネイティブで他のライブラリ(jQueryなど)への依存関係がないと思います

これが図書館のウェブサイトです:http : //www.localeplanet.com/

Mozillaによるこの記事もご覧ください。クライアント側の翻訳に最適な方法とアルゴリズムを見つけることができます。http//blog.mozilla.org/webdev/2011/10/06/i18njs-internationalize-your-javascript-with- a-little-help-from-json-and-the-server /

すべてのそれらの記事/ライブラリの共通部分は、彼らが使用していることであるi18nクラスとget(またのような小さな関数名を定義するいくつかの点で方法を_/取り出す変換するため)keyvalue。私が説明する中で、key翻訳したいvalue文字列と翻訳された文字列を意味します。
次に、あなただけの店にJSONドキュメントを必要とするkeyのとvalueの。

例えば:

var _ = document.webL10n.get;
alert(_('test'));

そしてここにJSON:

{ test: "blah blah" }

現在人気のあるライブラリソリューションを使用することは良いアプローチだと思います。


1
違反はありませんが、これはアフシンがすでに試みたことではありませんか?彼の問題は、さまざまな開発者がどのキーを使用するかを覚えるのが難しいことです。あなたの説明した方法が進むべき道であることに同意します。それ以外の場合はどうなるかわかりません。素晴らしいリンクをありがとう。
Spock

47

あなたが解決すべき問題に直面したとき(そして率直に言って、最近では誰がそうではないのか?)、私たちコンピューターの人々が通常採用する基本的な戦略は、「分割統治」と呼ばれます。こんなふうになります:

  • 特定の問題を一連の小さな副問題として概念化します。
  • それぞれの小さな問題を解決します。
  • 結果を特定の問題の解決策に結合します。

しかし、「分割統治」だけが可能な戦略ではありません。より一般的なアプローチを取ることもできます。

  • 特定の問題をより一般的な問題の特殊なケースとして概念化します。
  • どういうわけか一般的な問題を解決します。
  • 一般的な問題の解決策を特定の問題に適合させます。

-エリック・リペルト

ASP.Net/C#などのサーバー側の言語には、この問題の解決策がすでに多数あると思います。

問題の主要な側面のいくつかを概説しました

  • 問題:必要な言語のデータのみをロードする必要がある

    解決策:この目的のために、データを言語ごとに個別のファイルに保存します

例。res.de.js、res.fr.js、res.en.js、res.js(デフォルト言語用)

  • 問題:各ページのリソースファイルを分離して、必要なデータのみを取得する必要がある

    解決策https://github.com/rgrove/lazyloadのような既存のツールを使用できます

  • 問題:データを保存するには、キーと値のペア構造が必要です

    解決策:文字列/文字列airではなく、javascriptオブジェクトをお勧めします。IDEからインテリセンスを利用できます

  • 問題:一般メンバーは公開ファイルに保存され、すべてのページがそれらにアクセスする必要があります

    解決策:この目的のために、Global_Resourcesという名前のWebアプリケーションのルートにフォルダーを作成し、「Local_Resources」という名前のサブフォルダーごとにグローバルファイルを保存するフォルダーを作成します

  • 問題:各サブシステム/サブフォルダー/モジュールメンバーは、スコープのGlobal_Resourcesメンバーをオーバーライドする必要があります

    解決策:それぞれのファイルを検討しました

アプリケーションの構造

root/
    Global_Resources/
        default.js
        default.fr.js
    UserManagementSystem/
        Local_Resources/
            default.js
            default.fr.js
            createUser.js
        Login.htm
        CreateUser.htm

ファイルに対応するコード:

Global_Resources / default.js

var res = {
    Create : "Create",
    Update : "Save Changes",
    Delete : "Delete"
};

Global_Resources / default.fr.js

var res = {
    Create : "créer",
    Update : "Enregistrer les modifications",
    Delete : "effacer"
};

目的の言語のリソースファイルは、Global_Resourceから選択したページに読み込まれる必要があります。これは、すべてのページに読み込まれる最初のファイルである必要があります。

UserManagementSystem / Local_Resources / default.js

res.Name = "Name";
res.UserName = "UserName";
res.Password = "Password";

UserManagementSystem / Local_Resources / default.fr.js

res.Name = "nom";
res.UserName = "Nom d'utilisateur";
res.Password = "Mot de passe";

UserManagementSystem / Local_Resources / createUser.js

// Override res.Create on Global_Resources/default.js
res.Create = "Create User"; 

UserManagementSystem / Local_Resources / createUser.fr.js

// Override Global_Resources/default.fr.js
res.Create = "Créer un utilisateur";

manager.jsファイル(このファイルは最後にロードする必要があります)

res.lang = "fr";

var globalResourcePath = "Global_Resources";
var resourceFiles = [];

var currentFile = globalResourcePath + "\\default" + res.lang + ".js" ;

if(!IsFileExist(currentFile))
    currentFile = globalResourcePath + "\\default.js" ;
if(!IsFileExist(currentFile)) throw new Exception("File Not Found");

resourceFiles.push(currentFile);

// Push parent folder on folder into folder
foreach(var folder in parent folder of current page)
{
    currentFile = folder + "\\Local_Resource\\default." + res.lang + ".js";

    if(!IsExist(currentFile))
        currentFile = folder + "\\Local_Resource\\default.js";
    if(!IsExist(currentFile)) throw new Exception("File Not Found");

    resourceFiles.push(currentFile);
}

for(int i = 0; i < resourceFiles.length; i++) { Load.js(resourceFiles[i]); }

// Get current page name
var pageNameWithoutExtension = "SomePage";

currentFile = currentPageFolderPath + pageNameWithoutExtension + res.lang + ".js" ;

if(!IsExist(currentFile))
    currentFile = currentPageFolderPath + pageNameWithoutExtension + ".js" ;
if(!IsExist(currentFile)) throw new Exception("File Not Found");

それが役に立てば幸い :)


7
このアプローチについて私が気に入らない唯一のことは、ローカリゼーションと開発が密に結合されていることです...したがって、英語(デフォルトは何でも)の文字列が追加されると、残りの言語はコードを通じて更新する必要があります。あるタイプの翻訳ファイルからツールでJSONを作成したいのですが。まだ良い表現!
Nate-Wilkins 2013

ローカリゼーションの場合と同じ方法で、このクエリを確認できます:stackoverflow.com/q/53864279/4061006。唯一のことは、Global_Resources / default.jsをGlobal_Resources / default.fr.jsに変換する方法です。これらのファイルを目的の言語に変換するために使用しているツール/キット。私もこれが必要なので
Jayavel

新しい言語を追加するときに翻訳者(または自分)により多くのコンテキストを提供し、一部の言語を忘れた場合に備えて、文字列の位置と意味を説明する各キーの横に人間が読めるコメントを保存する必要があります。文字列の意味。たとえば、Chrome拡張機能ローカライズする"Create" : {"message": "Create", "description": "text on the button that opens the editor with a blank Foo"}場合と同じようにします。または、これらのコメントを保持する別のファイルを作成します。
ボリス

13

jQuery.i18nは、Webページの国際化を可能にする軽量のjQueryプラグインです。Javaリソースバンドルと同様に、カスタムリソース文字列を「.properties」ファイルにパッケージ化できます。提供された言語またはブラウザから報告された言語に基づいて、リソースバンドル(.properties)をロードして解析します。

詳細については、JQueryを使用してページを国際化する方法をご覧ください。


リンクがなくなりました
Alexander Farber
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.