Movable Typeのテンプレートタグにおけるプライベートタグの正しい指定方法
Movable Typeでプライベートタグを使いたいときに指定する「include_privateモディファイア」が利用可能なテンプレートタグや、MTEntryIfTaggedタグでのプライベートタグの正しい判定方法について調べましたので、本エントリーで紹介します。
1.include_privateモディファイアが利用可能なテンプレートタグ
include_privateモディファイアは、プライベートタグを処理に含めたいときに指定するモディファイアです。
include_privateモディファイアが利用可能なテンプレートタグは、次の6種類です。
- MTEntryTags
- MTPageTags
- MTAssetTags
- MTEntryIfTagged
- MTPageIfTagged
- MTAssetIfTagged
MTEntryTagsタグでプライベートタグを対象にするには、次のようにinclude_privateモディファイアに「1」を設定します。
<mt:EntryTags include_private="1">
:
</mt:EntryTags>
include_privateモディファイアを指定しない場合は、「include_private="0"」と同じ意味になります。
2.MTXXXIfTaggedタグにおけるプライベートタグ判定方法
例えばMTEntryIfTaggedタグを使って、ブログ記事にプライベートタグ「@foo」が設定されていることを判定するには、前述のMTEntryTagsタグのお作法に従えば、次のようにtagモディファイアとinclude_privateモディファイアをセットで記述するように思われます。
<mt:EntryIfTagged tag="@foo" include_private="1">
:
</mt:EntryIfTagged>
ところが上記は誤りで、正解は次のようにtagモディファイアのみを記述します(正解はもうひとつありますが、話の流れ上、後述します)。
<mt:EntryIfTagged tag="@foo">
:
</mt:EntryIfTagged>
include_privateモディファイアを記述しない理由は、tagモディファイアで値を指定した場合、include_privateモディファイア自体が参照されなくなるためです。
ソースコードをトレースすると、MTEntryIfTaggedで起動される_hdlr_entry_if_taggedの処理は次のようになっています。tagモディファイアに値を設定している場合、赤色の部分が実行されます。
sub _hdlr_entry_if_tagged {
my ( $ctx, $args, $cond ) = @_;
my $entry = $ctx->stash('entry');
return 0 unless $entry;
my $tag
= defined $args->{name}
? $args->{name}
: ( defined $args->{tag} ? $args->{tag} : '' );
if ( $tag ne '' ) {
$entry->has_tag($tag);
}
else {
my @tags = $entry->tags;
@tags = grep /^[^@]/, @tags
if !$args->{include_private};
return @tags ? 1 : 0;
}
}
赤色部分で起動されているhas_tagの処理は、次のようになっています。
sub has_tag {
my $obj = shift;
my ($tag) = @_;
$tag = $tag->name if ref $tag;
foreach ( $obj->tags ) {
return 1 if $tag eq $_;
}
0;
}
このメソッドでは、引数に設定されたタグ名とオブジェクト(ブログ記事など)に設定されているタグ名をすべて比較し、一致すれば「1」を返却します。
つまり、通常のタグとプライベートタグとの区別などせず、MTEntryIfTaggedタグのtagモディファイアで指定したタグがブログ記事に設定されていれば、MTEntryIfTaggedブロックを実行します。
それでは、include_privateモディファイアはどのように使えばよいかというと、
tagモディファイアを指定せず、次のように記述します。
<mt:EntryIfTagged include_private="1">
:
</mt:EntryIfTagged>
上記のように「include_private="1"」のみを指定した場合、プライベートタグも含めて何らかのタグがブログ記事に設定されていれば、MTEntryIfTaggedブロックを実行します。先述の「『@foo』が設定されていることを判定するもうひとつの正解」がこの書き方です。ただし「@foo」以外のタグも判定に含まれます。
<mt:EntryIfTagged include_private="0">
:
</mt:EntryIfTagged>
上記のように「include_private="0"」を指定した場合、プライベートタグを除いた何らかのタグがブログ記事に設定されていれば、MTEntryIfTaggedブロックを実行します。
3.MTTagsタグでプライベートタグは出力可能か
MTTagsタグはそもそもプライベートタグを収集対象外としているので、MTTagsタグでプライベートタグを出力することはできません。プライベートタグを出力するには、MTEntryTagsなどのMTXXXTagsタグに「include_private="1"」を組み合わせます。
4.tagモディファイアで論理演算子は利用可能か
本題からそれますが、MTEntriesタグのtagモディファイアではANDやORなどの演算子が利用可能です。
MTEntryIfTaggedなどのMTXXXIfTaggedタグのtagモディファイアは、残念ながら論理演算子は利用できません。またカンマなどで区切って複数のタグを指定することもできません。
- Movable Typeでタグのインクリメンタルサーチを実現する
- Movable Typeの検索フォームでタグ検索をする
- Movable Typeのタグの「あいまい検索」について
- タグ別ブログ記事一覧
- Movable Type 5.0 のタグクラウドについて
- ウェブページで画像の出力を制御する
- 特定のランクのタグだけを表示する
- プライベートタグで特定のブログ記事一覧を表示する
- タグクラウドの折りたたみ for Movable Type 4
- タグ検索でエントリーの画像を表示する
- Movable Type 3.3 エントリー・タグ詳説