こんにちはHabradrug!
もちろん、このトピックは既にハックされていることは理解していますが、アプリケーションのローカリゼーションとその実装についての私のビジョンを説明しようと思います。 そのため、結果として得たいもの:.NETアプリケーション、特にWebFormsを開発後の段階で迅速にローカライズするシステム。 ポイントについて:
1.アプリケーション開発:ローカライズに対する最小限の注意。
2.開発の完了:ローカライズの最小時間。
それでも、これらすべてができるだけ便利でシンプルであることが必要です。
つまり、すべては次のようになります。
gettextに似たメソッドを使用して、テキストまたはキー+テキストを渡します。このメソッドは、ローカライズされた文字列または渡されたものを返します。 また、このメソッドを検索して
* .cs 、
* .aspx 、
* .ascxファイルを解析し、そこからキーとテキストを受信する、またはこれらのテキストとキーがアプリケーションリソースに既にあるユーティリティもあります。 次に、Google翻訳を使用します。これは少なくとも貧弱ですが、新しいテキストを翻訳します。 そして最後に、翻訳を編集し、すべてをリソースに保存します。 できた
明らかに、同様の、またはより優れたメカニズムがすでに開発されていますが、インターネットに登ったとき、私は非常に重いソリューションと有料ソリューションだけを見ました。
それでは、実装に取りかかりましょう。 ExpressionBuilder-aを使用したサーバー側コントロールのヘルパークラスから始めましょう。
public static class L
{
private static readonly Regex KeyRepairRegex = new Regex( "[^\\w\\d]" , RegexOptions.Compiled);
public static string Run( string value )
{
var key = GenerateKey( value );
var localized = Resources.ResourceManager.GetString(key);
return string .IsNullOrEmpty(localized) ? value : localized;
}
public static string Run( string key, string value )
{
var localized = Resources.ResourceManager.GetString(key);
return string .IsNullOrEmpty(localized) ? value : localized;
}
public static string Run( string key, string value , params object [] format)
{
var localized = Run(key, value );
if (format != null && format.Length > 0)
{
try
{
localized = string .Format(localized, format);
}
catch
{
}
}
return localized;
}
private static string GenerateKey( string value )
{
if ( string .IsNullOrEmpty( value )) return value ;
value = value .Length > 23 ? value .Substring(0, 23) + "__" : value ;
value = KeyRepairRegex.Replace( value , "_" );
if ( char .IsUpper( value [0])) value = "_" + value ;
value = value .ToLowerInvariant();
return value ;
}
}
現在、開発中、ローカライズが必要な場所で、次のように記述します。
<%= L.Run( "Hello, Mr.Everybody" ) %>
Lクラスはどのネームスペースにも明確に配置されていないため、 * .ascxファイルにインポートする必要はありません。
<%@ Import Namespace = "Example.Namespace" %>
ここでは、コードからわかるように、非常に重要なGenerateKeyメソッドがあります。 キーなしでテキストのみを送信する場合、このメソッドはキーを生成し、リソースでこのキーを探します。 リソースのキーには、文字[a-z0-9_]のみを含めることができます。 また、ユーティリティは同じメソッドを使用してキーを生成します。 次に、ExpressionBuilderを見て、スキーム全体のより具体的な例を示します。 なぜこのBuilderが必要なのですか?
サーバーコントロールの構成<%=%>はエラーにつながりますが、<%#%>の場合、DataBindメソッドを追加で呼び出す必要がありますが、これはあまり便利ではありません。 ExpressionBuilderから継承したクラスが必要です。
public class LExpressionBuilder: ExpressionBuilder
{
public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
{
var thisType = new CodeTypeReferenceExpression(GetType());
var expression = new CodePrimitiveExpression(entry.Expression.Trim());
const string evaluationMethod = "Localize" ;
return new CodeMethodInvokeExpression(thisType, evaluationMethod, new CodeExpression[] { expression });
}
public static string Localize( string expression)
{
return L.Run(expression);
}
public override object EvaluateExpression( object target, BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
{
return Localize(entry.Expression);
}
public override bool SupportsEvaluate
{
get { return true ; }
}
}
その結果、次のように記述します。
<input typ= 'submit' id= 'btnSubmit' runat= 'server' value = "<%$ L:A people free to choose will always choose peace %>" />
最初の部分の準備ができました。 ユーティリティに渡します。 これは通常のWinFormsアプリケーションです。
クラス図
図からわかるように、コードは非常に単純です。 しかし、主なことは簡単です。 必要なソリューションまたはプロジェクトを読み込み、Settingsクラスでリソースファイルへのパスを指定します。 そして...行きましょう! ソリューションクラスはすべてのファイルをロードします。 CodeParserは、すべての行とキーをTranslationクラスにロードします。これにより、リソースからすべての翻訳がロードされ、GridViewにすべて表示されます。 これで、手動またはgoogleで翻訳できるようになりました。元の行をテキストファイルに保存するか、たとえばxmlに保存するなど、他の何かを実装できます。
Assembla Subversion (登録はオプションです)
このユーティリティは、原則として「それだけが機能した場合」という原則に基づいて急いで書かれているので、グルに厳しく判断しないようお願いします。 誰か興味があれば、少なくともアルファ版にこの問題を持ち込むことができます。
他に何をしたいですか:
CodeParserがファイルから行を引き裂くと、その位置が記憶されます。 そして、ローカライズされた文字列のほとんどは最初にキーなしで私に送られるので、それらを生成するのに数ナノ秒余分にかかるので、ユーティリティは後でファイルの文字列にキーを挿入する必要があります。
しかし、これがなくても、すべてが非常にスマートに機能しますが、批判や提案を聞いて喜んでいます。
ご清聴ありがとうございました。
* Source code was highlighted with Source Code Highlighter .