MTIf タグの like 属性について
MTIf タグ(MTUnless タグ)の like 属性について、利用方法を紹介します。
この内容は、先日行われた「WebSig24/7 MT4分科会 第1回イベント『WebSig24/7 2007年秋 MT4の日』」で頂いたご質問、
- like 属性に or 演算子のようなものは使えますか?
- like 属性を使って、title 要素に表示するデータを収集したいのですが?
の回答です。ご返事が遅くなりましたこと、この場をお借りしてお詫びいたします。
1.like 属性の機能
MTSetVar タグに設定された変数、または MTSetVarBlock, MTSetVarTemplate ブロックタグの変数値が、like 属性に記述された文字列とマッチする場合に実行します。
また、属性値には perl の正規表現を使うことができます(厳密には、属性値は正規表現としてしか扱われません)。
2.ソースコード
lib/MT/Template/ContextHandlers.pm
の MTIf タグ(MTUnless タグ)の like 属性の処理は下の青色部分です。
sub _hdlr_if {
my ($ctx, $args, $cond) = @_;
my $var = $args->{name} || $args->{var};
my $value = $ctx->var($var);
:
} elsif (exists $args->{like}) {
my $re = eval { qr/$args->{like}/ };
return defined($value) && ($value =~ m/$re/) ? 1 : 0;
}
:
}
$args->{like}
には like の内容が設定されており、内容が存在すれば変数 $re
に代入します。この時、「qr// 演算子」を用いて、like の内容を正規表現として代入しています。
その後、m// 演算子を用いて、$value
(事前に取得されたもの)とのパターンマッチの結果(1 または 0)を返却します。
3.サンプル1
MTSetVar タグで、変数 hoge の値に "foo" を設定しています。
MTIf タグでは hoge に "f" が含まれていたらブロック内を実行します。この場合は含まれているので、ブロック内の MTGetVar を実行します。
<$mt:setvar name="hoge" value="foo"$>
<mt:if name="hoge" like="f">
<$mt:getvar name="hoge"$>
</mt:if>
Perl で書くと、多分下記のようになります。
my $hoge = 'foo';
if ($hoge =~ m/f/) {
print $hoge;
}
4.サンプル2
MTSetVar タグで、変数 hoge の値に "foo" を設定しています。
MTIf タグでは hoge に "foo" または "var" が含まれていたらブロック内を実行します。この場合は含まれているので、ブロック内の MTGetVar を実行します。
<$mt:setvar name="hoge" value="foo"$>
<mt:if name="hoge" like="foo|var">
<$mt:getvar name="hoge"$>
</mt:if>
Perl で書くと、多分下記のようになります。
my $hoge = 'foo';
if ($hoge =~ m/foo|var/) {
print $hoge;
}
4.サンプル3
ブログ記事リストのタイトルに "foo" または "var" が含まれているものだけを表示します。
<MTEntries>
<mt:setvarblock name="entrytitle"><$MTEntryTitle$></mt:setvarblock>
<mt:if name="entrytitle" like="foo|var">
<$mt:getvar name="entrytitle"$>
</mt:if>
</MTEntries>
Perl で書くと、多分下記のようになります。
for my $entrytitle (@entries) {
if ($entrytitle =~ m/foo|var/) {
print $entrytitle;
}
}
冒頭の2つめのご質問に適用する場合、このブロック全体を tilte 要素で括れば、ある程度期待する表示にできると思います。質問の解釈が誤ってましたら再度ご連絡ください。
5.参考
- Movable Type検索結果画面のMTIncludeタグでファイルを読み込む方法
- Movable Typeの月別コンテンツアーカイブリスト用テンプレート
- コンテンツデータでMTEntriesWithSubCategoriesの代替テンプレートタグ
- MTContentFieldタグの使い方
- Movable Typeでブログ記事一覧をカスタムフィールドでソートする方法
- MTの本文フィールドからimg要素のURLを取得する方法
- MTEntriesタグで指定した数の記事を除外して表示する方法
- Movable Typeのテンプレートタグの中でテンプレートタグを使う方法
- Movable Typeのテンプレートタグをテンプレートで生成する方法
- Movable TypeのMTEntriesタグで特定の複数ブログ記事を出力する方法
- Movable TypeでCSVデータからtable要素を作る方法
- MTIncludeタグのnameモディファイア
- Movable Type(MT)の特殊変数の入れ子
- ブロックタグにelseタグを組み込んで判定する
- Movable Type 5 におけるウェブサイトとブログの複数指定方法
MTIfのlike属性に変数を使っていてハマってしまいました。
カテゴリ-月別アーカイブのリストから動的に特定のカテゴリのリストを作ろうとして
取り出したいカテゴリ名をA+Cとして
変数$aにカテゴリ名
変数$bにカテゴリ-月別アーカイブのリストのタイトルをいれて
var $a value="A+C"
var $b value="[カテゴリ名]:00年00月"
と入っているイメージでMTIfのlikeで取り出せると思い
<MTArchiveList archive_type="Category-Monthly">
<$MTArchiveTitle setvar="$b">
<MTIf name="$b" like="$a">
good
<MTElse>
error
</MTElse>
</MTIf>
</MTArchiveList>
としてみた所 error となってしまいました。
で、もしやと思いカテゴリ名をA+Bと+部分を日本語に変更すると上手くgoodとなりました。
+部分が半角英数でも<MTVar name="a">や
<MTVar name="b">で表示するとA+Bという風に表示されるので
MTIf のlike属性の中では変数の中に演算子が入っていると
演算子が計算された値が入ってしますのでしょうか?
というかnameで呼び出した変数が計算されないだけなのでしょうか?
少し気になったので投稿させていただきました。
>kikiさん
こんにちは。
ご質問の件につきまして確認ですが、「A+C」は、Aというカテゴリー名とCというカテゴリー名の文字列の結合を行おうとされているのでしょうか。
またはカテゴリー名自身に「+」という記号が含まれているのでしょうか?
言い換えると、何がgoodで何がerrorとなるのを期待されているのか、もう少し具体的にお知らせください。
なお、「A」と「B」の文字列の結合を行うのであれば、
<mt:setvar name="cat" value="A" />
<mt:setvar name="cat" value="B" append="1" />
となります(質問の内容が理解できていないので筋違いな回答でしたらすいません)。
それではよろしくお願い致します。
お世話になっております。
説明の仕方が悪くて申し訳ないです。
カテゴリー名に半角英数の+を使っていて、つまり「A+C」というカテゴリー名にしていて、
カテゴリー名として「A+C」という文字列を変数に格納して
MTIfのlike属性で文字列「A+C」が含まれるとtrueといった具合に使おうとして...
という事だったのですが。
変数で
Var $a = "A+C"(カテゴリー名として動的に取得)
Var $b = "A+C:〜"(カテゴリ-月別アーカイブ名として動的に取得)
として
MTIf name="$b" like="$a"
とすると
$bには文字列「A+C」が含まれるので結果がtrueになると思っていた所
結果がfalseとなったので、???と思い、
カテゴリー名の「A+C」の+の部分を日本語の+に変えたら、
上記のif文の結果がtrueになったので、
like属性の変数$aの中身に半角英数の+などの演算子があった場合は、
Stringとして'A+C'が入るのではなく、
計算した結果の値(この場合「AC」)が格納される仕様なのかなと疑問に思ったので
(仮にname属性の$bの中身も計算されていたら「AC」で一致しますし...)
初歩的な事なのかもしれませんが質問させて頂きました。
>kikiさん
こんにちは。
ご質問の内容を理解致しました。
like モディファイアの中で半角の「+」を使用すると、正規表現用の文字(+の直前の文字が1文字以上あることを判定)として認識されます。したがって、like="A+B" と書くと、変数の値が「AB」「AAB」「AAAB」などでないと true になりません。
like モディファイアの中で「+」をそのままの文字(これを「リテラル」と言います)として扱いたい場合は、その文字をエスケープして「\+」にします。この場合であれば、like="A\+B" と書きます。
ただし、「全角文字の「+」に変更すれば期待通り動作する」ということなので、おそらくカテゴリー名に含まれる「+」がそもそも全角文字と思われます。したがって、like="A\+B" ではなく、like="A+B"(+は全角)で問題ないと思います。
like モディファイアは、半角の「+」を全角の「+」に変換するようなことはしません。
なお、半角の「+」は、name モディファイアや like モディファイアに記述しても演算子として動作しませんが、op モディファイアまたは、test モディファイアの中の式で利用すれば演算子として動作します。
あと、MTArchiveTitle タグの setvar モディファイアと、MTIf タグの name モディファイアの「$」は不要です。
それではよろしくお願い致します。
yujiroさま
お世話になっております。
なるほど、like属性の中が「AC」になっているのではなく、
正規表現の形で判定していたのですね!(正規表現には明るくなかったのでてっきり演算されているものだと思っていました。)
勘違いしたままにならないですみました。ありがとうございます。
(SetVarで :String とか指定ができたらなぁ〜。。。)
カテゴリー名等は半角の正規表現用の文字や演算子は使わない方が無難そうですね~ 何だか色々面倒な事が起こりそうだし...
>あと、MTArchiveTitle タグの setvar モディファイアと、MTIf タグの name モディファイアの「$」は不要です。
あっ...そうでした....
●いつも参考にさせていただいています。
like属性について質問させてください。
BlogIDをひろって以下のようにすると、機能するのですが、
MTIF name="blogcheck" like="1|2"
日本語のブログ名をひろって
MTIF name="blogcheck" like="ぶろぐアカ|ぶろぐアオ"
とすると機能しません。
ここに日本語は使えないのでしょうか。
ちなみに日本語でも一つの場合は機能しました。
「|」のときはダメなんでしょうか。。。
>成海さん
こんばんは。
ご返事遅くなりすいません。
ご質問の件ですが、別途ご返事致しますので、すいませんがもうしばらくお待ち頂けますでしょうか(週末は時間がとれないため来週になります)。
それではよろしくお願い致します。
>成海さん
こんにちは。
ご返事遅くなりすいません。
ご質問の件ですが、こちらで確認したところ、日本語についても正常に判定することを確認いたしました。
もう少し詳細に確認したいので、成海さん実際に使われたテンプレートタグをそのままコメントに貼り付け、設定されたブログ名もお知らせください。
またブログの文字コードはUTF-8でしょうか。
それではよろしくお願い致します。
お付き合いいただき感謝です。
ソースは
<MTSetVarBlock name="blogcheck"><MTBlogName></MTSetVarBlock>
<MTIF name="blogcheck" like="最新|Jコラム">
★任意の処理★
</MTIF>
です。
エントリー画面のedit_entry.tmpl内で使っています。
上記のコードですが、私の認識としては
[ blogcheckの変数に「最新」または「Jコラム」を含む場合に任意の処理を行う ]
です。
間違っていたらすみません。
文字コードはshift-jisで、
alt-tmpl内にedit_entry.tmplを置き、該当ブログのみ任意のCSSなどがあたるようにしています。
ちなみに
<MTIF name="blogcheck" like="^(最|J)>
だとうまく認識してくれました。
正規表現は深くはわからないんですが、
先頭にある文言でひっかけてみました。
先頭じゃなくてもうまくいきそうですが、
他の書き方がわからないもので。。。
いろいろ書きましたが、
不明点などあれば、なんなりとお願いします。
>成海さん
こんにちは。
ご連絡ありがとうございました。
正規表現は正しく記述されており、処理も妥当と思われます。
あと、確認ポイントとしては、edit_entry.tmpl 内で日本語を直接記述する場合、edit_entry.tmpl の文字コードとブログの文字コードが一致している必要があります。
具体的には、環境変数 PublishCharset で、ブログの文字コードをShift_JIS にしている場合は edit_entry.tmpl の文字コードをShift_JIS で保存してください。
ブログの文字コードが UTF-8(デフォルト)の場合は、edit_entry.tmpl の文字コードを UTF-8 で保存してください。
なお、デフォルトの edit_entry.tmpl に下記の判定処理を追加して、ブログ名に該当の文字列(「最新」または「Jコラム」)を追加したところ、UTF-8/Shift_JIS のいずれの文字コードでも正常に動作することを確認しました(edit_entry.tmpl の文字コードはブログの文字コードに合わせて変更して保存しています)。
<MTSetVarBlock name="blogcheck"><MTBlogName></MTSetVarBlock>
<name="blogcheck" like="最新|Jコラム">
★任意の処理★
</MTIF>
それではよろしくお願い致します。
検証いただき誠にありがとうございました。
文字コードは注視していたつもりなのですが、
今回あらためて保存したところ、正しい挙動になりました。
コピペしていたので、ヘンに拾ってきたのかもしれません。
ご丁寧な対応をいただき感謝です。
今後も参考にさせてきただきます。