今回は、前回に引き続き MTSeachEntries についてと、MTSplitVars タグの使い方です。 MTSearchEntries は基本的には1つの検索ワードで検索する仕様になっています。前回のサンプルでも、キーワード欄に入力した1つのキーワードを、動的に検索する方法を紹介しました。 今回は、MTSearchEntries に「 MTSplitVars 」というブロックタグを組み合わせ...
今回は、前回に引き続き MTSeachEntries についてと、MTSplitVars タグの使い方です。
MTSearchEntries は基本的には1つの検索ワードで検索する仕様になっています。前回のサンプルでも、キーワード欄に入力した1つのキーワードを、動的に検索する方法を紹介しました。
今回は、MTSearchEntries に「 MTSplitVars 」というブロックタグを組み合わせて複数の検索ワードで検索してみます。複数のキーワードは、キーワード欄にカンマ区切りで設定します。
今回の記事の完成版のコードは次のようになります。
<$mtml tag='mt:SetVars'$>
blog_id=<$mt:BlogID$>
entry_id=<$mt:EntryID$>
keywords=<$mt:EntryKeywords$>
keywords_length=<$mt:EntryKeywords regex_replace="/[^,]|\s/g","" cat="," count_characters="1"$>
limit=5
<$mtml tag='/mt:SetVars'$>
<mt:DynamicMTML>
<mt:SplitVars name="keyword" text="$keywords">
<$mt:Var name="__counter__" setvar="split_counter"$>
<$mt:Var name="keyword" trim="1" regex_replace="/\s| /g","%" setvar="keyword"$>
<mt:SearchEntries query="$keyword" blog_id="$blog_id" not_entry_id="$entry_id">
<$mt:EntryDate format="%Y%m%d%H%M%S" setvar="date"$>
<mt:SetVarBlock name="entries" key="$date">
<li><a href="<$mt:EntryPermalink$>"><$mt:EntryTitle$></a></li>
</mt:SetVarBlock>
</mt:SearchEntries>
<mt:If name="split_counter" eq="$keywords_length">
<mt:Loop name="entries" sort_by="key reverse">
<mt:If name="__counter__" eq="1">
<ul>
</mt:If>
<mt:If name="__counter__" le="$limit">
<mt:Var name="__value__">
</mt:If>
<mt:If name="__counter__" eq="$limit">
</ul>
</mt:If>
</mt:Loop>
</mt:If>
</mt:SplitVars>
</mt:DynamicMTML>
2011年12月27日現在、Github に公開されている DynamicMTML の MTSplitVars には2つほど不具合があります。その不具合を修正したファイルを用意しました。
このファイルをダウンロードして解凍し、次の場所にある同ファイルと置き換えてください。差し替えないと、今回の記事の内容はうまく動きません。
MTSplitVars タグは、text モディファイアで指定した文字列を delimiter モディファイアで指定した文字列で分割して、1つずつループで出力するブロックタグです。
まずは MTSplitVars のサンプルを見てみましょう。最もシンプルな例です。
<mt:SplitVars text="MT,MTOS,DynanicMTML">
<mt:If name="__first__"><ul></mt:If>
<li><$mt:Var name="value"$></li>
<mt:If name="__last__"></ul></mt:If>
</mt:SplitVars>
出力結果は次のようになります。
<ul>
<li>MT</li>
<li>MTOS</li>
<li>DynanicMTML</li>
</ul>
このように、text モディファイアにカンマ区切りのテキストを設定すると、カンマで分割された値を value という変数名で順次取り出すことができます。上記のコードを、デフォルト設定のままのモディファイアも省略せずに書くと次のようになります。
<mt:SplitVars name="value" text="MT,MTOS,DynanicMTML" delimiter="," glue="">
<mt:If name="__first__"><ul></mt:If>
<li><$mt:Var name="value"$></li>
<mt:If name="__last__"></ul></mt:If>
</mt:SplitVars>
設定できるモディファイアは以下の通りです。
MTSplitVars タグのループ内で、分割された1つ1つの値を取り出す変数名を指定します。デフォルトは value です。
上記のサンプルでは、デフォルトのままなので、MTVar name="value" で値を取り出しています。
区切り文字を指定します。デフォルトはカンマです。
分割するテキストを指定します。デフォルトはカンマ区切りのテキストですが、delimiter モディファイアで指定した値で区切ったテキストを指定できます。
1回のループを繋ぎ合わせる文字列を指定します。
MTSplitVars タグ内では、以下の値が MTVar にセットされます。
MTSplitVars の使い方が分かったところで、さっそくテンプレートを書いていきましょう。
まずは、キーワード欄に保存されているカンマ区切りの文字列を、カンマで分割して順次取り出すようにします。DynamicMTML、ブログ記事アーカイブテンプレートでの利用を前提にします。
このコードは、次のようになります。
<$mtml tag='mt:SetVars'$>
keywords=<$mt:EntryKeywords$>
<$mtml tag='/mt:SetVars'$>
<mt:DynamicMTML>
<mt:SplitVars name="keyword" text="$keywords">
<$mt:Var name="keyword" trim="1" regex_replace="/\s| /g","%" setvar="keyword"$>
<$mt:Var name="keyword"$><br />
</mt:SplitVars>
</mt:DynamicMTML>
以下、コードを分解して解説します。
まず、上段で、MTML タグを使って MTSetVars タグを出力します。その中で、カンマ区切りで入力したキーワード欄の値を keywords という変数にセットします。
<$mtml tag='mt:SetVars'$>
keywords=<$mt:EntryKeywords$>
<$mtml tag='/mt:SetVars'$>
このように、MTML タグで MTSetVars タグを出力すれば、変数をセットするところに MT タグが使えるので便利です。MTML タグについては「MTML タグで MT タグ自体を出力する方法」を参照してください。
下段は、MTDynamicMTML タグで囲み、ダイナミックに処理されるようにします。
上段でセットした変数 keywords の値を MTSplitVars の text モディファイアに渡し(text="$keywords")、順次 keyword という変数名(name="keyword")で取り出します。
<mt:SplitVars name="keyword" text="$keywords">
MTSplitVars 内の1行目で、カンマで分割されたキーワードの前後に余分なスペースが含まれていた場合は取り除き、キーワード中のスペースは任意の1文字を示す「%」に置換しています。
<$mt:Var name="keyword" trim="1" regex_replace="/\s| /g","%" setvar="keyword"$>
MTSplitVars 内の2行目の「<$mt:Var name="keyword"$><br />」は、動作確認のためのものです。
例えば、キーワード欄に「はじめて,dynamicmtml」と入力していた場合、上記のテンプレートにより次のように出力されます。
先ほどまでのコードは次のようになります。変わったのは上段部分です。
<$mtml tag='mt:SetVars'$>
blog_id=<$mt:BlogID$>
entry_id=<$mt:EntryID$>
keywords=<$mt:EntryKeywords$>
keywords_length=<$mt:EntryKeywords regex_replace="/[^,]|\s/g","" cat="," count_characters="1"$>
limit=5
<$mtml tag='/mt:SetVars'$>
<mt:DynamicMTML>
<mt:SplitVars name="keyword" text="$keywords">
<$mt:Var name="keyword" trim="1" regex_replace="/\s| /g","%" setvar="keyword"$>
<$mt:Var name="keyword"$><br />
</mt:SplitVars>
</mt:DynamicMTML>
上段の MTSetVars タグ内に、次のような変数をセットします。
ポイントは「分割されたキーワードの個数」です。
keywords_length=<$mt:EntryKeywords regex_replace="/[^,]|\s/g","" cat="," count_characters="1"$>
この部分は、次の流れで考えると分かりやすいと思います。
次に、上記のコードで取り出した変数 keyword の値を、MTSearchEntries に渡します。最終的なコードは次のようになります。変更部分は下段になります。
<$mtml tag='mt:SetVars'$>
blog_id=<$mt:BlogID$>
entry_id=<$mt:EntryID$>
keywords=<$mt:EntryKeywords$>
keywords_length=<$mt:EntryKeywords regex_replace="/[^,]|\s/g","" cat="," count_characters="1"$>
limit=5
<$mtml tag='/mt:SetVars'$>
<mt:DynamicMTML>
<mt:SplitVars name="keyword" text="$keywords">
<$mt:Var name="__counter__" setvar="split_counter"$>
<$mt:Var name="keyword" trim="1" regex_replace="/\s| /g","%" setvar="keyword"$>
<mt:SearchEntries query="$keyword" blog_id="$blog_id" not_entry_id="$entry_id">
<$mt:EntryDate format="%Y%m%d%H%M%S" setvar="date"$>
<mt:SetVarBlock name="entries" key="$date">
<li><a href="<$mt:EntryPermalink$>"><$mt:EntryTitle$></a></li>
</mt:SetVarBlock>
</mt:SearchEntries>
<mt:If name="split_counter" eq="$keywords_length">
<mt:Loop name="entries" sort_by="key reverse">
<mt:If name="__counter__" eq="1">
<ul>
</mt:If>
<mt:If name="__counter__" le="$limit">
<mt:Var name="__value__">
</mt:If>
<mt:If name="__counter__" eq="$limit">
</ul>
</mt:If>
</mt:Loop>
</mt:If>
</mt:SplitVars>
</mt:DynamicMTML>
下段のコードを分割して解説します。
MTSplitVars タグ内の最初で、変数 __counter__ の値を変数 split_counter に代入しています。
<$mt:Var name="__counter__" setvar="split_counter"$>
これは、MTSplitVars タグでセットされる特別な変数(__first__ や __counter__ など)が、入れ子になっている MTSearchEntries タグの後ろでは、MTSearchEntries タグの影響を受け、値が変わってしまう問題に対処するためです。この点は、ダイナミックパブリッシングのテンプレートを書くときには注意する必要がありそうです。
そのために、入れ子の後ろでもちゃんと特別な変数にアクセスできるように、最初に別の変数名にセットしておくわけです。
次に、MTSearchEntries タグに、上段の MTSeatVars タグでセットした変数などを渡します。
<mt:SearchEntries query="$keyword" blog_id="$blog_id" not_entry_id="$entry_id">
<$mt:EntryDate format="%Y%m%d%H%M%S" setvar="date"$>
<mt:SetVarBlock name="entries" key="$date">
<li><a href="<$mt:EntryPermalink$>"><$mt:EntryTitle$></a></li>
</mt:SetVarBlock>
</mt:SearchEntries>
そして、ここでは結果を直接出力せずに、一度 entries というハッシュ変数に代入します。変数 entries のキーは、MTEntryDate タグで取得したブログ記事の公開日を設定しています。こうすることで、後々公開日でソートすることができます。
最後に変数 entries の値を出力します。
<mt:If name="split_counter" eq="$keywords_length">
<mt:Loop name="entries" sort_by="key reverse">
<mt:If name="__counter__" eq="1">
<ul>
</mt:If>
<mt:If name="__counter__" le="$limit">
<mt:Var name="__value__">
</mt:If>
<mt:If name="__counter__" eq="$limit">
</ul>
</mt:If>
</mt:Loop>
</mt:If>
ここでポイントとなるのは、MTSplitVars タグの最後のループであるかを如何に判断するかです。
ここで MTSplitVars の前半で初期化した変数 split_counter (ループの回数)と、上段でセットした変数 keywords_length (=キーワードの数)を比較します。
<mt:If name="split_counter" eq="$keywords_length">
MTSplitVars は分割したキーワードをループで出力するので、キーワードの数とループの回数が同じであれば、それが最後のループということになります。
後は、MTLoop タグでハッシュ変数 entries の値を出力します。sort_by モディファイアで、キーの値でソートし、降順(reverse)に並べ替えています。
また、この入れ子になっている側のループでは、__counter__ の値は上書きされるのでそのまま使えます。したがって、__counter__ の値を使って出力数を制御しています。
MTSetVars で設定する limit の値を変更すれば、リストアップする記事数を変えられますし、sort_by の値を変えれば並び順を変更できます。
以上です。次回は、AND 検索の仕方を紹介します。