web-dev-qa-db-ja.com

リソースの一部をどのようにフォーマットしますか?

ASP.NET MVCでWebアプリケーションを構築していて、フォーマットされたテキストを表示する必要があるとします。非常に簡単な例は次のとおりです。

以下のリンクをクリックするか、キャンセルするには ここ をクリックしてください。質問がある場合は、カスタマーサービスにお問い合わせください。

リソースファイルには何を格納し、ビューにはインラインで何をコーディングしますか?

たとえば、リンクのターゲットをリソースにハードコーディングしますか?または、{0}を入れて、ビューにstring.Formatを入力しますか?または、リンクテキストを別のリソースとして保存し、ターゲットを含むマークアップをビューに配置しますか?

指示が長く、表形式で表示する必要がある場合はどうなりますか? <TABLE><TR>および<TD>タグをリソースに挿入しますか?または、これらのタグをビューに配置して、各セルのリソースを作成する必要がありますか?

一部のリソースにHTMLマークアップを配置する場合は、Razorで採用されている自動HTMLエスケープメカニズムを回避する必要があります(例: se Html.Raw )。直接挿入できるリソースとエスケープ解除が必要なリソースをどのように覚えていますか?フォーマットされたリソースを別のリソースファイルに保存しますか?命名規則を使用しますか?指を交差させますか?

結論:リソースのフォーマットpartの一般的な要件にどのように対処しますか?

4
John Wu

ASP.NET MVCでは、HTMLコンテンツはビューに属し、ローカライズされた文字列はリソースファイルに属します。

両方を混在させる必要がある場合、つまりローカライズされたHTMLコンテンツが必要な場合に問題が発生します。いくつかの選択肢があります:

  • HTMLをリソースファイルに配置します。これは最悪の解決策であり、十分な理由がない限り回避する必要があります。問題は、Html.Rawを使用してそのまま出力する必要があるHTMLと適切にエスケープする必要があるユーザーコンテンツを処理することが非常に複雑になるだけでなく、IDEからのサポートの完全な欠如です。構文の強調表示さえありません。

    また、リソースに保存されているHTMLに動的コンテンツを挿入することが不可能になることも意味します。最悪の場合、自分が何をしているのかよくわからないプログラマーのチームにいる場合、誰かがリソースからHTMLに動的コンテンツを挿入するためのプレースホルダーのシステムを作成することによって、車輪を再発明することになります。

  • ローカライズされたHTMLコンテンツを、カルチャーごとに1つのビューに配置します。

    このアプローチの利点は、個々のビューが読みやすく、維持しやすく、ソースがブラウザーに表示される結果に非常に近いことです。

    ただし、欠点は、ローカライズされたすべてのビューで同じマークアップを変更する必要があることです。たとえば6つの言語をサポートする必要がある場合、すべての変更を6回複製する必要があります。

  • 翻訳されたコンテンツのないHTMLをビューに配置し、対応するローカライズされたリソース文字列をビューから呼び出します。

    このアプローチの利点は、マークアップを1回だけ指定できることです。

    ただし、コンテンツの変更は面倒です。たとえば、1つのWordを含む段落を斜体で追加するには、3つの追加のリソース文字列を作成し、それらの翻訳を作成して、新しいマークアップで使用する必要があります。

    より微妙な問題は、リソースベースのアプローチと同じです。ローカリゼーションは、プレースホルダーを埋めるだけではありません。時には、文全体を変更する必要があります。場合によっては、コンテンツの順序を変更する必要があります(たとえば、[Cancel] the previous actionの場合、一部の言語では、キャンセルボタンの前にbeforeキャンセルボタンが必要になります)。私が間違っていなければ、ドイツ語);場合によっては、別の色または別のアイコンセットを使用する必要があります。 ¿...?をスペイン語で記述するのと同じように、英語で...?を英語で記述するのと同じくらい基本的なことは、マークアップ、動的コンテンツ、プレースホルダーを混在させると非常に複雑になる可能性があります。

    したがって、ローカライズされたビューは、より柔軟なソリューションであるように思われ、長期的には、メンテナンスが少なくて済みます。例外は、異文化へのコンテンツの微妙な適応について誰も本当に気にかけない状況で、膨大な数の言語(20以上)をサポートする必要がある状況です。


