チャレンジ! Movable TypeをCMSとして使ってみよう!

第13回検索用テンプレートに着手しよう!

今日は、システムテンプレート内の「検索結果」テンプレートのカスタマイズに取り掛かります。

くれま先輩:と、その前に!まずは恒例のMovable Typeアップデート情報に触れてみましょう!

ほげ山くん:出てましたね!しかも2つありますねー。

くれま先輩:ひとつは、セキュリティアップデートのMovable Type 4.24。⁠特殊な操作を行うと、サインインしていないユーザーが特定のユーザーのプロフィール編集画面にアクセスできてしまう。」という問題が解決されているので、皆さんぜひアップデートしてくださいね!

ほげ山くん:はーい!

【参考ページ】
Six Apart - Movable Type News: [重要] セキュリティアップデート Movable Type 4.24 の提供を開始
http://www.sixapart.jp/movabletype/news/2009/02/27-1400.html

くれま先輩:もうひとつは、昨年末話題に上っていたMotionを含むMovable Type 4.25のRC3が発表されてるのよー。今回から日本語ビルドも提供されてるし!

【参考ページ】
Movable Type 4.25 RC3 の提供を開始 | MovableType.jp
http://www.movabletype.jp/blog/movable_type_425_rc3.html

ほげ山くん:「RC」というのは、リリース候補版のことですよね?

くれま先輩:そうそう。まだ正式版じゃないから、テストの環境にインストールしてみて、色々試してみるといいよ!以下の蒲生トシヒロさんの記事にて「Movable Type Motionで、複数の方に投稿してもらう設定」などが詳しく解説されているので、興味のある人はぜひ読んでみてね!

【参考ページ】
【Movable Type Motion】Movable Type 4.25 RC3 日本語ビルド公開: 世界中の1%の人々へ
http://www.dakiny.com/archives/movable-type/
movable_type_motionmovable_type_425_rc3/

検索用テンプレートの編集画面を確認

くれま先輩:ではでは、作業に入っていこうね。今日は検索用テンプレートに取り掛かっていくよ!いままでの作業で、head要素の中身やdivを使った大まかな枠なんかは、できているでしょ?

ほげ山くん:あ、確認するので、待ってください!まずは、管理画面上部の[デザイン→テンプレート]クリックして、一覧画面を表示っと…。次に、⁠システムテンプレート」のセクションにある「検索結果」をクリック、でいいんですよね?

くれま先輩:うんうん。

ほげ山くん:いま、こんなところまで、できてますね。

これまでの作業で書かれた「検索結果」テンプレートの中身
<?xml version="1.0" encoding="<mt:PublishCharset />"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>

<mt:Include module="head要素" />
</head>
<body>
<div id="container">
	<div id="header">
		<mt:Include module="ヘッダ領域" />
	<!-- end div#header --></div>
	<div id="nav">
	<!-- end div#nav --></div>
	<div id="primary">
	<mt:Include module="パンくずナビゲーション" />
	<!-- end div#primary --></div>
	<div id="secondry">
	<!-- end div#secondry --></div>
	<div id="footer">
		<mt:Include module="フッタ領域" />
	<!-- end div#footer --></div>
<!-- end div#container --></div>
</body>

検索結果を表示させるサブテンプレートを追記する

くれま先輩:そうだね。他のテンプレートの場合とだいたい一緒だっただよね。じゃあまずは、div id="primary"の中の「パンくずナビゲーション」の直後に、検索結果を表示させるサブテンプレートを書いていこう。

div id="primary"内「パンくずナビゲーション」の直後に記述するサブテンプレート
<mt:SearchResults>
	<mt:BlogResultHeader>
	<h1>「<mt:SearchString />」での検索結果</h1>
	</mt:BlogResultHeader>
	<div class="serchResult">
		<h2><a href="<mt:EntryLink />"><mt:EntryTitle /></a></h2>
		<mt:SetVarBlock name="entry_category"><mt:EntryCategory></mt:SetVarBlock>
		<mt:If name="entry_category" eq="最新情報">
			<p><mt:EntryBody words="50" /></p>
		<mt:Else>
			<dl>
			<dt>著者名</dt>
			<dd><mt:author_name /></dd>
			<dt>発売日</dt>
			<dd><mt:release_date /></dd>
			<dt>対象年齢</dt>
			<dd><mt:readers_age /></dd>
			<dt>版型</dt>
			<dd><mt:book_size /></dd>
			<dt>説明</dt>
			<dd><mt:EntryBody words="50" /></dd>
			</dl>
			<p><mt:coverAsset><a href="<mt:EntryLink />"><img src="<mt:AssetThumbnailURL width="100" />"alt="<mt:EntryTitle />" title="<mt:EntryTitle />" /></a></mt:coverAsset></p>
		</mt:If>
	</div>
</mt:SearchResults>

ほげ山くん:この連載で初めて、mt:SearchResultsというのが出てきましたね!

くれま先輩:そうだね!これは「検索結果」テンプレートの中で、実行した検索の結果を表示するブロックタグなのよ。条件に当てはまるブログ記事に関するデータを、mt:Entriesなどと同じようにループで出力するイメージだね。なので、このブロックタグの中で、mt:Entryxxxxxxxというタグを使えるわけだ。

