23

質問を再定式化するのは

コメント:この質問はすでに「人気の質問バッジ」を獲得しているので、おそらく私だけが絶望的な人ではありません。:)

残念ながら、完全な問題スタックを示すことは非常に長い質問につながり、それは非常にメイソン特有です。

まず、意見のみの部分:)

私はHTML::Masonを長年使用しており、現在はMason2を使用しようとしています。詩人メイソンは 、CPANで最も先進的なフレームワークです。何も比較できるものは見つかりませんでした。すぐに使えるもので、非常にクリーンな書き込みが可能です/しかし非常にハッキング可能です:)/多くのバッテリーが含まれているWebアプリ(ロギング、キャッシュ、構成管理、ネイティブPGSIベースなど...)

残念ながら、作者は残りの単語を気にしません。たとえば、デフォルトでは、ASCIIベースのみであり、 マニュアル、FAQ、またはアドバイスはありませ。ユニコードでの使用方法

今事実。デモ。詩人アプリを作成します。

poet new my #the "my" directory is the $poet_root
mkdir -p my/comps/xls
cd my/comps/xls

そして、以下に追加しdhandler.mcます(2つの基本的な問題を実証するもの)

<%class>
    has 'dwl';
    use Excel::Writer::XLSX;
</%class>
<%init>
    my $file = $m->path_info;

    $file =~ s/[^\w\.]//g;
    my $cell = lc join ' ', "ÅNGSTRÖM", "in the", $file;

    if( $.dwl ) {
        #create xlsx in the memory
        my $excel;
        open my $fh, '>', \$excel or die "Failed open scalar: $!";
        my $workbook  = Excel::Writer::XLSX->new( $excel );
        my $worksheet = $workbook->add_worksheet();
        $worksheet->write(0, 0, $cell);
        $workbook->close();

        #poet/mason output
        $m->clear_buffer;
        $m->res->content_type("application/vnd.ms-excel");
        $m->print($excel);
        $m->abort();
    }
</%init>
<table border=1>
<tr><td><% $cell %></td></tr>
</table>
<a href="?dwl=yes">download <% $file %></a>

アプリを実行します

../bin/run.pl

http:// 0:5000 / xls / hello.xlsxにアクセスすると、次のようになります。

+----------------------------+
| ÅngstrÖm in the hello.xlsx |
+----------------------------+
download hello.xlsx

ダウンロードhello.xlsxをクリックすると、ダウンロードが表示hello.xlsxされます。

上記は最初の問題を示しています。たとえば、コンポーネントのソースは「下」にないuse utf8;ため、lcは文字を理解しません。

