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

最終回 「最新記事のフィード」完成/サンプルサイトとテンプレートプラグイン

一年近く続いてきたこの連載ですが、今日でいよいよ最終回です。残りのテンプレート「最新記事のフィード」を少しカスタマイズした後、サンプルサイトとテンプレートプラグインのご紹介をします。

「最新記事のフィード」をカスタマイズして完成させる

ほげ山くん:先輩、まだいじっていないテンプレートって、⁠最新記事のフィード」だけなんですよね?

くれま先輩:うん。これを完成させたら、説明は完了だよ!頑張っていきましょ。ではでは、⁠デザイン→テンプレート]を選択して、インデックステンプレートのセクションの下にある「最新記事のフィード」をクリックしてね。

ほげ山くん:開きました。4.25デフォルトのテンプレートは、こんな感じですね。

4.25デフォルトの「最新記事のフィード」テンプレート
<$mt:HTTPContentType type="application/atom+xml"$><?xml version="1.0" encoding="<$mt:PublishCharset$>"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title><$mt:BlogName remove_html="1" encode_xml="1"$></title>
    <link rel="alternate" type="text/html" href="<$mt:BlogURL encode_xml="1"$>" />
    <link rel="self" type="application/atom+xml" href="<$mt:Link template="feed_recent"$>" />
    <id>tag:<$mt:BlogHost exclude_port="1" encode_xml="1"$>,<$mt:TemplateCreatedOn format="%Y-%m-%d"$>:<$mt:BlogRelativeURL encode_xml="1"$>/<$mt:BlogID$></id>
    <updated><mt:Entries lastn="1"><$mt:EntryModifiedDate utc="1" format="%Y-%m-%dT%H:%M:%SZ"$></mt:Entries></updated>
    <mt:If tag="BlogDescription"><subtitle><$mt:BlogDescription remove_html="1" encode_xml="1"$></subtitle></mt:If>
    <generator uri="http://www.sixapart.com/movabletype/"><$mt:ProductName version="1"$></generator>
<mt:Entries lastn="15">
<entry>
    <title><$mt:EntryTitle remove_html="1" encode_xml="1"$></title>
    <link rel="alternate" type="text/html" href="<$mt:EntryPermalink encode_xml="1"$>" />
    <id><$mt:EntryAtomID$></id>

    <published><$mt:EntryDate utc="1" format="%Y-%m-%dT%H:%M:%SZ"$></published>
    <updated><$mt:EntryModifiedDate utc="1" format="%Y-%m-%dT%H:%M:%SZ"$></updated>

    <summary><$mt:EntryExcerpt remove_html="1" encode_xml="1"$></summary>
    <author>
        <name><$mt:EntryAuthorDisplayName encode_xml="1"$></name>
        <mt:If tag="EntryAuthorURL"><uri><$mt:EntryAuthorURL encode_xml="1"$></uri></mt:If>
    </author>
    <mt:EntryCategories>
        <category term="<$mt:CategoryLabel encode_xml="1"$>" scheme="http://www.sixapart.com/ns/types#category" />
    </mt:EntryCategories>
    <mt:EntryIfTagged><mt:EntryTags><category term="<$mt:TagName normalize="1" encode_xml="1"$>" label="<$mt:TagName encode_xml="1"$>" scheme="http://www.sixapart.com/ns/types#tag" />
    </mt:EntryTags></mt:EntryIfTagged>
    <content type="html" xml:lang="<$mt:BlogLanguage ietf="1"$>" xml:base="<$mt:BlogURL encode_xml="1"$>">
        <$mt:EntryBody encode_xml="1"$>
        <$mt:EntryMore encode_xml="1"$>
    </content>
</entry>
</mt:Entries>
</feed>

くれま先輩:そうそう。このテンプレートが使われて、ブログの公開URL直下に「atom.xml」という名前のファイルが生成されるんだよね。このテンプレートをこのまま使ってもそんなには悪くないんだけど、これだと個々の絵本紹介記事のカスタムフィールドに入力した情報が出力されないのよね。ほら、⁠atom.xml」の一つ分の記事を見てみると、こんな感じなんだもん。

atom.xmlの一部分を抜粋したもの
<entry>
    <title>妖精を見つけた!</title>
    <link rel="alternate" type="text/html" href="http://xxx.xxxxxx.xx/gihyo-jp/world/post.html" />
    <id>tag:localhost,2008:/xxxxxxxxx//1.202</id>

    <published>2009-03-17T17:14:58Z</published>
    <updated>2009-05-06T07:21:08Z</updated>

    <summary>ある日ベットの下の穴を覗いてみたら、妖精のおうちを見つけてしまった!メアリーと妖...</summary>
    <author>
        <name>crema</name>
        
    </author>
    
        <category term="海外作家の絵本" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="ファンタジー" label="ファンタジー" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://xxx.xxxxxx.xx/gihyo-jp/">
        <![CDATA[<p>ある日ベットの下の穴を覗いてみたら、妖精のおうちを見つけてしまった!メアリーと妖精の心温まる冒険物語。</p>]]>
        
    </content>
