タグ検索を絞り込む(その2:カスタマイズ)
「タグ検索を絞り込む(その1)」の続きで、Movable Type 4 でのカスタマイズ方法です。
1.タグの絞り込み検索の仕組み
タグ検索は CGI(mt-search.cgi)を実行します。実行したURLのクエリー文字列の「tag=」の部分に、検索するタグ名を与えることでタグ検索が行なわれます。
例えば、タグ「Movable Type」による初回のタグ検索は次のようなURLを実行します。
http://user-domain/mt/mt-search.cgi?blog_id=1&tag=MovableType&limit=20&IncludeBlogs=1
このクエリー文字列「tag=」の右辺に、「 AND (ANDの前後に半角スペース)」を与えれば、複数のタグによる検索が可能になります。
例えば、タグ「Movable Type」と「Customize」で検索を行なうには、次のURLを実行します。
http://user-domain/mt/mt-search.cgi?blog_id=1&tag=MovableType%20AND%20Customize&limit=20&IncludeBlogs=1
「 AND 」はいくらでも連結できます。検索文字列と「AND」の間の「%20」は、半角スペースをURLエンコードしたものです。
つまり、前回のタグ検索文字列と今回のタグ検索文字列を「 AND 」で連結するサブテンプレートを作れば、この絞り込み検索の仕組みが実現できる訳です。
2.カスタマイズ
このカスタマイズでは Split プラグインを事前にインストールしてください。
その後、2.1~2.3に該当するいずれかの設定を行なってください。該当しない場合は、それらしき部分に追加してください。
なお、デザインはすべて確認できておりませんので、不具合がありましたらご連絡ください。
2.1 4.2 以降の「既定のブログ」の場合
次のサブテンプレート(青色)を、テンプレートモジュールの「ブログ記事の概要」に追加してください。
<mt:If name="entry_archive">
<mt:EntryIfTagged>
<div class="entry-tags">
<h4>タグ<span class="delimiter">:</span></h4>
<ul>
<li><mt:EntryTags glue='<span class="delimiter">,</span></li> <li>'><a href="javascript:void(0)" onclick="location.href='<$mt:TagSearchLink encode_js="1"$>';return false;" rel="tag"><$mt:TagName$></a></mt:EntryTags></li>
</ul>
<mt:searchString setvar="tag_name" />
<mt:if name="tag_name" like=" AND ">
<mt:getVar name="tag_name" split=" AND " setvar="tag_list">
<mt:else>
<mt:setVarBlock name="tag_list[0]"><mt:getVar name="tag_name"></mt:setVarBlock>
</mt:if>
<mt:setVar name="tag_data" value="" />
<mt:entryTags>
<mt:setVar name="tag_flag" value="0" />
<mt:loop name="tag_list">
<mt:if tag="TagName" eq="$__value__">
<mt:setVar name="tag_flag" value="1" />
</mt:if>
</mt:loop>
<mt:unless name="tag_flag">
<mt:setVarBlock name="tag_data" append="1"><a href="<mt:searchScript />?blog_id=<mt:blogID />&tag=<mt:searchString>%20AND%20<mt:tagName />&limit=20&IncludeBlogs=<mt:blogID />" rel="tag" title="<mt:searchString />と<mt:tagName />のタグ一覧へ"><mt:tagName /></a>,</mt:setVarBlock>
</mt:unless>
</mt:entryTags>
<h4>絞り込みタグ<span class="delimiter">:</span></h4>
<ul>
<li><mt:getVar name="tag_data" regex_replace="/(.*),$/","$1" /></li>
</ul>
</div>
</mt:EntryIfTagged>
</mt:If>
2.2 4.0 ~ 4.1 の場合
次のサブテンプレート(青色)を、テンプレートモジュールの「タグ」に追加してください。
<MTEntryIfTagged>
<div class="entry-tags">
<h4 class="entry-tags-header">タグ<span class="delimiter">:</span></h4>
<ul class="entry-tags-list">
<li class="entry-tag"><MTEntryTags glue='<span class="delimiter">,</span></li> <li class="entry-tag">'><a href="<$MTTagSearchLink$>&IncludeBlogs=<$MTBlogID$>" rel="tag"><$MTTagName$></a></MTEntryTags></li>
</ul>
<mt:searchString setvar="tag_name" />
<mt:if name="tag_name" like=" AND ">
<mt:getVar name="tag_name" split=" AND " setvar="tag_list">
<mt:else>
<mt:setVarBlock name="tag_list[0]"><mt:getVar name="tag_name"></mt:setVarBlock>
</mt:if>
<mt:setVar name="tag_data" value="" />
<mt:entryTags>
<mt:setVar name="tag_flag" value="0" />
<mt:loop name="tag_list">
<mt:if tag="TagName" eq="$__value__">
<mt:setVar name="tag_flag" value="1" />
</mt:if>
</mt:loop>
<mt:unless name="tag_flag">
<mt:setVarBlock name="tag_data" append="1"><a href="<mt:searchScript />?blog_id=<mt:blogID />&tag=<mt:searchString>%20AND%20<mt:tagName />&limit=20&IncludeBlogs=<mt:blogID />" rel="tag" title="<mt:searchString />と<mt:tagName />のタグ一覧へ"><mt:tagName /></a>,</mt:setVarBlock>
</mt:unless>
</mt:entryTags>
<h4 class="entry-tags-header">絞り込みタグ:<span class="delimiter">:</span></h4>
<ul class="entry-tags-list">
<li class="entry-tag"><mt:getVar name="tag_data" regex_replace="/(.*),$/","$1" /></li>
</ul>
</div>
</MTEntryIfTagged>
2.3 小粋空間テンプレートの場合
次のサブテンプレート(青色)を、テンプレートモジュールの「タグ」に追加してください。
<mt:entryIfTagged>
<div class="entry-tags">
<h3 class="entry-tags-header">タグ:</h3>
<ul class="entry-tags-list">
<mt:entryTags>
<li class="entry-tag"><a href="<mt:tagSearchLink />&IncludeBlogs=<mt:blogID />" rel="tag"><mt:tagName /></a></li>
</mt:entryTags>
</ul>
<mt:searchString setvar="tag_name" />
<mt:if name="tag_name" like=" AND ">
<mt:getVar name="tag_name" split=" AND " setvar="tag_list">
<mt:else>
<mt:setVarBlock name="tag_list[0]"><mt:getVar name="tag_name"></mt:setVarBlock>
</mt:if>
<mt:setVar name="tag_data" value="" />
<mt:entryTags>
<mt:setVar name="tag_flag" value="0" />
<mt:loop name="tag_list">
<mt:if tag="TagName" eq="$__value__">
<mt:setVar name="tag_flag" value="1" />
</mt:if>
</mt:loop>
<mt:unless name="tag_flag">
<mt:setVarBlock name="tag_data" append="1"><a href="<mt:searchScript />?blog_id=<mt:blogID />&tag=<mt:searchString>%20AND%20<mt:tagName />&limit=20&IncludeBlogs=<mt:blogID />" rel="tag" title="<mt:searchString />と<mt:tagName />のタグ一覧へ"><mt:tagName /></a>,</mt:setVarBlock>
</mt:unless>
</mt:entryTags>
<h3 class="entry-tags-header">絞り込みタグ:<span class="delimiter">:</span></h3>
<ul class="entry-tags-list">
<li class="entry-tag"><mt:getVar name="tag_data" regex_replace="/(.*),$/","$1" /></li>
</ul>
</div>
</mt:entryIfTagged>
3.サブテンプレート解説
2項のサブテンプレートの機能は、検索結果に表示されているブログ記事のタグから、現在の検索結果ページの検索タグを除外して表示します。そして、CGI(mt-search.cgi)のURLに、今回までの検索タグを「tag=」のクエリーに与えます。
このサブテンプレートを、いくつかのブロックに分けて解説します。
3.1 検索タグを分割して配列変数に設定
<mt:searchString setvar="tag_name" />
<mt:if name="tag_name" like=" AND ">
<mt:getVar name="tag_name" split=" AND " setvar="tag_list">
<mt:else>
<mt:setVarBlock name="tag_list[0]"><mt:getVar name="tag_name"></mt:setVarBlock>
</mt:if>
最初の MTSearchString タグで、今回表示されているタグ検索結果を変数 tag_name に保存します。変数 tag_name に「 AND 」が含まれていたら、split モディファイアを利用して、配列変数tag_listに、これまでのすべての検索タグを保存します。「 AND 」が含まれていない場合は、後続の処理で MTLoop タグを利用できるように、配列変数 tag_list の先頭に入れなおします。
3.2 ブログ記事に含まれるタグ一覧から、配列変数に設定されたタグを除外
<mt:setVar name="tag_data" value="" />
<mt:entryTags>
<mt:setVar name="tag_flag" value="0" />
<mt:loop name="tag_list">
<mt:if tag="TagName" eq="$__value__">
<mt:setVar name="tag_flag" value="1" />
</mt:if>
</mt:loop>
<mt:unless name="tag_flag">
...中略...
</mt:unless>
</mt:entryTags>
変数 tag_data を初期化し、MTEntryTag タグで、タグ検索でヒットしたブログ記事に含まれる、タグの一覧を処理します。変数 tag_flag は、これまでに使われた検索タグを出力から除外するためのフラグです。
フラグを設定する処理は、MTLoop タグを使って配列変数 tag_list をサーチすることで実現しており、これまでに使われた検索タグをみつけたら、変数 flag に 1 を設定します。
変数 tag_flag に 1 が設定されたら、次の MTUnless タグブロック内は実行せず、まだ検索タグとして登場していないタグだけを MTUnless タグブロック内で出力します。
3.3 ブログ記事に含まれるタグ一覧を変数に設定
<mt:unless name="tag_flag">
<mt:setVarBlock name="tag_data" append="1"><a href="<mt:searchScript />?blog_id=<mt:blogID />&tag=<mt:searchString>%20AND%20<mt:tagName />&limit=20&IncludeBlogs=<mt:blogID />" rel="tag" title="<mt:searchString />と<mt:tagName />のタグ一覧へ"><mt:tagName /></a>,</mt:setVarBlock>
</mt:unless>
MTUnless タグ内部では、タグ検索用のリンクを出力します。href 属性の値に、前回までの検索タグを MTSearchString タグ、そして今回の検索タグを MTTagNameタグ で与え、その間を「%20AND%20」で区切ります。リンクは直接出力せず、MTSetVarBlock タグを使って、変数 tag_data に一旦保存します。理由はあとで説明します。
3.4 ブログ記事に含まれるタグ一覧を出力
絞り込みタグ:<mt:getVar name="tag_data" regex_replace="/(.*),$/","$1" />
すべての処理が終わったら、変数 tag_data を出力します。
出力するタグの区切り文字をカンマ「,」にしているのですが、一番最後の「,」を、MTUnless タグブロック内の処理で出力しない制御がかなり面倒(=出力するタグが繰り返しの最後であることを判定するのが面倒)だったので、出力結果を一旦変数に保持し、変数を出力するときに regex_replace モディファイアで最後の1文字、つまりカンマを除去しています。
今回のタグ検索で使ったタグは、次のタグ検索結果ページの MTSearchString タグで取得できるので、再帰的な検索が行なえます。
- Movable Type検索でURL改ざんによるブログ検索をできないようにする方法
- Movable Typeの検索オプション徹底解説
- Movable Type 5.1の検索で「blog_idパラメータが不正です。」となる不具合の対処
- Movable Type 5.1の検索で検索結果テンプレートを指定する方法
- Movabel Type の検索結果フィードを利用する
- Movable Type検索結果のブログ記事タイトルからアーカイブページへリンクする方法
- Movable Type で複数ブログを検索する
- タグ検索を絞り込む(その1)
- Movable Type 検索の全角スペースを半角スペースと同じ振る舞いにする(MT4版)
- Movable Type 4.2 検索結果ページのカスタマイズ:ページナビゲーションをプルダウンメニューにする
- Movable Type 4.2 検索結果ページのカスタマイズ:ナビゲーションを検索結果の上下に表示する
- Movable Type 4.2 検索結果ページのカスタマイズ:検索結果が1ページだけのときに「1」という表示をなくす
- Movable Type 4.2 検索結果ページのカスタマイズ:検索結果の見出しに(現在のページ/総ページ数)を表示する
- Movable Type 4.2 検索結果ページのカスタマイズ:1ページに表示する件数を変更する
- システムテンプレートとその他のテンプレートを振り分ける
≫ [MT]タグ検索結果を絞り込み!複数タグでAND検索(1) from Notebook :: Hibi no Note
Movable Typeのカスタマイズ ネタです。 このブログのタグ検索画面で表示されるタグのリンクを表示するように変更しました。また、リンクをクリックす... [続きを読む]
こんばんわ^^
やっぱりそうでしたか (●´∀`●)
ブログ検索では AND 検索可能なので同じ mt-search.cgi ならタグ検索も・・・と考えてました。
じゃぁ、わたし検索されたエントリのタグクラウドを作ってみよっかなぁ。
そこから絞込みを可能にしてみます。
>bzbellさん
こんばんは。
それでは楽しみにお待ちしています。
タグネタ、まだまだ色々ありそうですね。
ではでは!
さっそく参考にさせて頂きました。
タグクラウドでサイドバーに表示したかったのですが、クラウドにする為にはもう一工夫必要なようです。
こんばんは。
パーフェクトガイド4.2のテンプレートでは、テンプレート「メタデータ」に挿入するのだと思いますが、8行目の次に挿入したところ、最初から、絞込みTagが表示されてしまいます。おそらく、Tag検索をして、はじめて絞込みTagが表示されると思うのですが、挿入場所が違うのでしょうか、それとも、他に手を加えるところがあるのでしょうか。
宜しく、お願いいたします。
>neroさん
こんばんは。
ご質問の件ですが、説明に不足がありました。
「メタデータ」に設定した状態で、追加した青色のサブテンプレートを、下記のテンプレートタグで括ってみてください。
<mt:if name="search_results">
:
中略
:
</mt:if>
それではよろしくお願い致します。
こんばんは。
そのようにしてみたら、表示は正常になったのですが、Tagによっては下記のエラーがでるようになってしまいました。上記のテンプレートタグで括る前は表示はおかしかったものの、エラーはでなかったのですが。
テンプレート「検索結果」の再構築中にエラーが発生しました: <mtgetVar>タグでエラーがありました:
<mtsearchResults>タグでエラーがありました:
<mtinclude>タグでエラーがありました:
error in module ブログ記事の概要:
テンプレート「ブログ記事の概要」の再構築中にエラーが発生しました: <mtinclude>タグでエラーがありました:
error in module メタデータ:
テンプレート「メタデータ」の再構築中にエラーが発生しました:
<mtif>タグでエラーがありました:
<mtentryIfTagged>タグでエラーがありました:
<mtif>タグでエラーがありました:
<mtsearchResults>タグでエラーがありました:
<mtinclude>タグでエラーがありました:
モジュールでお互いがお互いを参照している状態になっています:
ブログ記事の概要
宜しくお願いします。
>neroさん
こんばんは。
ご返事遅くなってすいません。
[5]の回答は誤りでした。申し訳ありません。
<mt:if tag="searchString">
:
中略
:
</mt:if>
としてください。
それではよろしくお願い致します。
こんばんは。
無事、正常に表示することができました。
ありがとうございます。
ちょっと、諦めかけていたので、助かりました(^^)