テキストの整形はPerlの基本
Perlは
print "This report is created by $author.";
もう少しこったことをしたければ、
printf "This report is created on %04d/%02d/%02d.", $year, $month, $day;
優先順位の都合でうまく埋め込めなかったり、
use Time::Piece;
print "This report is created by $author",
"on ".Time::Piece->new->ymd.".\n",
あるいはシェルから受け継いだヒアドキュメントを使う手もあるのでした。
printf <<"END", $year, $month, $day;
This report is created by $author,
on %04d-%02d-%02d.
END
また、
format STDOUT =
This report is created by @*,
$author
on @*-@*-@*.
$year, $month, $day
.
write;
ただし、
例によって多様性を重視するPerlの世界では有名どころだけでも片手では数えられないだけのテンプレートモジュールがありますが、
今回からは何度かにわけてテンプレートまわりのモジュールについてまとめてみます。初回の今回は、
Text::Template
この系統のモジュールとしてはまず
これはCPANに登録されているPerlのテンプレート関連モジュールとしては最古のものなので、
Text::Templateの機能自体はヒアドキュメントに毛が生えたようなもので、
use strict;
use warnings;
my $author = 'me';
my @items = (1, 2, 3);
print <<"END";
This report is created by ${author}.
@{[ do {
my $list = '';
for (@items) { $list .= "item $_\n" }
$list; # 最終的にこの値が埋め込まれます
}]}
END
use strict;
use warnings;
use Text::Template;
my $author = 'me';
my @items = (1, 2, 3);
my $template = <<'END'; # ここの部分は外部のファイルに切り出せます
This report is created by {$author}.
{
my $list = '';
for (@items) { $list .= "item $_\n" }
$list; # 最終的にこの値が埋め込まれます
}
END
print Text::Template->new(TYPE => 'STRING', SOURCE => $template)
->fill_in(HASH => { items => \@items, author => $author });
この例ではText::Templateに渡すテンプレートもヒアドキュメントで作成しているため違いが見えづらくなっていますが
HTML::Mason
この系統の第二陣に属するものとしては、
これらはPHPやASPの黎明期
ここではAmazon.
HTML::Masonではテンプレートはファイルに保存することが前提となっているため、
<%args>
$author
@items
</%args>
This report is created by <% $author %>.
% for (@items) {
item <% $_ %>
% }
続いて、
use strict;
use warnings;
use HTML::Mason;
use File::Spec;
my $interp = HTML::Mason::Interp->new(
comp_root => File::Spec->rel2abs('.'),
out_method => \my $out,
# 自動でHTMLエスケープしたい場合は下記も
# default_escape_flags => ['h'],
);
$interp->exec('/template.tmpl',
author => 'me',
items => [1, 2, 3],
);
print $out;
HTML::Masonにはほかにもさまざまな機能が用意されています。詳しくはHTML::Masonのサイトにドキュメントがまとまっているほか、
なお、
use strict;
use warnings;
use Text::MicroMason;
my $template =<<'END';
This report is created by <% $author %>.
% for (@items) {
item <% $_ %>
% }
<%args>
$author
@items
</%args>
END
my $mason = Text::MicroMason->new(
-Filters,
default_filters => 'h',
);
print $mason->execute(text=>$template,
author => 'me <[email protected]>',
items => [1, 2, 3],
);
また、
Text::MicroTemplate
三番目のグループに属するのは、
Mojoliciousについては第22回でも取り上げましたし、
両者の大きな違いは、
それぞれ簡単なサンプルを載せておきます。
use strict;
use warnings;
use Mojo::Template;
my $mt = Mojo::Template->new(auto_escape => 1);
print $mt->render(<<'END', 'me <[email protected]>', [1, 2, 3]);
% my ($author, $items) = @_;
This report is created by <%== $author %>.
% for (@$items) {
item <%= $_ %>
% }
END
use strict;
use warnings;
use Text::MicroTemplate 'encoded_string';
my $renderer = Text::MicroTemplate->new(template => <<'END')->build;
? my ($author, $items) = @_;
This report is created by <?= encoded_string($author) ?>.
? for (@$items) {
item <?= $_ ?>
? }
END
print $renderer->('me <[email protected]>', [1, 2, 3]);
なお、
Text::MicroTemplateはテンプレートを文字列として渡すようになっていますが、
use strict;
use warnings;
use Text::MicroTemplate::File;
our $mt = Text::MicroTemplate::File->new;
print $mt->render_file('template.mt', 'me <[email protected]>', [1, 2, 3]);
ここであえて$mtをourでグローバル化しているのは、
? my ($author, $items) = @_
This report is created by <?= encoded_string($author) ?>.
? for (@$items) {
item <?= $_ ?>
? }
?= $main::mt->render_file('footer.mt', $author);
footer.
? my $author = shift;
<footer><?= $author ?></footer>
ここでは前からの例にならってあえて配列で引数を渡していますが、
use strict;
use warnings;
use Text::MicroTemplate::File;
my $context = {
author => 'me <[email protected]>',
items => [1, 2, 3],
};
our $mt = Text::MicroTemplate::File->new;
print $mt->render_file('template.mt', $context);
# あとはすべてのテンプレートの先頭に「?= my $context = shift;」を書くだけ
また、
use strict;
use warnings;
use Text::MicroTemplate::File;
my $mt = Text::MicroTemplate::File->new;
my $context = {
author => 'me <[email protected]>',
items => [1, 2, 3],
mt => $mt,
};
print $mt->render_file('template.mt', $context);
# template.mtでは ?= $context->{mt}->render_file(...)のようにします
なお、
これらのテンプレートは、