</entry>

ほげ山くん:うゎ。これを見ても、よくわかんないですね…。

くれま先輩:下から4行目を見てみて。⁠<![CDATA[<p>ある日ベットの下の穴を覗いてみたら、妖精のおうちを見つけてしまった!メアリーと妖精の心温まる冒険物語。</p>]]>」って出力されているけど、これってブログ記事投稿画面の「本文」欄に入力した内容が「<$mt:EntryBody encode_xml="1"$>」で出力されてるんだよね。

ほげ山くん:あー、なるほど。そうか。他にも「著者名」「発売日」なんかを投稿したのに、それが出力されてないってことですよね。

くれま先輩:そうそう。だから、こんな風にテンプレートを変更するよ。

変更後の「最新記事のフィード」テンプレート
<mt:HTTPContentType type="application/atom+xml" /><?xml version="1.0" encoding="<mt:PublishCharset />"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><mt:BlogName remove_html="1" encode_xml="1" /></title>
<link rel="alternate" type="text/html" href="<mt:BlogURL encode_xml="1" />" />
<link rel="self" type="application/atom+xml" href="<mt:Link template="feed_recent" />" />
<id>tag:<mt:BlogHost exclude_port="1" encode_xml="1" />,<mt:TemplateCreatedOn format="%Y-%m-%d" />:<mt:BlogRelativeURL encode_xml="1" />/<mt:BlogID></id>
<updated><mt:Entries lastn="1"><mt:EntryModifiedDate utc="1" format="%Y-%m-%dT%H:%M:%SZ" /></mt:Entries></updated>
<mt:If tag="BlogDescription"><subtitle><mt:BlogDescription remove_html="1" encode_xml="1" /></subtitle></mt:If>
<generator uri="http://www.sixapart.com/movabletype/"><mt:ProductName version="1" /></generator>
<mt:Entries lastn="15">
<entry>
<title><mt:EntryTitle remove_html="1" encode_xml="1" /></title>
<link rel="alternate" type="text/html" href="<mt:EntryPermalink encode_xml="1" />" />
<id><mt:EntryAtomID /></id>

<published><mt:EntryDate utc="1" format="%Y-%m-%dT%H:%M:%SZ" /></published>
<updated><mt:EntryModifiedDate utc="1" format="%Y-%m-%dT%H:%M:%SZ" /></updated>

<summary><mt:EntryExcerpt remove_html="1" encode_xml="1" /></summary>
<author>
<name><mt:EntryAuthorDisplayName encode_xml="1" /></name>
<mt:If tag="EntryAuthorURL"><uri><mt:EntryAuthorURL encode_xml="1" /></uri></mt:If>
</author>
<mt:EntryCategories>
<category term="<mt:CategoryLabel encode_xml="1" />" scheme="http://www.sixapart.com/ns/types#category" />
</mt:EntryCategories>
<mt:EntryIfTagged><mt:EntryTags><category term="<mt:TagName normalize="1" encode_xml="1" />" label="<mt:TagName encode_xml="1" />" scheme="http://www.sixapart.com/ns/types#tag" />
</mt:EntryTags></mt:EntryIfTagged>
<content type="html" xml:lang="<mt:BlogLanguage ietf="1" />" xml:base="<mt:BlogURL encode_xml="1" />">
<mt:IfCategory name="最新情報">
<mt:EntryBody encode_xml="1" />
<mt:Else>
著者名:<mt:author_name encode_xml="1" />/発売日:<mt:release_date encode_xml="1" />/対象年齢:<mt:readers_age encode_xml="1" />/版型:<mt:book_size encode_xml="1" />
<mt:EntryBody encode_xml="1" />
</mt:IfCategory>
</content>
</entry>
</mt:Entries>
</feed>

ほげ山くん:あ、まずはファンクションタグの書き方を、この連載用のルールに変更したんですね?

くれま先輩:そうなの。ファンクションタグの「$」をとって、最後に「/」をつけるルールに合わせたのよ。で、変更したのは<mt:IfCategory name="最新情報">~</mt:IfCategory>の部分なの。⁠最新情報」カテゴリとそれ以外のカテゴリの場合に出力する内容を変えたいから、この条件分岐を入れたわけ。

ほげ山くん:「最新情報」カテゴリの場合は、<mt:EntryBody encode_xml="1" />で本文だけを出力するんですね。

くれま先輩:うん。それで、⁠最新情報」カテゴリじゃない場合には、さっき話したみたいに「著者名:<mt:author_name encode_xml="1" />/発売日:<mt:release_date encode_xml="1" />/対象年齢:<mt:readers_age encode_xml="1" />/版型:<mt:book_size encode_xml="1" />」の部分を追加したの。これで、個々の絵本に関する文字情報をきちんとRSSフィードに掲載できるでしょ。

ほげ山くん:なるほどー。

