
過去6か月の間に、クールな〜100行のフレームワークを作成する方法に関する多くの記事がありました。 単一のフレームワークではなく〜2000行を記述する方法に関するタックルストーリー。
背景
技術的な部分に移る前に、問題の歴史について知りたいと思います。 「なぜ?」という質問に対して、
この記事は良い答えを提供します。
ローカリゼーションとインターナリゼーション
とは 、Anton NemtsevがエカテリンブルクのDUMPで講演しました。 アレクサンダー・ジェラシモフは、Frontend Dev Confでミンスクでタイポグラフィ
についてプレゼンテーションを行いました。 BadooのAlexander TevosyanがMoscowJS
の多言語サイトの
レイアウト機能について語り、同僚のGleb Deikaloが
多段階翻訳について書いています。 テキスト自体を簡単に翻訳できるように書く方法は、Translation Forum RussiaカンファレンスのHyperbatonに関する
Kristina Yaroshevichのレポートで既に議論されています。さらに、
Pavel Doroninは同様のトピックについて書きました。
Hyperbatonとは何ですか?ハイパーバトンは
スピーチの図です 。 最初は、なぜ会議を
パンと呼ぶのか長い間考えていました。 一般に、公開されたレポートを確認することをお勧めします。 言語学者以外にとっても興味深いものがたくさんあります。 たとえば、
Maxim Ilyakhov Habréでは、ローカライズに関連するさまざまなトピックに関する多くの記事を見つけることができます。 AlconostやABBYYなどの大企業は、パックで書き込みます。
上記の記事とレポートは多くの質問に答えます。 しかし、コードの編成の問題は部分的にしか説明されていません。 それでも、はい、私の本JavaScriptでのシュルレアリスムでは、ローカライズロジックとそのDOMでの動作について部分的に説明しました。 しかし、コードとその一般的な構造についてもう少し説明するときが来ました。
はじめに
なぜクライアントに?それはすべて私たちが解決しようとしている問題に依存しています。 私たちがサイトについて話している場合、サーバーはこちらのほうが優れています。 このアプリケーションの場合、クライアントにインフラストラクチャを展開することをお勧めします。 一方では、クライアントはオフラインで作業できます。 一方、クライアントがローカルファイルを使用する場合、サーバーリクエストを削減します。 さらに、サーバーがない場合や、サーバー開発者の時間が非常に高価であるため、このタスクの一部としてそれを費やすことは意味がありません。
なぜjavascriptで?フロントエンド開発者として、HTMLまたはCSSを選択できます。 HTMLの使用方法は、個人的には想像できません。 ローカリゼーションタスクの一部としてCSSを機能させる方法は、Anton Lunev(
http://habrahabr.ru/post/121075/ )によって書かれました。 しかし、最初のケースと2番目のケースでは、JavaScriptが提供する柔軟性と機会を失っています。
既製のものは何ですか?stackoverflowを備えたさまざまな30行の機能、およびBadoo、Yandex、Alconostなどからの内部ツールとは別に、現時点ではいくつかの非常に許容可能なソリューションがあります。
翻訳ストレージに関するアコーディオン
特定の言語のフレーズの翻訳が記述される変数があります。 さらに、アプリケーション全体で、フレーズ自体を使用する代わりに、対応する変数が置き換えられます。 したがって、変数の値を変更することにより、アプリケーション全体の言語を変更できます。

たとえば、ゲーム「Zhmuriki」では、すべてのフレーズの翻訳を別の変数に翻訳して書き留めました(
CARL VARIABLES!少なくともグローバルではないのは良いことです! )。 変数の操作は、次の2つの場合にうまく機能します。
- ハードウェアには厳しい制限があります(たとえば、安価なビデオコンソールをいくつかプログラムしています)。
- 同じ認証システムを使用しています(たとえば、スロットマシン用のソフトウェアを作成しています)。
最初のケースでは、リソースを削減し、メモリの制限を満たすためにすべてを厳しく保存する必要があります。 このような状況で優れた論理アーキテクチャを展開することは、常に可能ではありません。
2番目のケースでは、誤ってパラメーターを切り替える可能性さえも除外しようとしています。 同じスロットマシンを見ると、負ける可能性はすべて特定の国の法律によって厳しく規制されています。 したがって、ロシアに米国向けの機械があり、ブルガリアにハンガリー向けの機械がある場合は除外されます。
ゲーム「Zhmuriki」はVKontakteで動作し、上記の制限のいずれにも該当しません。 彼女の例では、ローカリゼーションシステムのコードとアーキテクチャの品質が何の役割も果たさないことを明確に示しています。 はい、誰かがコードをリファクタリングしたり、新しい機能を追加したりするのは不便かもしれません。 はい、おそらくこのアプローチはより多くのバグにつながるでしょう。 しかし、事実は、製品です。生産では、お金をもたらし、誰もが幸せです。
各フレーズを新しい変数に保存することはあまり便利ではなく、通常、翻訳自体は別の構成ファイルに転送されます。 そのため、ほとんどのローカリゼーションシステムの開発者は、JSONやXMLなどの情報の保存に一般的な形式を使用することを好みます。 通常、ほとんどのJavaおよびPython開発者はXMLを使用し、フロントエンド開発者はJSONを使用します。 慣れている人がいます 標準形式により、1つのプログラミング言語のコンテキストとまったく異なる言語のコンテキストの両方で、まったく異なるローカリゼーションシステムに同じ翻訳を簡単に使用できます。
他の方法で行った人はかなりいます。 そのため、RubyはYMLの使用を好み、フラッシャーはXLIFF、C`shniki-PO形式を好みます。たとえば、l20n.orgのメンバーは、タグと属性を持つ独自の形式を考え出しました。 それらを簡単に見てみましょう。
YmlYMLはXMLに似ており、人間が読めるだけです。 RegExpsを明示的に保存することもできます。
それは:
<translation> <hello>, !</hello> </translation>
次のようになりました:
translation: hello: ", !"
PO主にフリーソフトウェアのローカライズに使用されます。 簡単です。 開発者は、gettext()などの関数ですべての行をラップし、これらの行が翻訳のキーになります。 翻訳がない場合、元の文字列が置き換えられます。
msgid "Hello, World!" msgstr ", !"
なぜなら 上記の形式はどれもネイティブではなく、フロントエンドレンダリングに便利です。 ゲーム「Valley of Sweets」の翻訳付きファイルの例:

JavaScriptでJSON形式を使用する場合、一部のローカリゼーションシステムはネストされたプロパティをサポートしません。 上記のようなファイルの例を見ることができます。 これには、明白な翻訳構造が必要です。 ほとんどのローカリゼーションシステムでは、このような問題はなく、上記のコードは簡単に変換できます。
それは:
{ ... "inviteFriend": " ", "inviteFriend2Lines": "<br> ", "InviteFriend2Lines": "<br> ", ... }
次のようになりました:
{ ... "invite": { "friends": { "line1": " ", "line2": "<br> " }, "friend": "<br> ", ... }
このアプローチにより、翻訳の構造がより明確になります。 フレーズ識別子は「invite.friends」という形式を取り、次の形式の関数によってJSONオブジェクトから引き出されます。
function getProperty (json, key) { key = key.split(/[\.]+/gim); for (var i = 0, l = key.length; i < l; i++) { var propertyName = key[i]; if (!json[propertyName]) { return null; } json = json[propertyName]; } return json; }
次のステップは、この構造にケースを反映させることです。 数字が必要な場合があります。 典型的な例:「リンゴ2個」、「リンゴ1個」、「リンゴなし」。 すでに上記のl20nの人たちは、このような問題を解決しました。
<brandShortName { *nominative: "Aurora", genitive: "Aurore", dative: "Aurori", accusative: "Auroro", locative: "Aurori", instrumental: "Auroro" }>
そして、Angularを使用する人は次のように書きます。
{{numMessages, plural, one { } two { } other { } }}
たとえば、数字やケースの考えはまったく捨てました。 これ:
- 実際に個人的に出会ったことはありません。
- システムを非常に複雑にし、自動化に悪影響を及ぼします。
- エラーの可能性を劇的に増加させます。
- 品質要件と必要な翻訳の数を増やします。
- 「簡単なローカライズ」のルールと矛盾します(YaroshevichとIlyakhovのレポートを参照)。
- 原則として、インターフェイスで決定的な役割を果たさず、UIを変更することで簡単に不要になります。
リンゴの古典的な問題は、絵文字で解決できます。 以下に例を示します。
レッドアラートでのユニットの作成
MineCraft Inventoryおそらくこれは特定のゲーム構築ですが、通常のSPAアプリケーション(管理パネル、ユーティリティなど)では、そのようなカウンターを常に正しく、ケースなしで表示することもできました。
バナーシステムでの統計のクイック表示
CosmoSimゲームでは、パラメーターは数字と絵文字で表示されます。もちろん、それが好きかどうかにかかわらず、問題を解決しなければならない場合が多くあります。 そのような場合は、おそらく
Pavel Doroninによる記事か、「...」の松葉杖でしょう
。Replace (/.../ gim、 "...");
テンプレートの問題は何ですか?問題は、特定のテンプレートを作成するオプションがすぐに普遍的ではなくなることです。 ユニバーサルテンプレートはありません。 このオプションを自動化すると、コンテンツに関係なく、すべての行が正規表現によって処理されて変数が検索されます。 これは多くの余分な作業です。 これを回避し、最初にデータ内のテンプレートで行をマークすると、保存する必要があるデータの量が増えます。 したがって、テンプレートの操作は常に「正しい翻訳」対2つの椅子のある謎です。 「システムのシンプルさと汎用性。」
HTMLアコーディオン
翻訳の保存についてはすでに説明しましたが、今度はHTMLに切り替えます。 以下に書かれたほとんどすべてのものはすでに「JavaScriptのシュルレアリスム」という本にあり、NemnotsvとTevosyanは存在しなかったものを持っていました。
HTMLページのレイアウトについて話す場合は、何らかの方法でDOM要素をマークする必要があります。DOM要素の内部のテキストは翻訳が必要です。 原則として、開発者はさまざまな属性を要素に割り当て、この属性に翻訳IDを記述します。 例:
<p translate="hello">, !</p> <p data-i18n="hello">, !</p> <p data-l10n-id="hello">, !</p> <p data-localize="hello">, !</p>
しかし! 識別子とそれが適用されるタグによって取得された翻訳オブジェクトを分析する人はほとんどいません。 これが行われない場合、次のようなタスク:
- 入力フィールドの値とプレースホルダーを変更します。
- 画像を変更します。
- 接続されているフォントを変更します。
など 松葉杖によって決定されるか、まったく決定されません。 不適切なシステムを選択することで不快感を覚える状況の例は、次のコードです。
<img src="scheme_ru.png" alt=" " title=" 2114" translate="id__"/> <input type="text" placeholder=" " value=" " translate="id__"/> <link rel="stylesheet" type="text/css" href="css/ru.css" translate="id__"/>
ローカリゼーションシステムでは、受け取った翻訳のタイプとHTML要素のタイプを区別します。 したがって、タイプ文字列 "scheme_en.png"の翻訳を受け取り、HTML要素IMGを持っているため、ほとんどの場合、src属性を変更する必要があると想定できます。 INPUT要素を使用する場合、プレースホルダー属性の翻訳とLINKタイプがそれぞれ必要になる可能性が高く、他のパラメーターが指定されていない場合はhref属性を置き換えます。 さらに、要素を操作するためのルールが定義されていない、またはあいまいな状況では、「オブジェクト」タイプの翻訳を使用し、そのプロパティを列挙することで、作業しているタグの属性に値を割り当てます。 上記の例の翻訳を検討してください。
{ "id__": { "src": "scheme_uk.png", "alt": " ", "title": " і 2114", }, "id__": { "placeholder": "і ", "value": " " }, "id__": "css/ua.css" }
タグの属性を変更する機会があるので、さまざまな国のグループのインターフェースを変更する問題の解決にスムーズに進みます。 すでに何度も言われているように、「ローカライズ、これはテキストの翻訳だけでなく、特定の国の文化的特徴への製品の適合でもあります。」 したがって、スタイルを自動的に切り替えて写真を変更する機能が必要です。
少し痛みコメントと記事で繰り返し、私はあなたが国の旗と絵文字を表示すべきでないという意見を聞いた。 人が何かを知らない場合、彼は常に英語をオンにしてそれを理解します。 この観点に強く反対します。 事実、私は英語をあまり知らないということです。 悪い翻訳は、不在よりも私にとってはるかに優れています。 私のような人がたくさんいます。
ジョージアまたはイスラエルにまったく同じ男がいるとします。 これはこの国では普通の平均的な人です。 彼はあなたがグルジア語やイディッシュ語を見るのとほぼ同じ方法で英語を見るでしょう。 以下は、小さなHTMLゲームのスクリーンショットです。 ボタンの絵文字が表示されない場合、言語切り替えメニューにどのような試みがありますか? 言語に旗が付いていなかった場合、50か国語のスキスクを見て、どれくらい長く苦痛を感じますか?
ミラーリングすることを忘れないでくださいこれについて多くのことが言われているので、追加するものはありません。 要素を構成しましたか? 必ずrtl.cssを添付してください(
rtl-cssに役立ちます)。 ローカリゼーションシステムのすべてのRTLをリストします。 彼女は、どの場合に接続する必要があるかを知っている必要があります。

たとえば、次のように:
LanguageApplication({ rightRules: [ "module/button/button__right.css", "module/popup_text/popup_text__right.css", "module/progress_bar/progress_bar_right.css", "module/popup_window/popup_window__right.css", "module/popup_window/popup_window__animation_elements_right.css", "js/applications/language/language__right.css", "css/right.css" ] });
アーキテクチャアコーディオン
翻訳を保存するための可能な形式を簡単に説明し、HTMLで少し突っ込んだので、少し苦痛を加えることができます。 いい質問です。ローカライズが一般的な方法でどのように機能するかを見てみましょう。
ロシア語と英語の2つのファイルがあります。 User-Agentを使用して、ユーザーの言語を判別し、最初の言語または2番目の言語のいずれかを接続します。

簡単な作業で、すべてが美しく明確です。 ローカリゼーションシステムには、この原則に基づいたデモが表示されます。 しかし、それは私たちとは異なっていました。 複数のモバイルポータルが同じモジュールから組み立てられました。 ポータルは似ていましたが、一部のセクションは異なっていました。 ゲームを一方で、書籍をもう一方で販売しました。両方で曲を購入できます。 さまざまなオンライントーナメントとチャンピオンシップがありました。 ロシアでのみ実施されたものもあれば、CIS全体で実施されたものもありました。 リソースを生成しないために、翻訳はいくつかのファイルに分割されました。 特定のモバイルポータルごとに、これらの翻訳の組み合わせは異なりました。 なぜなら ロシア語版と英語版のセクションの数が一致しなかった(そして半分のケースが一致しなかった)場合、1つの組み合わせの翻訳数も1つのポータル内で言語から言語に変更されました。

図には何が見えますか? たくさんのファイル。 また、ファイルの各バンドルには、アセンブリ内の必要な翻訳の数、順序、およびバージョンを説明する構成ファイルが必要です。

「すごい! これですべてが正常になりました!」私はその瞬間に考えました。 しかし、ご想像のとおり、これは旅の始まりに過ぎませんでした。 半年後、私は心理テストの適用に関する仕事を始めました。 すべてがかなり平凡です:テストを選択し、質問に答え、壁に心理的な胸のサイズを公開します。 すべては問題ありませんが、ロシアではそのようなテストはすでに満杯です。 しかし、いくつかのチェコ共和国やクロアチアでは。 人口が少なく、プログラマーも少ない。 小さい市場は、大きなプレーヤーにとって魅力的ではありません。 したがって、ロシア向けの「最高のテスト」を作成して、1億4600万人まで、または400万人までが住んでいるクロアチアについても同じように勝つことができます。 今後、プロジェクトは失敗したと言いますが、開発段階では、これはまだ明らかではありませんでした。

何がありますか? アプリケーションの公開時点で約30のテスト。 各テストは序論であり、約10の質問と少なくとも3つの結論です。 このすべてに3つの言語が掛けられます。 合計:30 *(1 + 10 + 3)* 3 =少なくとも2000文字のボリュームを持つ複雑な構造の90の翻訳。 アプリケーションが「シュート」する場合、テストの数は2、3回増加し、転送の数は少なくとも5倍になります。 ユーザーがすべての言語のすべてのテストに合格しなくても、1ページのアプリケーションがあることを覚えておく必要があります。 そして、このアプリケーションはゆっくりですが着実にメモリを消費し、新しいテストのたびに消えてしまいます。
テストで何が飛ぶ? 多くの異なるファイルがテストとともに到着します。 それらの1つは、変換構成です。 このテストが利用可能なすべての言語について説明しています。 アドレスはそこに書き込まれ、そこから対応する翻訳がロードされます。
なぜなら 私たちのアプリケーションはモジュールで構成されており、インターフェースの翻訳が個別であり、各テストの翻訳が個別であることは明らかです。 前述のように、これによりリソースを再利用する機会が得られます。

画像を見て、「テスト翻訳」パッケージが「インターフェース翻訳」パッケージにどのように到着したかを見てください。 ローカリゼーションシステムは何をしますか? そうです、2つの構成を組み合わせ、3番目の構成を取得します。 そして、最終構成を流通させた後、彼女は今必要な翻訳について考え始めます。 彼女がすべてを考えてロードすると、結果を再度結合して、出力に単一のJSONを取得します。 JSONがフレーズの最終的な翻訳を形成するのはこのためです。

煙草を吸って、グレブ・デイカロに「挨拶」をする時が来ました。グレブ・デイカロは、前述のように、「多段階翻訳」について書いています。 構成と翻訳を組み合わせることで、彼の記事で説明したものと同じマルチステージを実現できます。 このためだけに、異なる言語のフレームワーク内の翻訳を所定の順序でマージする必要があります。
思い出に戻りましょう。 設定ファイルを上下に塗りつぶし、それらが結合される順序がわかったので、テストの完了後にメモリのクリアを試みることができます。 これを行うには、ダウンロードしたパッケージとそれが追加した翻訳を削除する必要があります。 次に、最終的な翻訳で残りを結合します。

良いことが判明しました。 これで、翻訳のブロック全体をメモリからロードおよびアンロードできます。 しかし、隣の部署の同僚は、より簡単で簡単な解決策を提案しました。テスト翻訳を1つの変数に書くことです。 したがって、後続の各テストの翻訳は、以前の翻訳を上書きします。 そのときまでに、上記のすべてがすでに2回実装されていたことは残念です。
なぜ2つ? 構成ファイルの構造を説明したときに間違っていたからです。 システムはオンラインとオフラインの両方の作業に共通である必要があることを上記ですでに書きました。 オフラインで作業する場合、JSファイルを直接接続することによってのみ翻訳をアップロードできます。 この初期化ファイルは、データオブジェクトを提供します。 なぜなら 将来、それを削除する予定です。IDでオブジェクトに署名する必要があり、同じIDを構成ファイルに保存する必要があります。 翻訳IDのリストを受け取った構成を削除すると、リクエストでダウンロードされたすべての翻訳も削除されます。 構成ファイルの構造を次のように説明しました。
{ id: "id ", translations: { ru: { b: "/lang/b.js", a: "/lang/a.js" } } }
「AからBへの転送」または「BからAへ」の更新を誰がロールしますか? 運が良ければ「A to B」ですが、彼はこれを行う義務はありません。 構造は配列ではないため、順序は重要ではありません。 さらに、別の間違いは、ファイルがアップロードされた順序がビルド順序に影響することでした。 したがって、私はやり直す必要がありました:
{ id: "id ", translations: { ru: [ { id: "b", url: "/lang/b.js" }, { id: "a", url: "/lang/a.js" } ] } }
これはローカリゼーションシステムですか? いいえ、これは構成読み込みシステムです。 私が犯したもう1つの間違いは、最初のバージョンではホテルクラスに割り当てなかったことです。 一般に、かなりの数の個別のクラスとモジュールが取得されます。
- 何らかの種類のファイルダウンローダー。 JSファイルはそれ自体をロードしません。
- 現在の言語のアイコンを描画し、選択可能な他のリストを表示するもの。
- 複数のオブジェクトと設定を1つに結合するためのピース(上記のように)。
- 少なくともメモリ用の最も単純なライブラリ(ユーザーが選択した言語を覚えておく必要があります);
ほとんどの「既製」ローカリゼーションモジュールでは、これはそうではありません。 なんで? おそらくそれらを書く人はめったに使用しないからでしょう。
興味深い事実:JSのローカライズシステムサイトはいずれもローカライズされていません。
カール! ローカライズを作成したとき、少なくともそれを自分で使用しました! カール自身が使用!オンデマンドでのみDOMを更新しますすべてのローカリゼーションシステムに、言語を切り替えてDOMツリーを更新する個別の方法があるわけではありません。 すべての翻訳の準備ができた直後に操作を完了する必要がある場合、これは困難を引き起こす可能性があります。 また、多くの実装では、各翻訳ファイルの読み込みが完了した後にDOMツリーが更新されます。 たとえば、言語を「アルメニア語」に切り替えました。 システムは、3つの翻訳ファイルのロードを開始します。メインインターフェース、設定、プラグインの翻訳です。 このような状況では、DOMを更新するのは1回だけです(リストの最後のファイルのロードが終了した後)。
英語、motherf **カー! 話せますか?
これでローカライズの準備ができましたか? いや! これで、このシステムを取り巻くインフラストラクチャを決定する準備ができました。 翻訳を含むファイルの形式と構造はプログラマーが決定し、その内容は翻訳者またはプロジェクトマネージャーが決定します。 これらの人々は、情報ストレージの選択された構造に精通しているだけでなく、それを受け入れて理解しようとする試みを放棄するかもしれません。 JSONオブジェクトの引用符を簡単に削除したり、XMLのタグを誤って削除したりする可能性があります。さらに、一般的に多くのユーザーがMicrosoft Word(DOCX)形式のファイルを使用することを好みます。
インフラストラクチャのタスクは、管理者にローカライズ用のツールを提供するだけでなく、翻訳の安定性とアセンブリと更新の容易さを保証することでもあります。 ローカリゼーションシステムは、多くの場合、インフラストラクチャエラーや不足に悩まされます。 翻訳でファイルを更新し、それらを最新の状態に保つのは非常に複雑であるため、多くの場合、1つまたは複数の言語が無効になります。
Mushroom Warゲームのマネージャーは、Excelスプレッドシートを使用して翻訳を処理します。翻訳はパーサーによって処理され、XMLドキュメントに変換されます。XMLドキュメントは、ローカリゼーションシステムがプロジェクトをビルドするために使用します。

Evilibriumのメンバーは、ファイルを直接操作しないことを決定し、Googleドキュメントでまったく同じタブレットを作成しました。 ロジックは単純です-翻訳者にリンクを送信することは、ファイルを送信するよりも簡単です。 したがって、誰もがオンラインで翻訳を行い、組み立て中にタブレットは同じ方法でダウンロードされ、目的のXMLに解析されます。

現時点では、翻訳を扱うための多くのオンラインサービスがあります。 誰かが良く、誰かが悪いが、ほとんど全員が翻訳者または翻訳者のグループとやり取りするタスクに対処します。 また、ほとんどのサービスは、アプリケーションを自動的に翻訳する機能を提供します。 このトピックに関するインターネット上の多くの記事がありますが、 この記事はボタンアコーディオンに関するものなので、独自の翻訳プログラムを作成しないのは罪です。
続行する前に、私が思うに、自動翻訳が正常である理由について少し説明したいと思います。 第一に、一連のルール(単純、簡潔、直接的な語順など)に従ってテキストを記述する場合、自動翻訳は90%の精度に達する可能性があります(Kristina Yaroshevichのレポートを参照)。
第二に、ほとんどのアプリケーションでは、オープン、クローズ、保存、ロード、新しいゲーム、終了、次へ、キャンセルなど、かなり標準的で不十分なフレーズのセットが使用されます。間違って翻訳するのは非常に困難です。第三に、あなたと私は、ロシア語のネイティブスピーカーとして、たくさんのrozumіtibagato mov slovyanskogo movno grupiを持っています。そのため、翻訳者がいなくても翻訳の重大なエラーをチェックできます。しかし、これは私の個人的な意見です。例えば、Pavel Doroninは彼の記事で、正反対の意見を堅持しました。次のアプリケーションをローカライズするために、翻訳を含むファイルをカットする必要がありました。翻訳を送ったフリーランサーは、常にJSONを壊していました。すぐに、JSONの代わりに、プレーンテキストを送信し始めました。最初の近似では、タスクはフリーランサーのテキストから有効なオブジェクトを取得することでした。このタスクのために、2ウィンドウアプリケーションが膝の上に作成されました(入力のテキスト、出力のJSON)。テキストをフレーズに分割する方法は?例を見てみましょう:TEXTAREAのテキスト: 1 2
普通の人が見ているように: 1 2
プログラマーが見ているように: 1\n 2
いいね!
テキストを分割できるシンボルがあります。また、それは隠されたシンボルであり、翻訳者は誤ってそれを壊したり拭いたりすることはできません(少なくともほとんどの場合)。 split()を介してテキストを配列に変換し、それをオブジェクトに置き換えます。これをJSON.stringify()に送り込み、必要な有効なファイルを取得します。
なぜなら
JSONテンプレートは異なる場合があります。別のファイルに配置することをお勧めします。そして、それを別のファイルに入れたので、JSONだけでなく生成するように教えてもいいですか?これらの考えに基づいて、「テンプレート生成」機能を編集できる別のウィンドウをプログラムに追加しました。入力では、翻訳されたフレーズの配列を受け取り、出力では、JSON、XML、または他の何かを返します。
次のアプリケーションの翻訳が必要になったとき、何らかの自動翻訳機を固定すれば、大幅に節約して翻訳の量を増やすことができると思いました。すぐに言ってやった。これで、プログラムはテキストを取得し、それを一連の言語に翻訳し、最終的な有効なJSONを生成できます。
その後、JSONフットクロスをJavaScriptファイルにカットするスクリプトを書き始めました。その後、彼は考えて、代わりにNodeJSに小さなローカルサーバーを作成しました。次に、Yandex.Translatorから次の転送を受信した後、プログラムはノードにデータを送信し始め、必要なファイルをその場でカットしました。結果は非常に満足しています。さて、小さなゲームには約45〜50の言語の標準翻訳が付属し始めました。したがって、ローカリゼーションは重要な場所ではないが、快適な追加であるいくつかの小さな製品がリリースされました。テストの結果、同じ場所で自動翻訳が誤っていることがわかりました。たとえば、「戻る」という単語は、「前」または「トム」として翻訳されます(「20年前」の意味)。なぜなら
フレーズは同じ松葉杖が現れ始めていた。ある時点で、それらを削除して辞書を追加することにしました。そのため、プログラムには3番目のウィンドウがあります。
これで、辞書には次のようなフィールドが含まれました。 { ru: { en: { "": "Back" ...
なぜなら
辞書の追加中に、アプリケーションを少しリファクタリングすることを決め、その後多くの変更を加えました。同時に、ローカライズについてもっと読むことにしました。その瞬間、Denis Lukyanovの記事「ソフトウェアローカリゼーションのための7つのオンラインサービスの概要」に出会い、この間ずっと自転車を書いていることに気付きました...さて、あなたは何ができますか、自転車は自転車です。原則から、私はそれを終えることを決め、最後の仕上げをしました。これで、ノードはすぐに翻訳を多数の形式(JS、JSON、XML、PO、YML、CSV)にカットし始め、これらのファイルを「クリーン」と「ダーティ」の2つのフォルダーに保存しました。 「ダーティ」フォルダー内のファイルを変更すると、ディクショナリ内の「同期」をクリックでき、ノードは検出された違いに応じてディクショナリを自動的に生成します。現在、同期は半分の形式でのみ機能します。プログラムをいじり続けるかどうかは明確ではありません。サイトに
アクセスして、その外観を確認したり、ダウンロードしたりすることもできます(設定のファイルへのリンク)。少なくとも10人が継続する必要があるために登録を解除した場合、私はそれを思い出させます。さらにいくつかの機能が必要です:- 設定を保存する 職場では、多くのプロジェクトを切り替える必要があります。
- ファイルを手動で転送せずにすぐに目的のプロジェクトのビルドに分類されるように、翻訳を保存する方法の選択。
- 保存形式の選択、として PO、YML、XML、JSONは実際には使用されません。毎回生成することは意味がありません。
理想的には起こりません1週間前にこの記事を書きましたが、上記の自転車のリファクタリングを止めることはできません。私は1つを書き直し、もう1つを書き直しました。3つ目の問題が修正されるまで、誰にも見せることはできません。一般に、これは実用的なプロトタイプと見なされます。
ローカライズなしのローカリゼーション
ローカリゼーションシステムは、まず、特定の定数セットの値の制御システムです。その中で選択された言語は、これらのセットを切り替えることができるキーです。キーを1か所で変更することにより、アプリケーション全体で定数を変更します。そして、この考えに気付いているなら、多分ローカリゼーションシステムの可能性を異なる角度から見てください。システムを非標準的に使用するいくつかのケースを一緒に見てみましょう。アプリケーションの外観を変更する
作業では、同じモジュールセットを使用して、コンテンツを販売する一般的なモバイルサイトを作成します。パートナーごとに、アイコンのセットも含むいくつかのスタイルを変更します。さらに、休日やプロモーションでは、特定のサイトの外観を変更して、ターゲットオーディエンスに適したムードを作成します(たとえば、新年のスタイルや「バレンタインデー」を称えるテーマ)。同じレイアウトテンプレートを使用するには、それらからイメージアドレスを削除する必要がありました。このような各画像に特定の識別子を付け、JSONオブジェクト内のすべてのアドレスを対応するキーで書き留めました。システムが機能するためには、現在の構成とテーマに基づいて、すべての写真を現在のアドレスに自動的に登録する特定のメカニズムが必要でした。だからこのメカニズムは、一方で設定を受け取り、他方で特定の識別子で値を返す必要があります。また、DOMが既に形成されている場合は、DOMツリーを調べて、マークされたすべての画像を自分で更新できるようにしたいと思います。説明したシステムの機能は何も思い出させませんか?画像アドレスを持つJSONオブジェクトの例: { header: { menu: { normal: "/images/201409/menu__normal.png", hover: "/images/201409/menu__hover.png" }, search: "/images/201407/search__blue.png" }, ... footer: { icon: "/images/201408/question.png", up: "/images/201407/up.png" } }
このような一対一のメカニズムは、ローカリゼーションシステムのロジックを繰り返します。もしそうなら、なぜそれを作成するのですか?ローカリゼーションモジュールにこの作業を強制することができます。言語値として目的のトピックの名前のみを使用します。さらに、前述のように、ローカライズシステムはプラグインスタイルのアドレスを変更することもできます。これは、プラグインCSSコードを含む制御を取得することを意味します。同じ設定ファイル内で翻訳と言語を混在させたくない場合は、OOPなしで行うことはできません。OOPは、異なる目的(1つは翻訳をロールし、もう1つはスタイル)のためにローカライズの2つのインスタンスを作成する方法の質問に答えます。数式の係数の変更ゲーム機用のソフトウェアを開発するUnicum社のプログラマーも、ローカリゼーションファイルに数学的係数を含めて賞金を計算しました。これは、ゲームの法律がソフトウェアを使用する国によって大きく異なる場合があるためです。したがって、たとえば、スロットマシンの賞金の平均割合は、60%から95%の範囲で変動する可能性があります。さらに、さまざまな難易度のゲームを開発する場合、ローカリゼーションシステムを使用して、ゲームのバランスに影響する係数を保存し、すばやく変更することもできます。ストーリーの変更ゲームのプロットがグラフとして記述され、JSONオブジェクトとして保存され、オブジェクトのマージ操作を実行できるローカリゼーションシステムに渡される場合、メインストーリーラインにパッチと追加を作成できます。ただし、複数のストーリーライン自体を作成し、ゲームの開始時にそれらをランダムに選択することもできます(キーは「選択された言語」ではなく、「選択されたプロット」です)。ゲームルールの変更ブラックジャックとポイントゲームの違いは何ですか?あまりない。主な違いは、デッキではなく36枚のカードの数です。オンラインブラックジャックを書いた場合(半年前に書いたように)、JSONでデッキを詰め込み、ローカリゼーションシステムのインスタンスに入れて、設定にオプション「ルールの切り替え」を追加します。手首を軽く動かすだけのローカリゼーションシステムが、ゲームルールを選択するシステムに変わりました。まとめと結論
JavaScript:- JSONまたはXML形式で翻訳を保存します。
- 翻訳をモジュールに分割します。
- オンデマンドでのみDOMを更新します。
- メモリを消去します。
- 言語を選択する機会を提供します。
- 行った選択を覚えておいてください。
アセンブリシステムについて考えます。- 翻訳者からのデータをプログラマー向けの形式に変換します。
- 個々のモジュールのグループを1つの最終版に翻訳します。
Denis Lukyanovの完成品を選択します。レイアウト時:- RTLについて考えます。
- テキストの長さを制限します。
- 翻訳へのポインタは属性内になければなりません。
- 疑似要素を介してCSSで翻訳を書こうとしないでください。
rtl-cssを使用し、Alexander Tevosyanを見てください。テキスト:- UTF-8で保存。
- フォントはすべての言語をサポートする必要があります。
- 擬似ローカリゼーションを使用したテスト。
- 過度の最適化を避けます。
Pavel Doroninを読みます。テキストで、次を削除します。- 同義語;
- 削減;
- 分詞;
- 動詞名詞;
- 受動態
- 無意味な動詞;
- 非個人化された構造;
- 前置詞、で;
- 口実のない多くの場合;
- 言葉の省略;
Kristina Yaroshevichを表示します。追加:情報スタイルの場合:- ストップワードを削除します。
- 構造を強調表示します。
- 画像と情報を複製します。
章を使用します。編 、Maxim Ilyakhovを見て、スクリーンショットを準備してください。いくつかの利点:言語とその名前 { ar: "عربي", // az: "Azərbaycan", // be: "і", // bg: "", // bs: "Bosanski", // ca: "Català", // cs: "Čeština", // da: "Dansk", // de: "Deutsch", // el: "Ελληνικά", // en: "English", // es: "Español", // et: "Eesti", // fa: "فارسی", // fi: "Suomi", // fr: "Français", // he: "עברית", // hr: "Hrvatski", // hu: "Magyar", // hy: "Հայ", // ja: "日本語", // id: "Indonesian", // is: "Ljóðmæli", // it: "Italiano", // ka: "ქართული", // kk: "Ққ", // ko: "한국어", // ky: "", // lt: "Lietuvių", // lv: "Latviešu", // mk: "", // ms: "Melayu", // mt: "Malti", // nl: "Nederlandse", // no: "Norsk", // pl: "Polski", // pt: "Portuguesa", // ro: "Română", // ru: "", // sk: "Slovenskej", // sl: "Slovenski", // sq: "Shqiptare", // sr: "", // sv: "Svenska", // tg: "ҷӣ", // th: "ไทย", // tr: "Türk", // tt: "", // uk: "ї", // vi: "Việt nam", // zh: "中国" // }