I私が多く楽しんでいる1つの例は、何十もの言語をサポートする必要があったWebアプリのリクエストを一度受け取ったことです。ページには「6商品」と書かれた商品のカウンターがありました。いくつかの数字ではうまくいきましたが、他の数字ではうまくいきませんでした。「1つの製品」は、英語の文法に関しては特に正しくありませんでした。したがって、製品の所有者は、必要に応じて適切なバリアントを表示できるかどうかを尋ねました。所要時間の見積もりを出したとき、POは私が狂っていたように私を見ました。「なぜ、あなたは必要なのか 「製品」バージョンを追加して、番号が1の場合はそれを表示するだけですか?コードは1行にする必要があります。」したがって、私はif n == 1ルールが英語ではtrueである可能性があることを説明し始めましたが、ロシア語などの言語ではそうではありません。 2、3、または4で終わるが12、13、および14で終わらない数値、およびその他の場合は3番目の形式。サポートするカルチャが増えると、導入するルールも増えます。これは、リソース文字列を追加するよりもはるかに複雑です。


元の回答:

ASP.NET MVCを代わりに(特にMVC Webアプリのコンテキストで)使用できないのは残念です。ASP.NETMVCには、特別にパーシャルビューと呼ばれるメカニズムがあります。 。リソースファイルを処理する必要はありません(これには、構文の強調表示を備えた適切なエディターの欠如やバージョン管理における不自然な差異など、多くの欠点があります)代わりに、HTMLコンテンツをビューの中に配置します。それを他のページに含めます。

ASP.NETでは、似たようなメカニズムがser controlになる可能性があり、後でRenderPartialを使用して含めます。ユーザーコントロールを使用すると、パラメーターをパラメーターに渡すことができるため、URIを渡すことができます。次に、値をHTMLに挿入するだけです。

部分ビューとユーザーコントロールのどちらにも、マークアップとロジックの両方を後で比較的簡単に追加できるという追加の利点があります。これは、リソース文字列では得られないものです。

そう:

  • それが属している場所、つまりビュー内にHTMLを保持します。
  • ローカライズされた文字列を格納するという主な目的でリソースを使用します。
1

私は、年間700万人の乗客を移動する運送会社の予約エンジンを維持および開発するチームの一員でした。予約エンジンは、10の異なるロケールで利用できます。ロケールはすべて、さまざまなコンテンツエディターによって管理されます。

リソースでHTMLを使用して、h1やリンクなどの単純なものを作成します。これにより問題が発生することはありません。

たとえば、リンクのターゲットをリソースにハードコーディングしますか?または、{0}を入れてビューにstring.Formatを入力しますか

はい、それは良いアプローチでしょう。置き換えることができるプレースホルダーを含むhtmlリンクを置くだけです。

指示が長く、表形式で表示する必要がある場合はどうなりますか?

Htmlテーブル全体をリソースに入れるのは少し極端です。私は別の解決策を見つけようとします。

直接挿入できるリソースとエスケープ解除が必要なリソースをどのように覚えていますか?

コンテンツエディターが敵対的買収を試みていないと仮定すると、それらを信頼できるはずです。その場合、すべてのリソースに対してHtml.Rawを使用できます。

0

リソース文字列の見込みから、これを保存します。

Click any of the links below, or click {0} to cancel. Contact {1} with any questions.

ただし、これは動的文字列の問題を解決するだけです。マークアップと文字列を混在させたいとは思わないので、リソースの一部としてHTMLタグを追加しないことをお勧めします。リソースは、別の言語への翻訳が必要なリテラルテキストである必要があります。

問題は、文字列ANDマークアップが必要なことです。

したがって、この場合はリソース文字列をまったく使用しません。あなたが本当に欲しいのはcontentです。したがって、このようなものをリソース文字列に保存しないでください。代わりに、すべて、テキスト、マークアップなどを返すコンテンツをリクエストしてください。

これは、自社開発のWebサービス/ dllまたはエンタープライズコンテンツ管理システムである可能性がありますが、リソース文字列ではありません。

0
Jon Raynor