目次
一度では全て書き切れないので、幾つかの連載記事とする予定です。
MovableType のヘルプドキュメント
にある内容を網羅し、これに沿った形で書いていくつもりですので、併せて読み進めていただけるとモア・ベターかと思います。
よろしくお付き合いくださいませm(_ _)m
コンテナタグ
コンテナタグ(container tags)とは、
HTML タグで云う所の
<div> や
<blockquote> のように、
他の
HTML タグや
テンプレートタグや文字列を、その中に含むことができる
テンプレートタグのことです。
MT のコンテナタグは、その中身(コンテンツ)に対して、何らかの処理を行いたい場合に使用します。
例えば、
<MTEntries> コンテナタグは、
複数のエントリから一つずつエントリを取り出しながら、
その中に含まれる
<MTEntryTitle> などのコンテンツを処理します。
また、
<MTCalendar> コンテナタグは、
日付を変化させながら、その月の日数分だけ、そのコンテンツを繰返す処理を行います。
ここでは簡単な例として、コンテンツを
<blockquote> で囲むだけの
<MTMyBlockquote> コンテナタグを作ってみます。
そして、何れかのテンプレートに次のように追記し、そのテンプレートを再構築してみましょう。
コードの詳細
- MT::Template::Context->add_container_tag (MyBlockquote => ¥&my_blockquote);
-
テンプレートのコンテクストに新しいコンテナタグを追加します。
変数タグの名前は「MTMyBlockquote」で、その処理内容は my_blockquote にある、と云うことです。
変数タグで出てきた add_tag と全く同じです。
- my ($ctx, $args, $cond) = @_;
-
現在のコンテクストと引数、条件式のハッシュ参照を取得します。やっぱり、おまじないで。
- my $builder = $ctx->stash('builder')
- my $tokens = $ctx->stash('tokens')
-
<MTMyBlockquote> コンテナタグの
コンテンツ($tokens)と、
それを処理するためのビルダ($builder)を取得します。
- my $out = $builder->build ($ctx, $tokens, $cond);
-
ビルダを使ってコンテンツを構築し、その結果を $out に代入します。
- return $ctx->error ($builder->errstr) if !defined $out;
-
コンテンツ内でテンプレートタグの使い方を間違っていたり、MT に何かエラーが発生した場合、
$out が未定義(!defined) になるので、
MT のエラーログにエラー内容($builder->errstr)を返して処理を中断します。
- '<blockquote>'. $out. '</blockquote>';
-
正常に構築されていたら、コンテンツ全体を blockquote タグで括って、
<MTMyBlockquote> コンテナタグの答え(?)とします。
コンテナタグの引数
変数タグでは、その動作を変更するのに
引数を使うことができました。
MTMyBlockquote プラグインの
ソースコードを見ると、
変数タグの時と同じく
$args と書かれた部分が見つかります。
お察しのとおり、変数タグと全く同じ方法でコンテナタグでも引数を取ることができるのです。
そこで、
<MTMyBlockquote> を改造して、
色々な
HTML タグでコンテンツを括ることができる
<MTAnyBlock> テンプレートタグを作ってみます。
そして、何れかのテンプレートに次のように追記し、そのテンプレートを再構築してみましょう。
…このテンプレートタグに意味があるのか、それは考えない方向で(苦笑
コードの詳細
- my $tag = $args->{tag} or return $out;
-
tag="..." で指定された値を $tag に代入します。
何も指定されていない場合は、コンテンツをそのまま返します。
- my $class = $args->{class} or "<$tag>". $out. "</$tag>";
-
class="..." で指定された値を $class に代入します。
何も指定されていない場合は、コンテンツを $tag タグで括って返します。
- "<$tag class=¥"$class¥">". $out. "</$tag>";
-
コンテンツを $tag と $class で括って返します。
コンテナタグ中の変数タグ
<MTCalendar> コンテナタグの中で使用される
<MTCalendarDay> 変数タグのように、
様々に値を変化させるような変数タグはどのように実現すれば良いのでしょうか?
そして、何れかのテンプレートに次のように追記し、そのテンプレートを再構築してみましょう。
コードの詳細
- my $loop = $args->{count} || 1;
-
<MTMyLoop> コンテナタグの引数
count="..." から繰返す回数を取得します。
- for (my $count = 1; $count <= $loop; $count++)
-
$loop 回だけ処理を繰返します。
現在の繰り返し回数は $count です。
- local $ctx->{__stash}{'myplugin::count'} = $count;
-
現在の繰り返し回数 $count を
myplugin::count に記憶しておきます。
- $html .= $out;
-
この処理で得られた結果を、今までのコンテンツの処理結果の最後に付けたします。
- $count = $ctx->stash('myplugin::count');
-
myplugin::count に記憶してある内容を $count に代入します。
- return $ctx->error ('MTMyLoopCount must be used in MTMyLoop') if !defined $count;
-
$count が未定義(!defined) だった場合、
<MTMyLoopCount > 変数タグは
<MTMyLoop > コンテナタグの中でしか使えないことを示すエラーメッセージを返します。
条件タグ
条件タグ(conditional tags)は、
<MTEntryIfExtended> のように、
ある条件が成立した場合に、そのコンテンツを表示したい場合に使用します。
条件タグは、コンテナタグと非常に似ています。
例として、その日が日曜日だった場合に成立する
<MTIfSunday> 条件タグを作ってみます。
そして、何れかのテンプレートに次のように追記し、そのテンプレートを再構築してみましょう。
コードの詳細
- my $e = $ctx->stash('entry') or return $ctx->_no_entry_error('MTIfSunday');
-
現在のエントリを取得し、$e に代入します。
エントリが無い場合、エラーを返します。
- my $ts = $e->created_on;
-
エントリ $e の投稿日を $ts に代入します。
- MT::Util::wday_from_ts ($ts =‾ m/^(¥d¥d¥d¥d)(¥d¥d)(¥d¥d)/) == 0;
-
MT::Util::wday_from_ts 関数を使用して、投稿日の曜日を取得します。
曜日が日曜日(0)の場合には真、日曜日以外(1〜6)の場合には偽を返します。
条件タグはコンテナタグと非常に似ています。
これを示すために、先の
<MTIfSunday> 条件タグをコンテナタグとして無理矢理に書き換えてみました。
それが次の
ソースコード(
sample_2_4a.pl)です。
日曜日の場合のみ、ビルダでそのコンテンツを構築し、その内容をそのまま返すようにしています。
ビルダやコンテンツの取得部分は、コンテナタグと全く同じです。
そして日曜日以外の場合には、このコンテナタグは空文字を返すようにしています。
その結果、このプラグインは条件タグとして記述した
<MTIfSunday> と全く同じ機能を持つことがわかります。
このように条件タグと同じ機能をコンテナタグを利用して実装することも可能ですが、
単に条件によってコンテンツを表示するか否かを選択したいだけの場合は、条件タグを使用するのが良いでしょう。
また、変数タグやコンテナタグと同様に、
$args を使用して引数を扱うことができる点も同じです。
コンテナタグ中の条件タグ
普通の条件タグと特段変わったことはありません。
コンテナタグの中で変数タグを扱ったように、
stash を使用して条件判定を行うこともできます。
ここでは、先の
<MTMyLoop> で、
<MyLoopCount> の値が偶数か奇数かを判定する条件タグを書いてみましょう。
そして、この条件タグを使用したテンプレートは次のようになります。
この記事で使用した
プラグインのプログラムコードを
ダウンロードできます。