118. 118/122
トークンの引き継ぎ
sub build {
for my $t (@$tokens) {
my ( $tokens, $tokens_else, $uncompiled );
if ( $childNodes && ref($childNodes) ) {
( $tokens, $tokens_else ) = ( [], [] );
for my $sub (@$childNodes) {
my $tag = lc $sub->tag;
if ( $tag eq 'else' || $tag eq 'elseif' ) {
push @$tokens_else, $sub;
}
else {
push @$tokens, $sub;
}
}
my $hdlr = $ctx->handler_for( $t->tag );
my ( $h, $type, $orig ) = $hdlr->values;
my $conditional = defined $type && $type == 2;
if ($h) {
$timer->pause_partial if $timer;
local ( $ctx->{__stash}{tag} ) = $t->tag;
local ( $ctx->{__stash}{tokens} )
= ref($tokens)
? bless $tokens, 'MT::Template::Tokens'
: undef;
local ( $ctx->{__stash}{tokens_else} )
= ref($tokens_else)
? bless $tokens_else, 'MT::Template::Tokens'
: undef;
local ( $ctx->{__stash}{uncompiled} ) = $uncompiled;
①子ノードがあれば
$tokensまたは
$tokens_elseにpush
②子ノードの$tokensを
$ctx(stash)に
保持(=引き継ぎ)
MT::Builder
$VAR1 = [
bless( [
'Entries',
{},
[
bless( [
'EntryTitle',
{},
[],
undef,
[],
$VAR1->[0],
undef
], 'MT::Template::Node' )
],
'<$mt:EntryTitle$>',
[],
undef,
undef
], 'MT::Template::Node' )
];
子
ノ
ー
ド
親
ノ
ー
ド
119. 119/122
ブロックタグのビルド
ブロックタグの場合、タグハンドラ内でさらにビルドを再帰的に実行し、出力結果を積み上げ
sub build {
:
for my $t (@$tokens) {
:
my $hdlr = $ctx->handler_for( $t->tag );
:
my $out = $hdlr->invoke( $ctx, ¥%args, $cond );
:
}
}
MT::Builder
sub _hdlr_entries {
:
my $tok = $ctx->stash('tokens');
:
for my $e (@entries) {
:
my $out = $builder->build( $ctx, $tok, ... );
:
}
}
②ブロックタグがあればビルドを再帰的に実行
MT::Template::Tag::Entry
①タグハンドラ実行
120. 120/122
コンテキストエラーの仕組み
記事コンテキストの場合
sub _hdlr_entry_title {
my ( $ctx, $args ) = @_;
my $e = $ctx->stash('entry')
or return $ctx->_no_entry_error();
my $title = defined $e->title ? $e->title :
'';
:
return $title;
}
sub _hdlr_entries {
:
for my $e (@entries) {
:
local $ctx->{__stash}{entry} = $e;
:
my $out = $builder->build( $ctx, $tok, ... );
:
}
}
<mt:Entries>
<mt:EntryTitle>
</mt:Entries>
インデックステンプレート
MT::Template::Tag::Entry MT::Template::Tag::Entry
①MTEntriesタグの処理で
記事コンテキストを設定
②MTEntryTitleタグ内のコンテキスト判定OK
121. 121/122
コンテキストエラーの仕組み
記事コンテキストでない場合
<mt:EntryTitle>
インデックステンプレート
sub _no_entry_error {
my ($ctx) = @_;
my $tag_name = $ctx->stash('tag');
$tag_name = 'mt' . $tag_name unless $tag_name =~ m/^MT/i;
return $_[0]->error(
MT->translate(
"You used an '[_1]' tag outside of the context of an entry; "
. "Perhaps you mistakenly placed it outside of an 'MTEntries'
container tag?",
$tag_name
)
);
}
MT::Template::Context
①いきなりMTEntryTitleタグ処理のため、
記事コンテキスト判定NG
②エラー処理
sub _hdlr_entry_title {
my ( $ctx, $args ) = @_;
my $e = $ctx->stash('entry')
or return $ctx-
>_no_entry_error();
my $title = defined $e->title ? $e-
>title : '';
:
return $title;
}
MT::Template::Tag::Entry