Movable Typeのテンプレートタグにおけるプライベートタグの正しい指定方法

Movable Typeのテンプレートタグにおけるプライベートタグの正しい指定方法

Posted at August 3,2011 3:33 AM
Tag:[include_private, MovableType, Tag]

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モディファイアは、残念ながら論理演算子は利用できません。またカンマなどで区切って複数のタグを指定することもできません。

関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)