くれま先輩:でも、ここで、あと1つMovable Typeの設定を変更しておきたいことがあるの。XMLのちょっと詳しい話になるんだけれど、もしこのテンプレートをこのまま使った場合、万が一カスタムフィールドの値として「<」「>」などの文字が含まれていると、出力される文字列が「CDATAセクション」として出力されてしまうのよね。

ほげ山くん:「CDATAセクション」って、なんでしたっけ…?

くれま先輩:さっき見た「<![CDATA[<p>ある日ベットの下の穴を覗いてみたら、妖精のおうちを見つけてしまった!メアリーと妖精の心温まる冒険物語。</p>]]>」ってあったでしょ?この例のように、本文内に含まれているHTMLタグなんかはXML文書の中でマークアップの指定として扱われてしまうから、まずいんだよね。そこでMovable Typeのシステムが出力する文字列を判別して、HTMLタグなどが含まれている場合には、⁠<![CDATA[~]]>」という文字列で括って出力してくれるわけだ。このように括ってある「CDATAセクション」のなかでは、⁠<」「>」が書いてあっても問題ないの。

ほげ山くん:ふむふむ。

くれま先輩:だけど、RSSリーダーによっては、⁠<![CDATA[~]]>」で括られた部分とそうでない部分が混在すると、うまく読み込めない場合があるんだって。だからHTMLタグなどが含まれる場合に「<![CDATA[~]]>」で括る処理を行わないで、⁠&lt;」とか「&gt;」のような実体参照に変換してくれるように、Movable Typeの設定を変更したいの。

ほげ山くん:うーむ。どうにか分ったような気がします…。で、その設定はどうやればいいんですか?

くれま先輩:サーバのMovable Typeをインストールしたディレクトリの直下に「mt-config.cgi」というファイルがあるでしょ?その一番下に「NoCDATA 1」という環境変数を追加するだけ。詳しくは、movabletype.jpにも説明があるから見てみてね。それから、⁠小粋空間」の荒木勇次郎さんの関連エントリもあるので、ぜひ読んでみて。

【参考ページ】
NoCDATA | 環境変数リファレンス
http://www.movabletype.jp/documentation/appendices/config-directives/
nocdata.html
小粋空間: RSSリーダーの本文表示の違いを探る(その1)
http://www.koikikukan.com/archives/2005/01/27-193023.php
小粋空間: RSSリーダーの本文表示の違いを探る(その2)
http://www.koikikukan.com/archives/2005/01/28-170550.php
小粋空間: RSSリーダーの本文表示の違いを探る(その3:NoCDATAの利用)
http://www.koikikukan.com/archives/2005/01/29-220023.php

ほげ山くん:とりあえず「NoCDATA 1」を設定しましたー。

サンプルサイトとテンプレートプラグイン

くれま先輩:お疲れ様!これでとりあえず、テンプレートのカスタマイズは全部完了だよ!

ほげ山くん:おぉー。ちょっと嬉しいですね!

くれま先輩:この連載では少しずつ文章で説明してきたこともあって、サイトの全体像がつかみにくかったかもしれません。そこで最後に、読者の皆様向けにサンプルのサイトをお見せしたいと思います。

図1 サンプルサイト「絵本出版のリブリート」のトップページ
図1 サンプルサイト「絵本出版のリブリート」のトップページ

ほげ山くん:うぅ、なんというか、血と汗と涙の結晶ですねっ。でも先輩、こうやって外からサイトを見るだけじゃ、読者の方には物足りないんじゃないですか?やっぱりテンプレートの中身を見ないと…。

くれま先輩:はいはい。わかってまーすw だから、テンプレートセットプラグインを作っておいたよ!以下のURLで配布しますので、読者の方はぜひ練習で使ってみてくださいね。

「絵本出版のリブリート」テンプレートセットプラグイン
http://crema.s42.coreserver.jp/gihyo-jp/ChallengeMTForCMS.zip

ほげ山くん:先輩、このプラグインって、ライセンスはどうなってるんですか?

くれま先輩:うーん。ライセンスは、X11ライセンス(別名MITライセンスでの公開にします。リンク先にライセンス詳細が書いてありますので、この条件に従う範囲内で、自由にお使いください!それからこの配布用のテンプレートセットは、CSSレイアウトの都合上、連載中でご説明したのと少しだけ異なる部分があります。その説明は、同梱の「readme.txt」に書いておくので、ご一読ください。

ほげ山くん:テンプレートセットプラグインの使い方も、⁠readme.txt」に書いてあるんですよね?

くれま先輩:書いてありますよー!まずはダウンロードして、読んでみてくださいな。

ほげ山くん:それにしても先輩。一年間弱の期間、早かったような長かったような感じですね。

くれま先輩:ほげ山くんは、この期間よく頑張ったね!次の案件からは、ほげ山くんにいろいろお任せするからよろしくねー。

ほげ山くん:(うぅ、プレッシャーが…。)が、頑張りまーす!

くれま先輩:読者の皆さま。全16回にお付き合いくださって、本当にありがとうございました。またどこかでお会いいたしましょう!

おすすめ記事

記事・ニュース一覧