ほげ山くん:なるほど、このサブテンプレート内に、mt:EntryLink、mt:EntryTitleなどが入っていますね。んー、mt:BlogResultHeaderってなんでしたっけ?

くれま先輩:テンプレートタグリファレンスを見ると、⁠実行した検索の結果は、ブログごとにグループにまとめられています。まとめられたグループの中の最初の結果を表示するときに、その内容を表示するブロックタグです。」とあるんだよね。

ほげ山くん:じゃ、複数のブログがあるときは、検索結果のブログごとのグループの頭に、この中身が表示されるっていうことですよね?

くれま先輩:そうなんだけれど、その前に、⁠ヘッダ領域」というテンプレートモジュールの中にこんな書き方をしたのを覚えてるかな?

「ヘッダ領域」テンプレートモジュール内の、検索フォーム内の記述
<form method="get" action="<mt:CGIPath /><mt:SearchScript />">
	<p><input type="hidden" name="IncludeBlogs" value="<mt:BlogID />" /><input name="search" type="text" id="search" value="<mt:SearchString />" />
	<input name="submit" type="image" src="<mt:BlogUrl />img/btn_search.gif" alt="検索" id="submit" />
	</p>
</form>

ほげ山くん:ちょ、ちょっと待ってください…。探します…。あぁ、書いてありましたね!

くれま先輩:2行目のname="IncludeBlogs" value="<mt:BlogID />"って書いてある部分で、特定のIDのブログに含まれる記事だけを検索結果に含めるように指定しているの。詳しくは、以下のページを参考にしてみてね。

【参考ページ】
MTSearchResults | テンプレートタグリファレンス
http://www.movabletype.jp/documentation/appendices/tags/
searchresults.html

ほげ山くん:要するに、このブログのIDだけが「IncludeBlogs」の値として設定されるわけですね。

くれま先輩:そうそう。そうすると、mt:SearchResultの中には、いつもひとつのブログに含まれる検索結果だけがリストアップされるってことだから、mt:BlogResultHeaderもループの中で1回しか表示されないってことになるよね。

ほげ山くん:そういう使い方を前提として、mt:BlogResultHeaderの中に「<h1>「<mt:SearchString />」での検索結果</h1>」って書いてあるんですね。この部分は「⁠⁠検索キーワード⁠⁠』での検索結果」って出力されるんですよねー。

くれま先輩:うん。この部分をこの検索結果の大見出しにしたいから、h1でマークアップしているんだよね。

ほげ山くん:でもそうするんだったら、mt:SearchResultsの外側に「<h1>「<mt:SearchString />」での検索結果</h1>」って書いてもいいんじゃないんですかね?

くれま先輩:そうしたいんだけど、検索結果が見つからなかった時の処理も考えておかなければいけないわけですよ。

ほげ山くん:はぁ。

くれま先輩:そのときは、h1に「⁠⁠<mt:SearchString />』と一致する結果は見つかりませんでした。」って出したいんだよね。

ほげ山くん:あ、なるほど。mt:SearchResultsの外側に固定されたh1を書いてしまうと、検索結果が見つからなかった時に不整合が生じるんですね。

くれま先輩:ではどうするかというのは次のセクションで説明するから、先に、mt:SetVarBlockとmt:Ifを使って条件分岐をしているところについて話しておくねー。

ほげ山くん:そうそう、mt:SearchResultsの中で条件分岐をしてるのが、気になってたんですよね。

くれま先輩:「最新情報」カテゴリとそれ以外のカテゴリで、投稿内容の体裁が全然違うでしょ?それぞれに合った体裁で、結果を出力したいわけ。だからmt:SetVarBlockを使って、mt:EntryCategoryの値を変数「entry_category」の中に設定しているの。

ほげ山くん:mt:EntryCategoryというのは、⁠ブログ記事に指定されたメインカテゴリ」が出力されるんですよね…。そうか、そのブログ記事のメインカテゴリが「最新情報」かそうでないかを判別して、条件分岐してるんですね。

くれま先輩:うん、その通り!

検索結果が見つからなかったときの処理を加える

くれま先輩:っじゃ、さっき言っていた「検索結果が見つからなかった時の処理」について話をしようかな。

ほげ山くん:お願いしまーす。

くれま先輩:さっきのmt:SearchResultsのサブテンプレートの下に、こんな風に書いてみてね。

mt:SearchResultsのサブテンプレートの下に記述するサブテンプレート
<mt:NoSearchResults>
<h1>「<mt:SearchString />」と一致する結果は見つかりませんでした。</h1>
<a href="<mt:BlogUrl />">トップページに戻る</a>
</mt:NoSearchResults>

ほげ山くん:NoSearchResultsって、検索結果が無かった時に実行されるタグってことですか?

くれま先輩:そうよ!ほら、この中に<h1>「<mt:SearchString />」と一致する結果は見つかりませんでした。</h1>って書いているでしょ?こうして、状況によって異なるh1を出力し分けているってこと。

ほげ山くん:なるほどです。

くれま先輩:さて今回はこのくらいにして、次回はもう少し検索用テンプレートについて理解を深めていこうね。Movable Type4.2以降では検索結果が多かった時にAjaxを使ったページ分割ができるようになっているから、それについても説明するよ!

ほげ山くん:楽しみにしてます!

次回予告

おすすめ記事

記事・ニュース一覧