Переформулируя вопрос, потому что
Комментарий: Этот вопрос уже получил «значок популярного вопроса», так что, вероятно, я не единственный безнадежный человек. :)
К сожалению, демонстрация полного стека задач приводит к очень длинному вопросу, и он очень специфичен для Мейсона .
Во-первых, Поэт и Мейсон являются наиболее продвинутыми фреймворками в CPAN. Ничего похожего не нашел, что из коробки позволяет писать такие чистые / но очень хакерские :) / web-apps, со многими включенными батареями (ведение журнала, кеширование, управление конфигурациями, на основе PGSI и т. д.)
К сожалению, автора не волнует остальное слово, например, по умолчанию он основан только на ascii, без какого-либо руководства, часто задаваемых вопросов или советов по поводу: как использовать его с юникодом
Теперь факты. Демо. Создайте приложение для поэта:
poet new my #the "my" directory is the $poet_root
mkdir -p my/comps/xls
cd my/comps/xls
и добавьте в dhandler.mc
следующее (которое продемонстрирует две основные проблемы)
<%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>
<% $cell %>
download <% $file %>
и запустите приложение
../bin/run.pl
перейдите по адресу http: / /0:5000/xls/hello.xlsx, и вы получите:
+----------------------------+
| ÅngstrÖm in the hello.xlsx |
+----------------------------+
download hello.xlsx
Щелкнув загрузку hello.xlsx , вы получите hello.xlsx
в загрузках.
Сказанное выше демонстрирует первую проблему,
например, источник компонента не находится "под" используйте utf8;
,
поэтому lc
не понимает символы.
Вторая проблема заключается в следующем, попробуйте [ 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
) не декодируется, сценарий работает с октетами в кодировке utf8, а не с символами Perl.
Итак, говоря perl - "источник находится в utf8", добавляя use utf8;
в
, получаем
+--------------------------+
| �ngstr�m in the hll.xlsx |
+--------------------------+
download hll.xlsx
добавление функции use 'unicode_strings'
(или используйте 5.014;
) еще хуже:
+----------------------------+
| �ngstr�m in the h�ll�.xlsx |
+----------------------------+
download h�ll�.xlsx
Конечно , источник теперь содержит широкие символы, ему требуется Encode :: encode_utf8
на выходе.
Можно попробовать использовать такой фильтр:
<%filter uencode><% Encode::encode_utf8($yield->()) %>%filter>
и отфильтровать весь вывод:
% $.uencode {{
<% $cell %>
download <% $file %>
% }}
, но это помогает только частично, потому что нужно позаботиться о кодировке в
или
блоков.
Кодирование / декодирование внутри кода Perl во многих местах ( читается: не на границах ) приводит к нечеткому коду.
Кодирование / декодирование должно выполняться четко где-то в Поэт / Мейсон границы - конечно, Плак работает на байтовом уровне.
Частичное решение.
К счастью, Поэт умно позволяет изменять это части (и Мэйсона), так что,
в каталоге $ поэта / lib / My / Mason
вы можете изменить Compilation.pm
на:
override 'output_class_header' => sub {
return join("\n",
super(), qq(
use 5.014;
use utf8;
use Encode;
)
);
};
что будет вставлять нужную преамбулу в каждый компонент Mason . (Не забудьте прикоснуться к каждому компоненту или просто удалить скомпилированные объекты из $ poet_root / data / obj
).
Также вы можете попробовать обработать запрос / ответы на границы,
отредактировав $ pet_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 и до сих пор не существует документации или помощники по этому поводу.: (
Основные вопросы: - где (какие методы должны быть изменены модификаторами метода Moose) и как правильно декодировать входы и где выход (в приложении Poet / Mason.)
text / plain
или text / html
и тому подобное ... Может ли кто-нибудь помочь с реальным кодом - что я должен изменить в приведенном выше?