エントリー
ほとんどのWeb開発者は、Webサイトを複数の言語に翻訳する必要がありました。 ミッションは非常にシンプルで、ソリューションは原則としてルーチンを指します。 ローカリゼーションはプロジェクトの退屈で非創造的な部分であるという声明に多くの人が同意すると確信しています。
この記事では、議論のために別のウェブサイト翻訳モデルを紹介したいと思います。 原則を1つの文で説明しようとすると、次のようになります。CDNは、ユーザーと元のソースの間でコンテンツを翻訳します。
翻訳の必要性
リソースの多言語性の利点を証明する価値があるとは思いませんが、それでも、これに小さなパラグラフを1つ当てます。
デフォルトでは、地球上の30億人のユーザーがインターネットサイトにアクセスできます-単にあなたのサイトがインターネット上にあるからです。 サイトで何かを販売する場合、言語を追加するだけで、実際に新しい市場に参入できます。 W3Techsによると、英語はインターネットコンテンツの半分であるため、少なくとも、現地語(ビジネスを行う地域の言語)と英語版のバージョンが必要になります。
既存の方法
翻訳ファイル
GNU gettextのような特別な形式から、現在のフレームワークで使用できるシンプルなテキストファイルまで、さまざまなオプションがあります。 結果はほぼ同じです。テキスト出力の時点で、辞書の翻訳をチェックする関数が呼び出されます。
PHPの例:
// gettext: echo _(", !"); // Laravel 5 echo trans('common.hello_world');
この方法の利点:
- 何十年にもわたって実証された方法(通常の説明を読んでください);
- 個々のファイルをサードパーティの翻訳者に単純に提供する機能。
- コードへの影響はほとんどありません。
メソッドの短所:
- 原則として、即座に変更を加える可能性はありません。
- gettext辞書をコンパイルし、最終ファイルをリポジトリにコミットする必要があります。
- テキスト管理が比較的不便で遅いため、プロジェクトが大きくなるほど、ファイルが多くなり、階層がわかりにくくなります。
- 翻訳者チームが翻訳に取り組むための標準的なメカニズムはありません。
- 原則として、2つのスキームが並行して使用されます-バックエンドの翻訳とフロントエンドの翻訳(JavaScript)。
- プログラマーがHTMLタグを引き出すのは不便だったため、HTMLタグは翻訳用のテキストに時々表示されます。
データベース翻訳
最初の方法とは異なり、翻訳はプロジェクトデータベースに保存されるため、外出先で調整を行うことができます。 原則として、プロジェクト開発者は管理者用の翻訳コントロールパネルを作成しますが、これには余分な時間がかかります。
この方法の利点:
- チームの作業を整理しやすい。
- すぐに変更を加える機能。
メソッドの短所:
- 翻訳のためのセクションをサードパーティの翻訳者に提供することはより困難です。
- フロントエンドテキストは、引き続きバックエンドテキストとは別に翻訳されます。
- プログラマーがHTMLタグを引き出すのは不便だったため、HTMLタグは翻訳用のテキストに時々表示されます。
JavaScriptを介したユーザー側の翻訳
比較的新しい方法であり、現在、いくつかの西洋のスタートアップによって提供されています。 外部JavaScriptファイルへのリンクを追加するだけで、事前に提供された(または承認された)翻訳に基づいてDOM内のテキストの置き換えが開始されます。
この方法の利点:
- プログラミングがほとんどまたはまったくない簡単なインストール。
- フロントエンドとバックエンドは、1つの翻訳リポジトリから同時に翻訳されます。
- すべてのテキストはDOMから事後的に処理されたため、テキストリポジトリにはHTMLタグはありません。
メソッドの短所:
- 検索エンジンには追加の言語は表示されません。
- ソーシャルネットワークでリンクを共有することもできません。
- サイトを開くときの追加のネットワーク負荷(遅延のリスクを読んでください)。
CDNトランスレーター
実際、この記事で議論するために提起されたもの。 しかし、ユーザーとサイトの間に「レイヤー」が挿入されるとどうなるでしょうか?Webコンテンツを翻訳できるエッジサーバーでしょうか? CloudFlareなどのサービスは、クライアントページを最小限に変更する方法を既に知っています。たとえば、Googleアナリティクスコードを追加します。 さらに一歩踏み込んで、ユーザーがテキストとリンクを置き換えることを許可したらどうなりますか?
従来のCDNの動作:
- クライアントはアドレスXを要求します。
- アドレスXがキャッシュ内にある場合、キャッシュからすぐに返されます。
- Xアドレスがキャッシュにない場合、エッジサーバーは元のサイトに要求を作成し、クライアントに応答を返します。 元のサイトの応答のヘッダーとサイトに設定されたルールに応じて、リソースXをキャッシュできるようになりました。
![](https://habrastorage.org/files/157/6c0/cac/1576c0cacd7a4dc99dfb83d31802f0aa.jpg)
CDNトランスレーターの動作:
- クライアントはアドレスXを要求します。
- アドレスXがキャッシュ内にある場合、アドレスXはそのままキャッシュから返されます。
- Xアドレスがキャッシュ内にない場合、エッジサーバーは元のサイトに要求を作成し、突然変異ルールを適用します-リンクを置き換え、翻訳されたテキストを置き換えます。 元のサイトの応答のヘッダーおよびサイトに設定されたルールによっては、リソースXがキャッシュされる場合があります。
ステップ2bの詳細
元のサイトから応答を受信した後、ボーダーサーバーは、翻訳方法のタスクに直面します。 推奨される戦術:
- Content-typeヘッダーに注意してください。 サポートされている値のリストに値が含まれていない場合、コンテンツを変換しようとしないでください。
- 回答のサイズに注意してください。 サイズが設定された境界を超える場合-コンテンツを変換しようとしないでください。
- コンテンツの解析と編集を開始します。 HTMLページの例:テキストの子孫ノードを持つすべてのDOMノードをウォークスルーします。 リポジトリ内の翻訳済みテキストを要求し、ソーステキストとコンテキストをパラメーターとして渡します。
- コンテンツの必要な部分を置き換えて、結果をユーザーに返します。 ヘッダーとルールが許可する場合、結果をキャッシュします。
リポジトリを独立したRESTful APIとして実装することは論理的であり、URL:セレクターなどのコンテキストを設定すると便利です。 たとえば、「ニュース」で始まるページの任意のブロックで「メインページ」という単語を「ホーム」として翻訳したい場合、コンテキスト「/ニュース*:頭」を取得します。 世界はCSS / jQueryスタイルのセレクターに非常に慣れているので、ほとんどすべての開発者がこの構文をすぐに使い始めることができます。
ボーダーサーバーはリポジトリAPIへの翻訳を要求するため、一般的な言語とフレームワークのSDKとパッケージの実装は完全に論理的になります。 ウェブサイトの所有者には選択肢が与えられます。CDNを介してコンテンツを翻訳したり、既存のコードのクラスを通じて翻訳したりできます。
PHPアプリケーションがあり、Laravelフレームワークを使用するとします。 レガシーサポートの実装は簡単です。trans()ヘルパー関数を再宣言し、ローカルテキストファイルではなくリモートAPIで検索を実行する実装に置き換えます。 各リクエストでの遅延を避けるために、キャッシュまたは個別のプロキシプロセスを使用します。
同様に、JavaScriptオブジェクト、グラフィックスなどのコンテンツを変更できます。
この方法の利点:
- アプリケーションと翻訳の完全な抽象化-アプリケーションは、他の言語バージョンの可用性についてまったく知りません。 プログラマーは冷静にメイン製品に取り組みます。
- バックエンドとフロントエンドのコンテンツは、1つの翻訳リポジトリを使用して同時に翻訳されます。
- グラフィック画像を簡単に翻訳できます。
- 他の(別個の)ドメインでサイトの翻訳バージョンを実行するのは非常に簡単です。
- 既存のCDNサービスと互換性があります。 チェーンに配置できます。
- 検索エンジンおよびソーシャルネットワークとの互換性。
- すべてのテキストはDOMから事後的に処理されたため、テキストリポジトリにはHTMLタグはありません。
- チームワークを整理しやすい。
メソッドの短所:
- 私は見つけることができませんでしたが、私はこれを手伝ってくれてとてもうれしいです!
YouTubeビデオ
概念を明確に説明するために、このような翻訳システムのプロトタイプを示す非常に短いビデオクリップを撮影しました。 英語の物語ですが、ロシア語の字幕を追加しました。
実装
提案された方法の実現可能性と実用性をすでに確認しました-PHPとLumenでボーダーアプリケーションのプリミティブバージョンを作成しました。
ユーザーからのリクエストを受信し、翻訳されたレスポンスを返す私の方法:
/** * @param Request $request * @param WebClientInterface $crawler * @param MutatorInterface $mutator * @param TranslatorInterface $translator * @return Response */ public function show(Request $request, WebClientInterface $crawler, MutatorInterface $mutator, TranslatorInterface $translator) { $url = $request->client['origin'] . parse_url($request->url(), PHP_URL_PATH); $response = $crawler->makeRequest($request->getMethod(), $url); if ($response === false) abort(502); $mutator->initWithWebRequest($response); if ($response->isTranslatable()) $mutator->translateText($translator); if ($response->isCacheable()) $mutator->cache(60); $mutator->replaceLinks($request->client['origin'], $request->getSchemeAndHttpHost()); return (new Response($mutator->getBody(), $mutator->getStatusCode())) ->withHeaders($mutator->getHeaders()); }
プロセッサの負荷のために多くの人がパラダイムを疑うようになると確信しています-結局のところ、同じnginxは何らかの方法で回答の内容を変更したくないため、パフォーマンスに非常に悪影響を及ぼすでしょう。 一般的に、このように翻訳すると、事後の事実は確かにリソースの点でより高価になります。
私の主張は次のとおりです。 過去5〜10年にわたってITリソースのコストが常に減少していることを目の当たりにしているため、サーバーが5ドルの時代になりました。多くのサイトでは、負荷を少し増やすことはそれほど怖くありません。 第二に、私がこのプロジェクトに関与した場合、パフォーマンスの最適化が優先分野の1つになります。 確かに、改善のための多くの場所を見つけることができます!
おわりに
業界は常に最適化、快適性の向上、コスト削減に向かっています。 Webアプリケーションのローカライズの提案された方法は、5〜10年後には主な方法になる可能性が高いと思います。
さらに、CDNは構造として、ますます新しいアプリケーションを持つ場合があります。 CloudFlareは世界のDDoS保護を提供し、Imgixはその場でレスポンシブ画像を作成します。