2番目の問題は次のとおりです。[ http:// 0:5000 / xls /hélló.xlsx]または http:// 0:5000 / xls / h%C3%A9ll%C3%B3.xlsx を試してみてください。見る:

+--------------------------+
| ÅngstrÖm in the hll.xlsx |
+--------------------------+
download hll.xlsx
#note the wrong filename

もちろん、入力(path_info)はデコードされません。スクリプトは、perl文字ではなく、utf8でエンコードされたオクテットで機能します。

したがって、perlに「ソースはutf8にあります」と伝えると、結果ににを追加use utf8;します。<%class%>

+--------------------------+
| �ngstr�m in the hll.xlsx |
+--------------------------+
download hll.xlsx

追加use feature 'unicode_strings'(またはuse 5.014;)さらに悪い:

+----------------------------+
| �ngstr�m in the h�ll�.xlsx |
+----------------------------+
download h�ll�.xlsx

もちろん、ソースにはワイド文字が含まれているためEncode::encode_utf8、出力に必要です。

次のようなフィルターを使用してみることができます。

<%filter uencode><% Encode::encode_utf8($yield->()) %></%filter>

出力全体をフィルタリングします。

% $.uencode {{
<table border=1>
<tr><td><% $cell %></td></tr>
</table>
<a href="?dwl=yes">download <% $file %></a>
% }}

<%init%>ただし、または<%perl%>ブロックのエンコーディングに注意する必要があるため、これは部分的にしか役立ちません。多くの場所でのperlコードのエンコード/デコード(読み取り:境界ではない)は、spagethyコードにつながります。

エンコード/デコードは、 詩人とメイソンの境界のどこかで明確に行う必要があります。もちろん、Plackはバイトレベルで動作します。


部分的な解決策。

幸いなことに、詩人は巧妙にそれ(およびメイソン)の部分を変更することを許可しているので、 $poet_root/lib/My/Masonあなたは次のように変更することができますCompilation.pm

override 'output_class_header' => sub {
    return join("\n",
        super(), qq(
        use 5.014;
        use utf8;
        use Encode;
        )
    );
};

必要なプリアンブルをすべてのメイソンコンポーネントに挿入するもの。(すべてのコンポーネントに触れることを忘れないでください。または、コンパイルされたオブジェクトをから削除してください$poet_root/data/obj)。

また、次のように編集して、境界でリクエスト/レスポンスを処理してみることができます$poet_root/lib/My/Mason/Request.pm

#found this code somewhere on the net
use Encode;
override 'run' => sub {
    my($self, $path, $args) = @_;

    #decode values - but still missing the "keys" decode
    foreach my $k (keys %$args) {
        $args->set($k, decode_utf8($args->get($k)));
    }

    my $result = super();

    #encode the output - BUT THIS BREAKS the inline XLS
    $result->output( encode_utf8($result->output()) );
    return $result;
};

すべてをエンコードすることは間違った戦略です、それは例えばXLSを壊します。

したがって、4年後(2011年に最初の質問をした)はまだわかりません:( Mason2アプリケーションでUnicodeを正しく使用する方法はまだわかりませんが、それに関するドキュメントやヘルパーはまだ存在しません。:(

主な質問は次のとおりです。-どこで(Mooseのメソッド修飾子によってどのメソッドを変更する必要があるか)、入力をどのように正しくデコードし、出力をどこで(Poet / Masonアプリで)。

  • しかし、テキストのものだけ、例えばtext/plainまたはtext/htmlなど...
  • 上記の「サプライズフリー」を実行します。たとえば、単純に機能するものを実行します。;)

誰かが実際のコードを手伝ってくれませんか?上記で何を変更する必要がありますか?

4

3 に答える 3

4

Mason2のマニュアルには、コンポーネントの継承の仕組みが記載されているため、この共通コードをメインのBase.mpコンポーネント(他のすべての継承元)に配置すると、問題が解決する可能性があると思います。

プラグインの作成については、Mason :: Manual::Pluginsで説明されています。

したがって、Mason :: Requestを変更する独自のプラグインを作成し、オーバーライドするrequest_args()ことで、UTF-8でデコードされたパラメーターを返すことができます。

編集:

UTF-8出力に関しては、Apacheディレクティブを追加して、text/plainおよびtext/HTML出力が常にUTF-8として解釈されるようにすることができます。

AddDefaultCharset utf-8
于 2011-05-20T05:11:03.013 に答える
1

mason-usersメーリングリストには、UTF-8の処理に関する質問がありました。

  1. UTF-8で出力されるコンポーネント
  2. UTF-8 GET/POST引数の処理

ジョンの答えは次のとおりです。

メイソンにエンコードをインテリジェントに処理してもらいたいのですが、私はutf8を定期的に使用していないため、あなたや他の人が設計を手伝ってくれる必要があります。

これはおそらくプラグインにあるはずです、例えばMason :: Plugin::UTF8。

したがって、特に言及することについては、次のようなものが機能する可能性があります。

package Mason::Plugin::UTF8;
use Moose;
with 'Mason::Plugin';
1;

package Mason::Plugin::UTF8::Request;
use Mason::PluginRole;
use Encode;

# Encode all output in utf8 - ** only works with Mason 2.13 and beyond **
#
after 'process_output' => sub {
    my ($self, $outref) = @_;
    $$outref = encode_utf8( $$outref );
};

# Decode all parameters as utf8
#
around 'run' => sub {
    my $orig = shift;
    my $self = shift;

    my %params = @_;
    while (my ($key, $value) = each(%params)) {
        $value = decode_utf8($value);
    }
    $self->$orig(%params);
}

1;

あなたまたはutf8の問題に精通している他の誰かが、私ではなくこのプラグインを作成した場合は、おそらく最善でしょう。しかし、これを簡単にするためにメイソンコアに必要なものがあるかどうか教えてください。

IMHO、「use utf8;」を追加するには、以下も追加する必要があります。すべてのコンポーネントに。

package Mason::Plugin::UTF8::Compilation;
use Mason::PluginRole;
override 'output_class_header' => sub {
    return(super() . 'use utf8;');
};

1;
于 2011-07-24T14:32:29.403 に答える
1

OK、Firefoxでこれをテストしました。HTMLはUTF-8を正しく表示し、zipをそのままにしておくので、どこでも機能するはずです。

パッチを適用することから始める場合はpoet new My、必要patch -p1 -i...path/to/thisfile.diffです。

diff -ruN orig/my/comps/Base.mc new/my/comps/Base.mc
--- orig/my/comps/Base.mc   2015-05-20 21:48:34.515625000 -0700
+++ new/my/comps/Base.mc    2015-05-20 21:57:34.703125000 -0700
@@ -2,9 +2,10 @@
 has 'title' => (default => 'My site');
 </%class>

-<%augment wrap>
-  <html>
+<%augment wrap><!DOCTYPE html>
+  <html lang="en-US">
     <head>
+      <meta charset="utf-8">
       <link rel="stylesheet" href="/static/css/style.css">
 % $.Defer {{
       <title><% $.title %></title>
diff -ruN orig/my/comps/xls/dhandler.mc new/my/comps/xls/dhandler.mc
--- orig/my/comps/xls/dhandler.mc   1969-12-31 16:00:00.000000000 -0800
+++ new/my/comps/xls/dhandler.mc    2015-05-20 21:53:42.796875000 -0700
@@ -0,0 +1,30 @@
+<%class>
+    has 'dwl';
+    use Excel::Writer::XLSX;
+</%class>
+<%init>
+    my $file = $m->path_info;
+    $file = decode_utf8( $file );
+    $file =~ s/[^\w\.]//g;
+    my $cell = lc join ' ', "ÅNGSTRÖM", "in the", $file ;
+    if( $.dwl ) {
+        #create xlsx in the memory
+        my $excel;
+        open my $fh, '>', \$excel or die "Failed open scalar: $!";
+        my $workbook  = Excel::Writer::XLSX->new( $fh );
+        my $worksheet = $workbook->add_worksheet();
+        $worksheet->write(0, 0, $cell);
+        $workbook->close();
+
+        #poet/mason output
+        $m->clear_buffer;
+        $m->res->content_type("application/vnd.ms-excel");
+        $m->print($excel);
+        $m->abort();
+    }
+</%init>
+<table border=1>
+<tr><td><% $cell %></td></tr>
+</table>
+<p> <a href="%c3%85%4e%47%53%54%52%c3%96%4d%20%68%c3%a9%6c%6c%c3%b3">ÅNGSTRÖM hélló</a>
+<p> <a href="?dwl=yes">download <% $file %></a>
diff -ruN orig/my/lib/My/Mason/Compilation.pm new/my/lib/My/Mason/Compilation.pm
--- orig/my/lib/My/Mason/Compilation.pm 2015-05-20 21:48:34.937500000 -0700
+++ new/my/lib/My/Mason/Compilation.pm  2015-05-20 21:49:54.515625000 -0700
@@ -5,11 +5,13 @@
 extends 'Mason::Compilation';

 # Add customizations to Mason::Compilation here.
-#
-# e.g. Add Perl code to the top of every compiled component
-#
-# override 'output_class_header' => sub {
-#      return join("\n", super(), 'use Foo;', 'use Bar qw(baz);');
-# };
-
+override 'output_class_header' => sub {
+    return join("\n",
+        super(), qq(
+        use 5.014;
+        use utf8;
+        use Encode;
+        )
+    );
+};
 1;
\ No newline at end of file
diff -ruN orig/my/lib/My/Mason/Request.pm new/my/lib/My/Mason/Request.pm
--- orig/my/lib/My/Mason/Request.pm 2015-05-20 21:48:34.968750000 -0700
+++ new/my/lib/My/Mason/Request.pm  2015-05-20 21:55:03.093750000 -0700
@@ -4,20 +4,27 @@

 extends 'Mason::Request';

-# Add customizations to Mason::Request here.
-#
-# e.g. Perform tasks before and after each Mason request
-#
-# override 'run' => sub {
-#     my $self = shift;
-#
-#     do_tasks_before_request();
-#
-#     my $result = super();
-#
-#     do_tasks_after_request();
-#
-#     return $result;
-# };
+use Encode qw/ encode_utf8 decode_utf8 /;

-1;
\ No newline at end of file
+override 'run' => sub {
+    my($self, $path, $args) = @_;
+    foreach my $k (keys %$args) {
+        my $v = $args->get($k);
+        $v=decode_utf8($v);
+        $args->set($k, $v);
+    }
+    my $result = super();
+    my( $ctype, $charset ) = $self->res->headers->content_type_charset;
+    if( ! $ctype ){
+        $ctype = 'text/html';
+        $charset = 'UTF-8';
+        $self->res->content_type( "$ctype; $charset");
+        $result->output( encode_utf8(''.( $result->output())) );
+    } elsif( ! $charset and $ctype =~ m{text/(?:plain|html)} ){
+        $charset = 'UTF-8';
+        $self->res->content_type( "$ctype; $charset");
+        $result->output( encode_utf8(''.( $result->output())) );
+    }
+    return $result;
+};
+1;
于 2015-05-21T05:02:20.367 に答える