Movable TypeでCSVデータからtable要素を作る方法
Movable Typeを使って、CSVデータからtable要素を簡単に作る方法を紹介します。このエントリーはMTQに寄せられたご質問の回答を情報展開したものです。
1.カスタマイズイメージ
次のようなカンマ区切りのCSVデータをブログ記事の本文に記述します。
h1,h2,h3,h4,h5
a1,a2,a3,a4,a5
b1,b2,b3,b4,b5
c1,c2,c3,c4,c5
このデータから次のtable要素を生成します。
<table>
<thead>
<tr><th>h1</th><th>h2</th><th>h3</th><th>h4</th><th>h5</th></tr>
</thead>
<tbody>
<tr><td>a1</td><td>a2</td><td>a3</td><td>a4</td><td>a5</td></tr>
<tr><td>b1</td><td>b2</td><td>b3</td><td>b4</td><td>b5</td></tr>
<tr><td>c1</td><td>c2</td><td>c3</td><td>c4</td><td>c5</td></tr>
</tbody>
</table>
2.カスタマイズ
CSVデータを分解するにはSplitプラグインを利用します。
プラグインをインストールした後、次のサブテンプレートをインデックステンプレートに記述して、再構築またはプレビューを実行します。サンプルは一番外側のMTEntriesタグにidモディファイアを与えて、ブログ記事IDが「100」の本文だけを処理するようにしています。
<mt:Entries id="100">
<table>
<mt:EntryBody split="\n" setvar="foo">
<mt:loop name="foo">
<mt:GetVar name="__value__" split="," setvar="bar" />
<mt:if name="__first__">
<thead>
<mt:loop name="bar">
<mt:if name="__first__">
<tr>
</mt:if>
<th><mt:GetVar name="__value__" /></th>
<mt:if name="__last__">
</tr>
</mt:if>
</mt:loop>
</thead>
<mt:else>
<mt:if "__counter__" eq="2">
<tbody>
</mt:if>
<mt:loop name="bar">
<mt:if name="__first__">
<tr>
</mt:if>
<td><mt:getVar name="__value__" /></td>
<mt:if name="__last__">
</tr>
</mt:if>
</mt:loop>
</mt:if>
</mt:loop>
</tbody>
</table>
</mt:Entries>
MTEntriesタグでブログ記事を読み込むだけでなく、同じインデックステンプレートにMTSetVarBlockタグでCSVデータを記述し、その変数を読み込むという方法もあります。
3.テンプレートの解説
MTEntryBodyタグで本文(CSVデータ)を取得し、splitモディファイアで改行文字(¥n)をセパレータにして分割した結果を変数fooに保持します。
<mt:EntryBody split="\n" setvar="foo">
変数fooには配列で各行のデータが保存されます。イメージは次のような感じです。
$foo[0] = 'h1,h2,h3,h4,h5'
$foo[1] = 'a1,a2,a3,a4,a5'
$foo[2] = 'b1,b2,b3,b4,b5'
$foo[3] = 'c1,c2,c3,c4,c5'
最初のMTLoopタグでこの変数fooを処理します。1回目の繰り返しでは「'h1,h2,h3,h4,h5'」、2回目の繰り返しでは「'a1,a2,a3,a4,a5'」という順で処理を行っていきます。
<mt:loop name="foo">
…中略…
</mt:loop>
1回目の繰り返し処理の中で、MTGetVarタグを使って変数fooから「__value__」で値「'h1,h2,h3,h4,h5'」を取得し、その値をsplitモディファイアでカンマ文字をセパレータにして、分割した結果を変数barに保持します。
<mt:GetVar name="__value__" split="," setvar="bar" />
変数barにはカンマで区切ったデータが配列で保存されます。イメージは次のような感じです。
$bar[0] = 'h1'
$bar[1] = 'h2'
$bar[2] = 'h3'
$bar[3] = 'h4'
$bar[4] = 'h5'
次のMTIfタグでは、繰り返し処理が初回か初回でないかを判定しています。これは初回の場合はthead要素とth要素を出力し、2回目以降はtbodyとtd要素を出力させるためです。
<mt:if name="__first__">
(thead要素とth要素を出力)
<mt:else>
(tbody要素とtd要素を出力)
</mt:if>
初回の繰り返しの場合は次の処理を行います。MTLoopタグでは先程カンマで分割した配列変数barを処理します。繰り返しの初回でtr要素の開始タグを出力し、MTGetVarタグで値(h1~h5)を順番に出力します。繰り返しの最後でtr要素の終了タグを出力します。
<mt:if name="__first__">
<thead>
<mt:loop name="bar">
<mt:if name="__first__">
<tr>
</mt:if>
<th><mt:GetVar name="__value__" /></th>
<mt:if name="__last__">
</tr>
</mt:if>
</mt:loop>
</thead>
2回目以降の繰り返しの場合は次の処理を行います。MTIfタグで2回目の繰り返しの場合のみtbody要素を出力します。tbodyの終了タグはすべての処理の最後に出力すればよいのでここでは登場しません。
あとは先程と同様、MTLoopタグではカンマで分割した配列変数barを処理します。繰り返しの初回でtr要素の開始タグを出力し、MTGetVarタグで値(a1~a5/b1~b5/c1~c5)を順番に出力します。
<mt:else>
<mt:if "__counter__" eq="2">
<tbody>
</mt:if>
<mt:loop name="bar">
<mt:if name="__first__">
<tr>
</mt:if>
<td><mt:getVar name="__value__" /></td>
<mt:if name="__last__">
</tr>
</mt:if>
</mt:loop>
その他、次のように最初のMTLoopで1行分のデータを別々の変数に保持してから出力するという方法もあります。こちらの方が見通しはよいですが、CSVデータの増減に柔軟に対応できるのは前述のサブテンプレートです。
<mt:Entries id="100">
<mt:EntryBody split="\n" setvar="foo">
<table>
<mt:loop name="foo">
<mt:GetVar name="__value__" split="," setvar="bar" />
<mt:loop name="bar">
<mt:if name="__counter__" eq="1"><mt:GetVar name="__value__" setvar="data1" /></mt:if>
<mt:if name="__counter__" eq="2"><mt:GetVar name="__value__" setvar="data2" /></mt:if>
<mt:if name="__counter__" eq="3"><mt:GetVar name="__value__" setvar="data3" /></mt:if>
<mt:if name="__counter__" eq="4"><mt:GetVar name="__value__" setvar="data4" /></mt:if>
<mt:if name="__counter__" eq="5"><mt:GetVar name="__value__" setvar="data5" /></mt:if>
</mt:loop>
<mt:if name="__first__">
<thead>
<tr>
<th><mt:GetVar name="data1" /></th>
<th><mt:GetVar name="data2" /></th>
<th><mt:GetVar name="data3" /></th>
<th><mt:GetVar name="data4" /></th>
<th><mt:GetVar name="data5" /></th>
</tr>
</thead>
<mt:else>
<mt:if name="__counter__" eq="2">
<tbody>
</mt:if>
<tr>
<td><mt:GetVar name="data2" /></td>
<td><mt:GetVar name="data3" /></td>
<td><mt:GetVar name="data4" /></td>
<td><mt:GetVar name="data5" /></td>
</tr>
</mt:if>
</mt:loop>
</tbody>
</table>
</mt:Entries>
4.区切り文字について
splitモディファイアの区切り文字にはタブ(¥t)を指定することも可能です。任意の文字列を設定すれば、それがそのまま区切り文字となります。
5.注意事項
WindowsにインストールしたMTでは、splitタグによる正常な動作を確認できていません。
Movable Type 5.1ベータ2リリースとMTEntryPrimaryCategoryタグ・MTEntryCategoriesタグのtypeモディファイアについて
Movable Type 5.1ベータ2がリリースされました。
ベータ2のトピックとして、MTEntryPrimaryCategoryタグとMTEntryCategoriesタグにtypeモディファイアが追加されましたので簡単に紹介します。
1.MTEntryPrimaryCategoryタグ
MTEntryPrimaryCategoryは、ブログ記事のメインカテゴリの情報を取得するためのブロックタグです。
これまでメインカテゴリの情報は、MTEntryCategoryファンクションタグでメインカテゴリのカテゴリ名を取得するか、それ以外の情報はMTEntryCategoryタグ・MTEntryCategoriesタグ・条件タグを組み合わせて取得するか、「EntryCategoryIDプラグイン」などのプラグインで取得する必要がありましたが、このタグを使えばメインカテゴリの情報を簡単に取得できます。
例:ブログ記事タイトルにメインカテゴリ名とメインカテゴリのIDを表示
<mt:Entries>
<mt:EntriesHeader>
<ul>
</mt:EntriesHeader>
<mt:EntryPrimaryCategory>
<li><mt:EntryTitle> [<mt:CategoryLabel />(<mt:CategoryID />)]</li>
</mt:EntryPrimaryCategory>
<mt:EntriesFooter>
</ul>
</mt:EntriesFooter>
</mt:Entries>
2.MTEntryCategoriesタグのtypeモディファイア
MTEntryCategoriesタグに「type="primary"」を付与できるようになりました。これにより、MTEntryPrimaryCategoryタグと同様の効果を得ることができます。
例:ブログ記事タイトルにメインカテゴリ名とメインカテゴリのIDを表示
<mt:Entries>
<mt:EntriesHeader>
<ul>
</mt:EntriesHeader>
<mt:EntryCategories type="primary">
<li><mt:EntryTitle> [<mt:CategoryLabel />(<mt:CategoryID />)]</li>
</mt:EntryCategories>
<mt:EntriesFooter>
</ul>
</mt:EntriesFooter>
</mt:Entries>
3.関連記事
MTInclude タグの name モディファイア
MTInclude タグはテンプレートから別のテンプレートやファイルを引き込むためのタグですが、非公式なモディファイアとして、name モディファイアがあります。
<$mt:Include name="xx"$>
name モディファイアは、アプリケーションディレクトリをルートとして、指定されたファイルをインクルードします。モディファイアの値にはパスを指定することも可能です。
例えば、テンプレートに次のように記述して再構築すると、「ようこそ」画面が表示されます。
<$mt:Include name="index.html"$>
このモディファイアは、管理画面用テンプレートファイルの、テンプレートファイルのインクルードで使われています。
Movable Type(MT)の特殊変数の入れ子
小ネタです。Movable Type(MT)の特殊変数は、次のような入れ子でも正常に動作します。
<mt:var name="foo" value="1","2","3","4","5" />
<mt:var name="bar" value="a","b","c","d","e" />
<mt:loop name="foo">
<mt:var name="__counter__" />:<mt:var name="__value__" />
<mt:loop name="bar">
<mt:var name="__counter__" />:<mt:var name="__value__" />
</mt:loop>
</mt:loop>
実行結果
1:1 1:a 2:b 3:c 4:d 5:e 2:2 1:a 2:b 3:c 4:d 5:e 3:3 1:a 2:b 3:c 4:d 5:e 4:4 1:a 2:b 3:c 4:d 5:e 5:5 1:a 2:b 3:c 4:d 5:e
次の場合も同様に可能です。
<mt:Entries>
<mt:getvar name="__counter__" />
<mt:EntryAssets type="image">
<mt:getvar name="__counter__" />
</mt:EntryAssets>
</mt:Entries>
ブロックタグにelseタグを組み込んで判定する
Movable Type の Actions タグには、繰り返し処理対象がない場合に else タグが使えるようになっています。
ふと、思い立って、次のように Entries タグでテストしたところ、正常に動作しました。
<mt:Entries>
<mt:EntryTitle />
<mt:else>
No Data.
</mt:Entries>
次のように、ブロックタグを入れ子にした状態で個別に判定することも可能です。
<mt:Entries>
<mt:EntryTitle />
<mt:Comments>
<mt:CommentBody />
<mt:else>
No Comment.
</mt:Comments>
<mt:else>
No Entry.
</mt:Entries>
以上です。
Movable Type 5 におけるウェブサイトとブログの複数指定方法
Movable Type 5 におけるウェブサイトとブログの複数指定方法を図にまとめました。
1.ウェブサイトでブログの情報を出力する場合
ウェブサイトのテンプレートタグに include_blogs="children" を指定します。例はウェブサイト配下のブログA~Cのウェブページをウェブサイトに表示する例です。箱の右上にマークがついているのが対象となります(以下同様)。

2.ウェブサイトで自ウェブサイトとブログの情報を出力する場合
ウェブサイトのテンプレートタグに include_blogs="children" と include_with_website="1" を加えて指定します。例はウェブサイト配下のブログA~Cとウェブサイトのウェブページをウェブサイトに表示する例です。

3.ブログで同一ウェブサイトのブログの情報を出力する場合
ブログのテンプレートタグに include_blogs="children" を指定します。例は同一ウェブサイトのブログA~CのウェブページをブログBに表示する例です。

4.ブログで同一ウェブサイトのブログとウェブサイトの情報を出力する場合
ブログのテンプレートタグに include_blogs="children" と include_with_website="1" を加えて指定します。例は同一ウェブサイトのブログA~CのウェブページとウェブサイトのウェブページをブログBに表示する例です。

5.ウェブサイトですべてのウェブサイトの情報を出力する場合
ウェブサイトのテンプレートタグに include_websites="all" を指定します。例はウェブサイトYにウェブサイトX~Zのウェブページをウェブサイトに表示する例です。

以上です。ちなみに、「children はウェブサイトのコンテキストでウェブサイト内のブログを対象にし、siblings は、ブログのコンテキストで同一ウェブサイト内のブログを対象にします」とドキュメントに書かれています。
ウェブサイトとブログでグローバルナビゲーションを共有する
Movable Type 5 でウェブサイトとブログでグローバルナビゲーションを共有する方法です。
方法は色々あると思いますが、ここではウェブサイトのテンプレートモジュールをグローバルナビゲーションとして利用する方法を紹介します。
1.グローバルナビゲーションのメニューにウェブサイトのメインページとブログのメインページを含むケース
次のように、ウェブサイトのメインページ(ホーム)と、ウェブサイト配下のブログのメインページ(ブログ名を使用)をウェブサイトとブログで共有する例です。

1.1 ウェブサイトの「ナビゲーション」テンプレートモジュール
ウェブサイトのテンプレートモジュール「ナビゲーション」を新規作成し、次の内容を設定します。
<ul>
<li><a href="<mt:WebsiteURL />">ホーム</a></li>
<mt:Blogs include_blogs="children">
<li><a href="<mt:BlogURL />"><mt:BlogName></a></li>
</mt:Blogs>
</ul>
mt:WebsiteURL タグでウェブサイトのURLを出力します。また、ブログの情報は mt:Blogs ブロックタグを利用して出力します。その際、include_blogs="children" を設定することで、ウェブサイト配下のすべてブログが出力対象となります。
1.2 ウェブサイトで「ナビゲーション」を利用する場合
ウェブサイトの各テンプレートから「ナビゲーション」テンプレートモジュールを呼び出すには、次のmt:Include タグを使用します。
<mt:Include module="ナビゲーション" />
1.3 ウェブサイト配下のブログで「ナビゲーション」を利用する場合
ブログの各テンプレートから「ナビゲーション」テンプレートモジュールを呼び出すには、mt:Include タグを、mt:BlogParentWebsite タグで括ります。また、mt:Include タグに blog_id モディファイアを設定し、ウェブサイトのIDを設定します。
<mt:BlogParentWebsite>
<mt:WebsiteID setvar="website_id">
<mt:Include blog_id="$website_id" module="ナビゲーション" />
</mt:BlogParentWebsite>
mt:Include タグを mt:BlogParentWebsite タグで括ることで、mt:Include タグはブログが属するウェブサイトのコンテキストで動作します。つまり、「ナビゲーション」テンプレートモジュールに設定したテンプレートタグは、ウェブサイトのコンテキストで評価されます。
2.グローバルナビゲーションのメニューにウェブサイトのメインページ・ウェブページとブログのメインページ・ウェブページを含むケース
2.1 ウェブサイトの「ナビゲーション」テンプレートモジュール
ウェブサイトのテンプレートモジュール「ナビゲーション」を新規作成し、次の内容を設定します。
<ul>
<li><a href="<mt:WebsiteURL />">ホーム</a></li>
<mt:Pages>
<li><a href="<mt:PagePermalink />"><mt:PageTitle /></a></li>
</mt:Pages>
<mt:Blogs include_blogs="children">
<li><a href="<mt:BlogURL />"><mt:BlogName /></a></li>
<mt:Pages>
<li><a href="<mt:PagePermalink />"><mt:PageTitle /></a></li>
</mt:Pages>
</mt:Blogs>
</ul>
ウェブサイトのウェブページも、ブログのウェブページも、mt:Pages タグを利用します。ブログのウェブページは mt:Blogs タグを使ってブログのコンテキストで動作させます。
実際にはプライベートタグなどを使ってウェブページのフィルタリングを行なうと思いますが、ここでは説明を割愛します。
2.2 ウェブサイトで「ナビゲーション」を利用する場合
1.2 と同様です。
2.3 ウェブサイト配下のブログで「ナビゲーション」を利用する場合
1.3 と同様です。
regex_replace モディファイアをダイナミックパブリッシングで利用する場合の注意
Movable Type の小ネタです。
regex_replace モディファイアでグループ化と後方参照($1など)を利用する場合、次のように記述します。
<mt:GetVar name="foo" regex_replace="/(.*)/","No.$1" />
上の例では、変数 foo の値が「1」であれば、出力は「No.1」となります。
テンプレートをダイナミックパブリッシングにすると、このままの記述では regex_replace モディファイアは正常に動作せず、出力は「No.」となってしまいます。
期待通りに動作させるためには、後方参照の「$」をエスケープします。
<mt:GetVar name="foo" regex_replace="/(.*)/","No.\$1" />
ちなみに、上記の展開されたダイナミックパブリッシングのソースコードを掲載しておきます。
エスケープなし(NGになるケース)
<?php /* Smarty version 2.6.13, created on 2009-11-21 23:25:15
compiled from mt:1872 */ ?>
<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
smarty_core_load_plugins(array('plugins' => array(array('function', 'mtgetvar', 'mt:1872', 4, false),array('modifier', 'regex_replace', 'mt:1872', 4, false),)), $this); ?>
<?php $this->_tag_stack[] = array("mtgetvar", array (
'name' => 'foo',
'regex_replace' => '/(.*)/',
)); echo ((is_array($_tmp=smarty_function_mtgetvar(array('name' => 'foo'), $this))) ? $this->_run_mod_handler('regex_replace', true, $_tmp, "/(.*)/", "No.".($this->_tpl_vars['1'])) : $this->_plugins['modifier']['regex_replace'][0][0]->regex_replace($_tmp, "/(.*)/", "No.".($this->_tpl_vars['1']))); array_pop($this->_tag_stack); ?>
エスケープあり(OKになるケース)
<?php /* Smarty version 2.6.13, created on 2009-11-21 23:25:53
compiled from mt:1872 */ ?>
<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
smarty_core_load_plugins(array('plugins' => array(array('function', 'mtgetvar', 'mt:1872', 4, false),array('modifier', 'regex_replace', 'mt:1872', 4, false),)), $this); ?>
<?php $this->_tag_stack[] = array("mtgetvar", array (
'name' => 'foo',
'regex_replace' => '/(.*)/',
)); echo ((is_array($_tmp=smarty_function_mtgetvar(array('name' => 'foo'), $this))) ? $this->_run_mod_handler('regex_replace', true, $_tmp, "/(.*)/", "No.\$1") : $this->_plugins['modifier']['regex_replace'][0][0]->regex_replace($_tmp, "/(.*)/", "No.\$1")); array_pop($this->_tag_stack); ?>
ということでお試しください。
複数ブログのブログ記事を時間順に1件ずつ表示する
MultiBlog タグに mode="context" を付与した場合や、Entries タグに blog_ids="children" を付与すれば、複数ブログのタグを時間順に表示することができますが、それぞれのブログの件数を制限することはできません(「blog_ids="children"」はMovable Type 5以降で利用可能)。
例えば、ウェブサイト配下に 3 つのブログがあり、ウェブサイトに各ブログの最新記事1件を時間順に並べる場合などです。
このエントリーでは、3つのブログのブログ記事が次のように(新着順に)並んでいても、

このように、それぞれのブログの最新記事1件を表示するカスタマイズを紹介します。

上記の表示は以下のサブテンプレートで実現できると思いますので、試してみてください。
1.MultiBlog タグの場合
<mt:MultiBlog mode="context">
<mt:Entries lastn="0">
<mt:EntriesHeader>
<ul>
</mt:EntriesHeader>
<mt:BlogName setvar="blog_name" />
<mt:var name="flag" value="0" />
<mt:loop name="list">
<mt:if name="__value__" eq="$blog_name">
<mt:var name="flag" value="1" />
</mt:if>
</mt:loop>
<mt:unless name="flag">
<li><mt:BlogName />:<mt:EntryTitle /></li>
<mt:setVar name="push(list)" value="$blog_name" />
</mt:unless>
<mt:EntriesFooter>
</ul>
</mt:EntriesFooter>
</mt:Entries>
</mt:MultiBlog>
2.MTEntries タグの場合
<mt:Entries blog_ids="children" lastn="0">
<mt:EntriesHeader>
<ul>
</mt:EntriesHeader>
<mt:BlogName setvar="blog_name" />
<mt:var name="flag" value="0" />
<mt:loop name="list">
<mt:if name="__value__" eq="$blog_name">
<mt:var name="flag" value="1" />
</mt:if>
</mt:loop>
<mt:unless name="flag">
<li><mt:BlogName />:<mt:EntryTitle /></li>
<mt:setVar name="push(list)" value="$blog_name" />
</mt:unless>
<mt:EntriesFooter>
</ul>
</mt:EntriesFooter>
<mt:var name="__counter__" />
</mt:Entries>
2010.04.14
「blog_ids="site"」を「blog_ids="children"」に変更しました("site"は、Movable Type 5.0ベータ版で設定可能となっていた値)。また、「blog_ids="children"」の利用可能バージョンを追記しました。
Movable Type のアーカイブページへのリンクを相対パス(ホストからの相対URL)で表示する
Movable Type のアーカイブページ(ブログ記事ページ・月別アーカイブページ・カテゴリアーカイブページ)へのパーマリンクを、相対パス(ホストからの相対URL)で表示するカスタマイズです。以下、ブログ記事ページを例に説明します。
通常、ブログ記事ページのパーマリンクは MTEntryPermalink タグを利用します。
<a href="<mt:EntryPermalink />"><mt:EntryTitle /></a>
このブログ記事ページへのアーカイブパスが
yyyy/mm/entry-basename.html
となっている場合、URLの代わりに相対パスで出力するには、次のようにします。
<a href="<mt:BlogRelativeURL /><$mt:EntryDate format="%Y/%m/"$><mt:EntryBasename separator="-" /><mt:BlogFileExtension />"><mt:EntryTitle /></a>
MTBlogRelativeURL タグは、ホストからの相対URLを出力するタグです。MTEntryDate タグはブログ記事の公開日時を出力し、format モディファイアを適用することで任意のフォーマットで出力できます。
MTEntryBasename タグはファイル名を出力します。separator モディファイアは、ファイルに含まれる「_」を「-」に変換するものです。MTBlogFileExtension タグはアーカイブの拡張子をピリオド付きで出力します。
このようにテンプレートタグを書き換えることで、
http://user-domain/2009/11/07/post.html
という URL を、
/2009/11/07/post.html
で出力することができるようになります。
アーカイブパスによって設定内容は異なりますが、以下のページを参考にすれば、すべてのアーカイブページの相対パスが出力できると思います。
include_with_website モディファイア
Tag:[exclude_websites, include_websites, include_with_website, MovableType, site_ids]
Permalink
Movable Type 5 では include_with_website モディファイアが追加されています。
このモディファイアは、自ウェブサイトのIDを include_blogs="site" というモディファイアの値に加えるものです。次のように設定すれば、ウェブサイト配下のブログ名と自ウェブサイト名を出力します。
<mt:Blogs include_blogs="site" include_with_website="1">
<mt:BlogName />
</mt:Blogs>
include_with_website モディファイアは、include_blogs モディファイアが使える以下のテンプレートタグで使えると思います(他にも使えるかもしれません)。
- MTAssets
- MTAuthors
- MTBlogs
- MTCategories
- MTBlogCategoryCount
- MTComments
- MTBlogCommentCount
- MTEntries
- MTAuthorEntryCount
- MTBlogEntryCount
- MTPings
- MTBlogPingCount
- MTTags
- MTTagSearchLink
- MTTagRank
- MTWebsites
また、以下のモディファイアも追加されています(上記のテンプレートタグで利用可能)。
- site_ids
- include_websites
- exclude_websites
ちなみに、デフォルトテンプレートの「最近のコメント(下)」を見ると、MTIf タグ(厳密には、MTIf タグの tag モディファイアに上記のテンプレートタグを使用した場合)にも include_with_website モディファイアを(つまり include_blogs="site" も)適用できるようです。
<mt:If tag="BlogCommentCount" include_blogs="site" include_with_website="1">
<mt:Comments lastn="10" sort_order="descend" include_blogs="site" include_with_website="1">
<mt:CommentsHeader>
<div class="widget-recent-comments widget">
<h3 class="widget-header">最近のコメント</h3>
<div class="widget-content">
<ul>
</mt:CommentsHeader>
<li><strong><$mt:CommentAuthor$>:</strong> <$mt:CommentBody remove_html="1" words="10"$> <a href="<$mt:CommentLink$>" title="<mt:CommentEntry><$mt:EntryTitle$></mt:CommentEntry>へのコメント">続きを読む</a></li>
<mt:CommentsFooter>
</ul>
</div>
</div>
</mt:CommentsFooter>
</mt:Comments>
</mt:If>
このサブテンプレートは、自ウェブサイトの(ウェブページへの)コメントも含めて、コメントが1件以上投稿(公開)されていれば、MTIf タグブロック内を実行するようになっています。MTIf タグの条件と整合するよう、中にある MTComments タグにも同じモディファイアを適用しています。
ということで、MTIf タグに設定できるモディファイアがさらに増えました。
Movable Type 5.0 情報(テンプレートタグ Tips)
Movable Type 5.0 のテンプレートタグの操作に関する Tips です(ベータ2現在の情報)。以前の記事と若干重複しているかもしれませんがあしからず。
また、情報の一部は「Movable Type 5 BETA ドキュメント」からの引用です。
1.親ウェブサイトのコンテキストに移動する
<mt:BlogParentWebsite>
:
</mt:BlogParentWebsite>
2.親ウェブサイトのモジュールをインクルードする
<mt:BlogParentWebsite><mt:WebsiteID setvar="website_id"></mt:BlogParentWebsite>
<mt:Include module="Test" blog_id="$website_id">
3.ウェブサイトに属するブログのコンテキストに移動する
<mt:Blogs include_blogs="site">
:
</mt:Blogs>
4.コメントのカスタムフィールドをコメント投稿フォームに表示する
<input type="hidden" name="blog_id" value="<MTBlogID>" />
<input type="hidden" name="customfield_beacon" value="1" id="customfield_beacon" />
<mt:CommentCustomFields>
<mt:SetVarBlock name="custom_field_name"><$mt:CustomFieldName$></mt:SetVarBlock>
<mt:SetVarBlock name="field-content"><$mt:CustomFieldHTML$></mt:SetVarBlock>
<mt:SetVarBlock name="custom_field_id">profile_<$mt:CustomFieldName dirify="1"$></mt:SetVarBlock>
<$mt:Include module="フォームフィールド" id="$custom_field_id" class="" label="$custom_field_name"$>
</mt:CommentCustomFields>
5.カスタムフィールドの埋め込みオブジェクトを表示する際の注意点
Movable Typeの標準テンプレートでは、プロフィールやコメントのカスタムフィールド項目をブログで表示する際、安全のためにHTMLタグを除去するグローバルモディファイア sanitize="1" を指定しています。
このため、カスタムフィールドの『埋め込みオブジェクト』で入力される<embed>や<object>タグは、標準の設定では除去されます。
タグを除去せずに、カスタムフィールドの値を表示したい場合は、 sanitize="0" とすることでHTMLをそのまま表示できます。ただし、これによりウェブサイト上で任意のHTMLを表示したり、JavaScriptを実行することが可能になります。ウェブサイトのセキュリティ確保のために、信頼されたユーザーだけがその項目を編集できるよう、コメント認証やユーザーの権限を厳しく設定してください。
MTArchiveList タグブロック内で使えるテンプレートタグ
MTArchiveList タグブロック内で使えるテンプレートタグということで、小ネタを紹介します。
MTArchiveList タグでは、通常、MTArchive系のテンプレートタグが使えますが、type モディファイアでブログ記事やカテゴリを指定した場合、その中に直接 MTEntry系や MTCategory系のファンクションタグが記述できます。
<mt:ArchiveList type="Individual">
<mt:EntryTitle />
</mt:ArchiveList>
<mt:ArchiveList type="Category">
<mt:CategoryLabel />
</mt:ArchiveList>
このサブテンプレートは(テンプレートタグの表記を MT3 のお作法に直しても)MT3.x では正常に動作しなかったので、MT4.x から動作が変わったようです。
以下は既出ですが、次のように書けば MTEntries タグブロック内は処理中のカテゴリに依存します。
<mt:ArchiveList type="Category">
<mt:CategoryLabel />
<mt:Entries>
<mt:EntryTitle />
</mt:Entries>
</mt:ArchiveList>
まとめると、「MTArchiveList タグブロック内はアーカイブテンプレートと同じコンテキストである」ということだと思います(多分)。
Movable Type のブログ記事に表示する画像のサイズを制御する
Movable Type のブログ記事に挿入した画像の表示サイズを制御するカスタマイズです。
ここでは次のようなサンプルを提供します。
- 元画像の幅が 200px 以上であれば、200px のサムネイルを表示
- 元画像の幅が 200px 未満であれば元画像を表示
完成イメージ

1.基本
画像の幅は MTAssetProperty タグに property="image_width" を与えることで取得できます。ここでは取得した値を変数 width に保存し、MTIf タグで判定します。
元画像の表示は、img 要素の src 属性に MTAssetURL タグを与えます。サムネイル画像の場合は、img 要素の src 属性に MTAssetThumbnailURL タグを与えます。サムネイルは事前に作成する必要はなく、このサブテンプレートが実行された時点で自動的に作成します。
なお、サムネイルを生成するには ImageMagick の利用が必要です。
<mt:SetVar name="size" value="200" />
<mt:Entries>
<mt:EntryAssets>
<mt:AssetProperty property="image_width" setvar="width" />
<mt:If name="width" lt="$size">
<p><img src="<mt:AssetURL />" alt="<mt:AssetFileName />" /></p>
<mt:Else>
<p><img src="<mt:AssetThumbnailURL width="$size" />" alt="<mt:AssetFileName />" /></p>
</mt:If>
</mt:EntryAssets>
</mt:Entries>
2.サムネイルの場合は元画像へのリンクを表示する場合
サムネイルに元画像へのリンクを表示する場合は、1項の MTAssetThumbnailURL タグ(と img 要素)の代わりに、MTAssetThumbnailLink タグを利用します(青色部分)。MTAssetThumbnailLink タグを使わずに、MTAssetThumbnailURL タグと MTAssetURL タグを組み合わせても構いません。
<mt:SetVar name="size" value="200" />
<mt:Entries>
<mt:EntryAssets>
<mt:AssetProperty property="image_width" setvar="width" />
<mt:If name="width" lt="$size">
<p><img src="<mt:AssetURL />" alt="<mt:AssetFileName />" /></p>
<mt:Else>
<p><mt:AssetThumbnailLink width="$size" alt="<mt:AssetFileName />" /></p>
</mt:If>
</mt:EntryAssets>
</mt:Entries>
いずれも、赤字の値を変更すれば、表示する画像の幅を変更できます。また、(X)HTML のマークアップは適宜変更してください。
Movable Type の記事中の&を&に変更する方法
Movable Type を使ってアンカーやアフィリエイトリンクなどを付けたブログ記事を書いたときに、リンクに含まれる&を&に自動的に変換する方法を紹介します。
1.基本
(X)HTML では、テキストやURLに含まれる & は & と、実体参照で記述する必要があります。
例1:テキスト
【誤】
ドラッグ&ドロップ
【正】
ドラッグ&ドロップ
例2:URL(Google の「Movable Type」の検索結果のリンク)
【誤】
<a href="http://www.google.co.jp/search?hl=ja&q=movable+type&btnG=Google+%E6%A4%9C%E7%B4%A2&lr=&aq=f&oq=">「Movable Type」の検索結果</a>
【正】
<a href="http://www.google.co.jp/search?hl=ja&q=movable+type&btnG=Google+%E6%A4%9C%E7%B4%A2&lr=&aq=f&oq=">「Movable Type」の検索結果</a>
2.Movable Type のブログ記事内にある & を & に変換する
各テンプレートにある MTEntryBody タグに、次の regex_replace タグ(青色部分)を追加すれば、ブログ記事内にある & をすべて & に自動変換して、ページを出力します。
<$mt:EntryBody regex_replace="/&/g","&"$>
次のようにしておけば、元からある & は変換対象になりません。
<$mt:EntryBody regex_replace="/&(?!amp;)/g","&"$>
ただし、他の実体参照(<など)がブログ記事に含まれている場合もすべて変換対象になってしまうので、プライベートタグを使って記事ごとに振り分けるのも手かもしれません(というか、もっとエレガントな正規表現があるかもしれません)。
<mt:EntryIfTagged tag="@ref">
<$mt:EntryBody regex_replace="/&/g","&"$>
<mt:Else>
<$mt:EntryBody$>
</mt:If>
実体参照したいブログ記事のタグに「@ref」を付与しておきます。
また、自動ではありませんが、下記のプラグインで実体参照化する方法もあります。
3.参考サイト
以下です。ありがとうございました。
Movable Type テンプレートタグの簡略化まとめ
Movable Type のテンプレートタグの簡略化についてまとめました。とりあえず思いついたものを並べておきます。
一部のより詳細な情報は、「blog.aklaswad.com - MTタグの書き方を調べてみました。」にありますので、そちらをご覧ください。
1.name モディファイアの簡略化
テンプレートタグの name モディファイアは、値以外の部分を省略できます。
1.1 ファンクションタグの場合
変更前
<$mt:SetVar name="foo" value="1"$>
変更後
<$mt:SetVar foo value="1"$>
1.2 ブロックタグの場合
変更前
<mt:If name="__first__">
...中略...
</mt:If>
変更後
<mt:If __first__>
...中略...
</mt:If>
2.変数の設定・取得の簡略化
MTSetVar タグ、MTGetVar タグは MTVar タグで置き換えられます。
変更前
<$mt:SetVar name="foo" value="1"$>
<$mt:GetVar name="foo"$>
変更後
<$mt:Var name="foo" value="1"$>
<$mt:Var name="foo"$>
1項の省略記法を追加
<$mt:Var foo value="1"$>
<$mt:Var foo$>
3.配列の設定を簡略化
配列に値を設定するには、[] または index モディファイアを利用しますが、value モディファイアをカンマやコロンで区切れば、まとめて記述できます。
変更前
<$mt:SetVar name="foo[0]" value="0"$>
<$mt:SetVar name="foo[1]" value="1"$>
<$mt:SetVar name="foo[2]" value="2"$>
変更後1
<$mt:SetVar name="foo" value="0","1","2"$>
変更後2
<$mt:SetVar name="foo" value="0":"1":"2"$>
4.複数の変数設定の簡略化
複数の変数を設定するには、MTSetVars タグを使用します。
変更前
<$mt:SetVar name="a" value="1"$>
<$mt:SetVar name="b" value="2"$>
<$mt:SetVar name="c" value="3"$>
<$mt:SetVar name="d" value="4"$>
<$mt:SetVar name="e" value="5"$>
変更後
<mt:SetVars>
a=1
b=2
c=3
d=4
e=5
</mt:SetVars>
参考:1項・2項の簡略化を行なった場合
<$mt:Var a value="1"$>
<$mt:Var b value="2"$>
<$mt:Var c value="3"$>
<$mt:Var d value="4"$>
<$mt:Var e value="5"$>
5.テンプレートタグの非 0 判定を簡略化
MTIfNonZero タグは、「MTIf タグ+tag モディファイア」で置き換えられます。
変更前
<mt:IfNonZero tag="MTBlogEntryCount">
...中略...
</mt:IfNonZero>
変更後
<mt:If tag="BlogEntryCount">
...中略...
</mt:If>
6.テンプレートタグの非空き判定を簡略化
MTIfNonEmpty タグは、「MTIf タグ+tag モディファイア」で置き換えられます。
変更前
<mt:IfNonEmpty tag="MTEntryMore">
...中略...
</mt:IfNonEmpty>
変更後
<mt:If tag="EntryMore">
...中略...
</mt:If>
7.ファンクションタグの内容を変数に設定する場合の簡略化
ファンクションタグの内容を変数に設定するには、MTSetVarBlock タグを利用する代わりに、setvar モディファイアを利用することで簡略化できます。
変更前
<mt:SetVarBlock name="blog_url"><$mt:BlogURL$></mt:SetVarBlock>
変更後
<$mt:BlogURL setvar="blog_url"$>
8.変数の内容を他の変数に設定する場合の簡略化
変数の内容を他の変数に代入するには、MTGetVar タグと MTSetVarBlock タグを併用する代わりに、setvar モディファイアを利用することで簡略化できます。
例:変数 foo の値(1)を、変数 bar に設定
変更前
<$mt:SetVar name="foo" value="1"$>
<mt:SetVarBlock name="bar"><$mt:Getvar name="foo" value="1"$></mt:SetVarBlock>
変更後
<$mt:SetVar name="foo" value="10"$>
<$mt:GetVar name="foo" setvar="bar"$>
1項・2項の省略記法を追加
<$mt:Var foo value="10"$>
<$mt:Var foo setvar="bar"$>
ついでに「$」や「:」も削除
<mtVar foo value="10">
<mtVar foo setvar="bar">
2010.01.31
5項・6項の記載を修正しました。
Movable Type のテンプレートタグでよくある5つの書き間違い
Movable Type でテンプレートタグやテンプレートの実験をするとき、私はいつも手入力で作るため、頻繁に文法誤りをしています。
ここでは、よくありがちな5つの書き間違いを紹介します。
中には、保存や再構築でエラーにならないパターンもあるので、きちんと書いたつもりなのにうまく動かないときなど、参考になれば幸いです。
1.終了タグのスラッシュ抜け
終了タグにスラッシュがありません。終了タグは開始タグをコピー&ペーストして書くので、個人的にはこのパターンが一番多いです。
【誤】
<mt:Entries>
<$mt:EntryTitle$>
<mt:Entries>
【正】
<mt:Entries>
<$mt:EntryTitle$>
</mt:Entries>
これは再構築でエラーになるのですぐに分かります。
2.変数の「$」抜け
変数を name モディファイア以外で使うときは、大抵先頭に「$」をつけないといけないのですが、ときどき忘れます。「$」をつけ忘れると、当然、期待した動作になりません。
【誤】
<$mt:BlogEntryCount setvar="foo"$>
<mt:Entries lastn="foo">
:
</mt:Entries>
【正】
<$mt:BlogEntryCount setvar="foo"$>
<mt:Entries lastn="$foo">
:
</mt:Entries>
配列変数のインデックスやハッシュ変数のキー、関数、特殊変数で「$」の有無がわけがわからなくなります。下は多分合ってます。
<mt:SetVar name="list{$foo}" value="var" />
<mt:SetVar name="push(list)" value="foo" />
<mt:GetVar name="list[$__counter__]" />
変数の「$」抜けは再構築エラーになりません。
3.空要素のブロックタグ
最後がスラッシュで閉じている、いわゆる空要素のブロックタグは、再構築エラーになりません。
【誤】
<mt:SetVarBlock name="foo" value="var" />
【正】
<mt:SetVar name="foo" value="var" />
または
<mt:SetVarBlock name="foo">var</mt:SetVarBlock>
余談ですが、
<mt:Entires />
も正常に再構築できます。
4.ダブルクォーテーション抜け
正常に再構築できて、正常な結果になりません。気がつかないと、「MTのバグ」で済ませてしまいます。
【誤】
<$mt:SetVar name="foo" value="var$>
<$mt:GetVar name="foo"$>
【正】
<$mt:SetVar name="foo" value="var"$>
<$mt:GetVar name="foo"$>
5.接頭辞(mt:)抜け
もはや、MTMLですらありません。
【誤】
<if>
<div>XXXXX</div>
</if>
【正】
<mt:if>
<div>XXXXX</div>
</mt:if>
あと、長い名前のテンプレートタグを使っていると「mt:」を抜きがちです。EntriesHeader や TopLevelCategories とか。意外に、For や Loop もそのまま書いてしまいます。私だけ?
Movable Type で他のブログのテンプレートモジュール・ウィジェットを利用する
Movable Type で複数ブログを作成した場合、他のブログのテンプレートモジュールやウィジェットを利用する方法です。

ここではブログBのテンプレートモジュール「hoge」を、ブログAで利用する方法を例に解説します。
1.ブログAの設定
ブログAの任意のテンプレートで、ブログBのテンプレートモジュール「hoge」を呼び出すために、MTInclude タグを記述し、blog_id モディファイアでブログBのブログIDを指定します。
...前略...
<mt:Include module="hoge" blog_id="ブログBのブログID" />
...後略...
または、MTInclude タグを MTMultiBlog タグで括り、include_blogsモディファイア(または blog_ids モディファイア)でブログBのブログIDを指定します。この場合は表示する内容によって、2項の設定が必要になります。
...前略...
<mt:MultiBlog include_blogs="ブログBのブログID">
<mt:Include module="hoge" />
</mt:MultiBlog>
...後略...
いずれの方法でも、ブログBのテンプレートモジュール「hoge」が、ブログAから呼び出せます。
2.ブログBの設定
1項で MTMultiBlog タグを使った場合、ブログBのテンプレートモジュール「hoge」を、MTMultiBlogLocalBlog タグで括ると、テンプレートモジュール「hoge」に記述されているテンプレートタグに対し、ブログAの情報が反映されます。MTMultiBlogLocalBlog タグで括らない場合は、ブログBの情報が反映されます。
<mt:MultiBlogLocalBlog>
もともとの「hoge」の内容
</mt:MultiBlogLocalBlog>
MTInclude タグに blog_id モディファイアでブログBを指定した場合は、この設定は不要です。
3.MultiBlogLocalBlog タグについて
MTMultiBlogLocalBlog タグの解説は、公式ドキュメントでは、それぞれ次のようになっています。
テンプレートタグリファレンス - MTMultiBlogLocalBlog
MTMultiBlog ブロックタグで定義している中で、一時的にローカルブログ (MTMultiBlog ブロックタグを利用して他のブログの内容を表示させたいブログ) の内容を表示したい場合に利用します。
つまり、この場合、MTInclude タグで呼び出しているブログAの情報を、ブログBのテンプレートモジュールに表示させることができる、というわけです。
ちなみに、テンプレートモジュール「hoge」を、MTMultiBlogLocalBlog タグで括らないと、例えば、テンプレートモジュール「hoge」の中に MTBlogName タグがある場合、再構築したときに MTBlogName タグは、「ブログB」と表示されます。
つまり、他のブログのテンプレートモジュールをインクルードしたときに、インクルード先のテンプレートを、
- 自ブログの情報を出力したい:MTMultiBlogLocalBlog タグで括る
- 他のブログの情報を出力したい:MTMultiBlogLocalBlog タグで括らない
という使い分けもできます。
4.その他
MTMultiBlogLocalBlog タグで括ったテンプレートモジュールやウィジェットは、自ブログではそのまま使えるようです。
次の記述では再構築NGになります。
...前略...
<mt:MultiBlog include_blogs="ブログBのブログID">
<mt:MultiBlogLocalBlog>
<mt:Include module="hoge" />
</mt:MultiBlogLocalBlog>
</mt:MultiBlog>
...後略...
MTInclude タグに identifier モディファイアを指定すれば、インデックステンプレートも呼び出せるかもしれません。
5.参考サイト
参考サイトは下記です。ありがとうございました。
コメント投稿者の表示を valid にする
コメント投稿者の表示には MTCommentAuthorLink タグを使用していますが、コメント投稿者名に「&」などの実体参照が必要な文字が含まれている場合、そのページが valid でなくなります。
グローバルモディファイアとして、escape モディファイアや encode_html モディファイアが用意されていますが、MTCommentAuthorLink タグにこのモディファイアを適用すると、タグで出力されるリンク(のアングルブラケット)まで実体参照されてしまいます。
1.通常のコメント投稿者表示で MTCommentAuthorLink タグを使用
下は通常のコメント投稿者表示で MTCommentAuthorLink タグを使用した場合の、サブテンプレートとその出力(ソースコード)です。
Posted by <mt:commentAuthorLink default_name="Anonymous" show_email="0" />
出力
Posted by <a title="http://www.koikikukan.com/" href="http://www.koikikukan.com/" rel="nofollow">yujiro</a>
2.MTCommentAuthorLink タグに escape モディファイアを適用した失敗例
下は、MTCommentAuthorLink タグに escape モディファイアを適用したときの、サブテンプレートとその出力(ソースコード)です。出力で、本来アングルブラケットになるべき (X)HTML 要素のタグが実体参照されてしまっています。
Posted by <mt:commentAuthorLink default_name="Anonymous" show_email="0" escape="html" />
出力
Posted by <a title="http://www.koikikukan.com/" href="http://www.koikikukan.com/">yujiro</a>
ここでは、他のテンプレートタグを組み合わせて、コメント投稿者を実体参照するカスタマイズを紹介します。
3.配布テンプレートの修正例
ブログ管理画面より「デザイン」→「テンプレート」で「コメント詳細」テンプレートモジュール編集画面を開き、赤色の MTCommentAuthorLink タグの部分を、青色の内容に変更してください。
変更前
<div class="comment"<mt:ifArchiveTypeEnabled archive_type="Individual"> id="c<mt:commentID />"</mt:ifArchiveTypeEnabled>>
<div class="comment-content">
<mt:ifCommentParent>
<p><a href="<mt:commentParent>#comment-<mt:commentID /></mt:commentParent>"><mt:commentParent>No.<mt:commentID />の<mt:commentAuthor /></mt:commentParent></a>さんのコメントへの返信</p>
</mt:ifCommentParent>
<mt:commentBody /></div>
<p class="comment-footer">
Posted by <mt:commentAuthorLink default_name="Anonymous" show_email="0" /> <mt:if tag="CommentAuthorIdentity"><mt:commentAuthorIdentity /></mt:if> at <mt:commentDate /><mt:ifCommentsAccepted> | <mt:commentReplyToLink /></mt:ifCommentsAccepted>
</p>
</div>
変更後
<div class="comment"<mt:ifArchiveTypeEnabled archive_type="Individual"> id="c<mt:commentID />"</mt:ifArchiveTypeEnabled>>
<div class="comment-content">
<mt:ifCommentParent>
<p><a href="<mt:commentParent>#comment-<mt:commentID /></mt:commentParent>"><mt:commentParent>No.<mt:commentID />の<mt:commentAuthor escape="html" /></mt:commentParent></a>さんのコメントへの返信</p>
</mt:ifCommentParent>
<mt:commentBody /></div>
<p class="comment-footer">
Posted by <mt:if tag="commentURL"><a href="<mt:commentURL />"></mt:if><mt:commentAuthor default="Anonymous" escape="html" /><mt:if tag="commentURL"></a></mt:if> <mt:if tag="CommentAuthorIdentity"><mt:commentAuthorIdentity /></mt:if> at <mt:commentDate /><mt:ifCommentsAccepted> | <mt:commentReplyToLink /></mt:ifCommentsAccepted>
</p>
</div>
4.デフォルトテンプレート(抜粋)の修正例
ブログ管理画面より「デザイン」→「テンプレート」で「コメント」テンプレートモジュール編集画面を開き、赤色の MTCommentAuthorLink タグの部分を、青色の内容に変更してください。
変更前
...前略...
<div class="asset-meta">
<span class="byline">
<$mt:CommentAuthorIdentity$>
<mt:IfCommentParent>
<span class="vcard author"><$mt:CommentAuthorLink$></span>から<a href="<mt:CommentParent><$mt:CommentLink$></mt:CommentParent>"><mt:CommentParent><$mt:CommentAuthor$></mt:CommentParent></a>への返信
<mt:Else>
<span class="vcard author"><$mt:CommentAuthorLink$></span>
</mt:IfCommentParent>
| <a href="<$mt:CommentLink$>"><abbr class="published" title="<$mt:CommentDate format_name="iso8601"$>"><$mt:CommentDate$></abbr></a>
<mt:IfCommentsAccepted>
| <$mt:CommentReplyToLink$>
</mt:IfCommentsAccepted>
</span>
</div>
...後略...
変更後
...前略...
<div class="asset-meta">
<span class="byline">
<$mt:CommentAuthorIdentity$>
<mt:IfCommentParent>
<span class="vcard author"><mt:if tag="commentURL"><a href="<mt:commentURL />"></mt:if><mt:commentAuthor default="Anonymous" escape="html" /><mt:if tag="commentURL"></a></mt:if></span>から<a href="<mt:CommentParent><$mt:CommentLink$></mt:CommentParent>"><mt:CommentParent><$mt:CommentAuthor$></mt:CommentParent></a>への返信
<mt:Else>
<span class="vcard author"><mt:if tag="commentURL"><a href="<mt:commentURL />"></mt:if><mt:commentAuthor default="Anonymous" escape="html" /><mt:if tag="commentURL"></a></mt:if></span>
</mt:IfCommentParent>
| <a href="<$mt:CommentLink$>"><abbr class="published" title="<$mt:CommentDate format_name="iso8601"$>"><$mt:CommentDate$></abbr></a>
<mt:IfCommentsAccepted>
| <$mt:CommentReplyToLink$>
</mt:IfCommentsAccepted>
</span>
</div>
...後略...
システムテンプレートとその他のテンプレートを振り分ける
Movable Type 4.1 以降で、システムテンプレート(コメントプレビュー/コメント完了/検索結果)とその他のテンプレートで処理を振り分けるカスタマイズです。
「Google Adsense の広告を検索結果ページだけに表示しない方法」ということで、以前にご質問を頂いたものを情報展開しておきます。
なお、このカスタマイズは、システムテンプレートの「ダイナミックパブリッシングエラー」や「ポップアップ画面」を利用していないことを前提にしていますので予めご了承ください。
1.システムテンプレートとその他のテンプレートで処理を振り分ける
システムテンプレートでは、変数 system_template に 1 が設定されるので、これを利用してシステムテンプレートとその他のテンプレートを振り分けます。
<mt:unless name="system_template">
システムテンプレート以外で表示
<mt:else>
システムテンプレートで表示
</mt:unless>
2.システムテンプレートをさらに振り分ける
冒頭に記した、「Google Adsense の広告を検索結果ページだけに表示しない方法」です。
システムテンプレートのコメントプレビュー/コメント完了ページと検索結果を振り分ける場合は、次のように変数 body_class を利用します。コメント関連のシステムテンプレートは変数 body_class に mt-comment -xxxxx という値が設定されます。
<mt:unless name="system_template">
システムではないページで表示
<mt:elseIf name="body_class" like="mt-comment">
コメントプレビュー・コメント完了ページで表示
<mt:else>
検索結果で表示
</mt:unless>
Adsensen のコードを最後の MTElse タグブロックに含めなければ、検索結果ページだけ非表示になります。
上記以外にも色々な振り分け方法があると思いますので、試してみてください。
また検索結果テンプレートだけに何らかのユーザ変数を設定しておけば、「ダイナミックパブリッシングエラー」や「ポップアップ画面」を含め、検索結果テンプレートだけを振り分けることが可能です。検索結果テンプレートを判定するには、変数 search_results で判定できます。
「Movable Type 4.2 パーフェクトガイド」をお持ちの方は、213ページ~214ページに関連する変数を掲載しています。
![]() | Movable Type 4.2 パーフェクトガイド 荒木 勇次郎 毎日コミュニケーションズ 2008-07-31 売り上げランキング : 9985 Amazonで詳しく見る by G-Tools |
2008.10.10
検索結果テンプレートの判定に関する記述を変更しました。
MTDate タグ・モディファイア詳説
MTDate タグの、Movable Type 4.2 におけるローカルモディファイア詳細です。MTDate タグは再構築の日付を表示するタグです。次の Date 系タグのローカルモディファイアはすべて共通です。
- MTArchiveDate
- MTArchiveDateEnd
- MTAssetDateAdded
- MTCalendarDate
- MTCommentDate
- MTDate
- MTEntryCreatedDate
- MTEntryDate
- MTEntryModifiedDate
- MTPageDate
- MTPageModifiedDate
- MTPingDate
- MTScoreDate
1.モディファイアなし
モディファイアを指定しない場合は次のように出力されます。出力フォーマットは、ブログ管理画面の「設定」→「ブログ記事」→「日付の言語」の設定に依存します。
<$MTDate$>
2008年7月 2日 01:23
2.utc モディファイア
utc モディファイアは、協定世界時(Coordinated Universal Time)を示します。タイムゾーンの設定で「UTC+9」とか設定するときの UTC です。1を設定するとタイムゾーンを無視して UTC で出力します。
分かりにくいですが、1項のサンプルから -9 時間で表示されます。
テンプレートタグの記述
<$MTDate utc="1"$>
出力
2008年7月 1日 16:23
3.format_name モディファイア
format_name モディファイアは出力フォーマットを決定します。rfc822 を設定すると、RFC822 に準拠したフォーマットで出力します。
テンプレートタグの記述
<$MTDate format_name="rfc822"$>
出力
Wed, 02 Jul 2008 01:23:56 +0900
iso8601 を設定すると、ISO8601 に準拠したフォーマットで出力します。
テンプレートタグの記述
<$MTDate format_name="iso8601"$>
出力
2008-07-02T01:23:56+09:00
utc モディファイアと組み合わせると、タイムゾーン指定子が UTC を表す「Z」になります。
テンプレートタグの記述
<$MTDate utc="1" format_name="rfc822"$>
出力
Tue, 01 Jul 2008 16:23:56 Z
テンプレートタグの記述
<$MTDate utc="1" format_name="iso8601"$>
出力
2008-07-01T16:23:56Z
3.relative モディファイア
Movable Type 4.2 で追加されたモディファイアです。名前の通り、相対時刻を出力します。JavaScript を利用するので、リアルタイムな相対時刻を表示します。
js を指定すると、JavaScript を利用して相対時刻を表示します。js 以外(1とか)であれば、再構築時間の相対時刻を表示します。
JavaScript を利用する場合は、mt.js のインクルードが必要です。
テンプレートタグの記述
<script src="<$MTBlogURL$>mt.js"></script>
...中略...
<$MTDate relative="js"$>
出力
5 分前
ソースコード
<script type="text/javascript">
/* <![CDATA[ */
document.write(mtRelativeDate(new Date(2008,7,02,01,23,56), '2008年7月 2日 01:23'));
/* ]]> */
</script><noscript>2008年7月 2日 01:32</noscript>
テンプレートタグの記述
<$MTDate relative="1"$>
出力
5 分前
4.mail モディファイア
1を設定すると出力内容をメールの文字コードにエンコードします。グローバルテンプレートのメール通知系で利用します。
テンプレートタグの記述
<$MTDate mail="1"$>
出力
2008年7月 2日 01:23
1項と同じに見えますが、1項の「月」や「日」は、次のように数字実体参照されています。
ソースコード
2008年7月 2日 01:23
5.language モディファイア
出力する言語を指定します。フランス語を指定すると次のようになります。
テンプレートタグの記述
<$MTDate language="fr"$>
出力
2 juillet 2008 1h23
Movable Type のブロックタグにファンクションタグで使うモディファイアを指定する
「ブロックタグに、ファンクションタグで使うようなグローバルモディファイアを指定するとどうなるのか」という実験です。オチあはりません。
以下、MTEntries タグに encode_html="1" を設定しない場合と、設定した場合の「最近のエントリー」を出力してみます。
1.encode_htmlなしの場合
サブテンプレート
<mt:entries>
<mt:entriesHeader><ul></mt:entriesHeader>
<li><a href="<mt:entryPermalink />"><mt:entryTitle /></a></li>
<mt:entriesFooter><ul></mt:entriesFooter>
</mt:entries>
出力結果
<ul>
<li><a href="http://user-dmain/2008/04/5.html">ブログ記事5</a></li>
<li><a href="http://user-dmain/2008/04/4.html">ブログ記事4</a></li>
<li><a href="http://user-dmain/2008/04/3.html">ブログ記事3</a></li>
<li><a href="http://user-dmain/2008/03/2.html">ブログ記事2</a></li>
<li><a href="http://user-dmain/2008/02/1.html">ブログ記事1</a></li>
<ul>
2.encode_htmlありの場合
サブテンプレート
<mt:entries encode_html="1">
<mt:entriesHeader><ul></mt:entriesHeader>
<li><a href="<mt:entryPermalink />"><mt:entryTitle /></a></li>
<mt:entriesFooter><ul></mt:entriesFooter>
</mt:entries>
出力結果
<ul>
<li><a href="http://user-dmain/2008/04/5.html">ブログ記事5</a></li>
<li><a href="http://user-dmain/2008/04/4.html">ブログ記事4</a></li>
<li><a href="http://user-dmain/2008/04/3.html">ブログ記事3</a></li>
<li><a href="http://user-dmain/2008/03/2.html">ブログ記事2</a></li>
<li><a href="http://user-dmain/2008/02/1.html">ブログ記事1</a></li>
<ul>
ということで、このサンプルでは見事にブロック内部全体がエンコードされました。
なお、これを使えばブラウザの[ページ]-[ソースの表示]を使わずに、ブラウザで直接ソースコードを見ることができます。
「グローバルモディファイア」という名前は伊達ではありませんでした。
MTIf タグの test モディファイアで Perl の式を利用する
Movable Type 4.1 の MTIf タグに test モディファイアというものが追加されていましたので、本エントリーにて紹介致します。
1.用途
test モディフィアの用途は、Perlの式を実行し、結果を利用して条件分岐を行うことです。Movable Type の MTSetVar タグ等で作成した変数の値を判定することもできます。
2.サンプル
MTSetVarタグで作った変数 foo の値が1文字以上の英文字であることを判定し、マッチすれば MTIf タグのブロックを実行します。
<$mt:setvar name="foo" value="OK"$>
<mt:if test="$foo =~ m/\w+/;">
<$mt:getvar name="foo"$>
</mt:if>
MTSetVarタグで作った変数 bar の値が5以上であることを判定し、マッチすれば MTIf タグのブロックを実行します。
<$mt:setvar name="bar" value="10"$>
<mt:if test="$bar > 5">
<$mt:getvar name="bar"$>
</mt:if>
このタグを利用すれば、かなりすごいことができそうに思われますが、とりあえず簡単なサンプルでお許しください。
MTIf タグの tag モディファイアでテンプレートタグの値を直接参照する
Movalbe Type 4.1 で、MTIf タグに tag モディファイアがいつのまにか追加されていました。本エントリーで紹介します。
使い方は簡単で、tag モディファイアにテンプレートタグ(ファンクションタグ)を指定すれば、変数のように値を参照できます。
1.基本
<mt:if tag="[ファンクションタグ名]">
指定したテンプレートタグに値がある場合は true、ない場合は false を返却します。
2.サンプル
ファンクションタグの値を MTSetVarBlock タグで一旦変数に取得して判定するケース
<mt:setvarblock name="count"><$MTEntriesCount$></mt:setvarblock>
<mt:if name="count">
:
</mt:if>
は、
<mt:if tag="MTEntriesCount">
:
</mt:if>
または
<mt:if tag="EntriesCount">
:
</mt:if>
と書くことができます。
3.応用
以前紹介した、「ブログ記事に同一カテゴリーのブログ記事リストを表示(MT4版)」を少し書き換えてみます。
変更前
<MTIf name="entry_template">
<MTSetVarBlock name="entryid"><$MTEntryID$></MTSetVarBlock>
<MTSetVarBlock name="entrycategory"><$MTEntryCategory$></MTSetVarBlock>
<dt class="sidetitle">
Entries of this Category
</dt>
<dd class="side">
<ul>
<MTEntries category="$entrycategory">
<MTSetVarBlock name="currententryid"><$MTEntryID$></MTSetVarBlock>
<MTIf name="currententryid" ne="$entryid">
<li><a href="<$MTEntryPermalink$>"><$MTEntryTitle$></a></li>
</MTIf>
</MTEntries>
</ul>
</dd>
</MTIf>
変更後
<MTIf name="entry_template">
<MTSetVarBlock name="entryid"><$MTEntryID$></MTSetVarBlock>
<MTSetVarBlock name="entrycategory"><$MTEntryCategory$></MTSetVarBlock>
<dt class="sidetitle">
Entries of this Category
</dt>
<dd class="side">
<ul>
<MTEntries category="$entrycategory">
<MTIf tag="EntryID" ne="$entryid">
<li><a href="<$MTEntryPermalink$>"><$MTEntryTitle$></a></li>
</MTIf>
</MTEntries>
</ul>
</dd>
</MTIf>
少し見通しが良くなりました。
MTLoop タグによる配列変数・ハッシュ変数の制御
Movable Type 4.0 では管理画面用だった MTLoop タグが、Movable Type 4.1 ではテンプレート上で利用できるようになりました。これにより配列やハッシュの取得が MTLoop タグで実現できるようになります。
以下、MTLoop での配列とハッシュの利用方法を紹介します。
1.配列を取得する
MTFor タグで設定し、MTLoop タグで取得するサンプルを示します。
<mt:for var="i" from="0" to="9">
<mt:setvar name="foo[$i]" value="$i">
</mt:for>
<mt:loop name="foo">
<mt:getvar name="__value__">
</mt:loop>
MTLoop タグの使い方は、name モディファイアに配列変数名を設定するだけで、ここでは foo を設定しています。
配列変数 foo の値は予約変数 __value__ に自動的に設定されるので、あとは MTGetVar タグの name モディファイアに指定するだけです。
MTLoop タグの部分を MTFor タグで書くと
<mt:for var="i" from="0" to="9">
<mt:setvar name="foo[$i]" value="$i">
</mt:for>
となるので、MTLoop タグの方が簡単に書けることがお分かりになると思います。
なお、MTLoopタグでは配列のインデックスが0から処理が開始されるため、設定側の MTFor タグの from モディファイアは「0」、to モディファイアは「9」を設定しています。
2.ハッシュを取得する
4.1 ベータ 2 から新しく追加された sethashvar タグ(ハッシュをまとめて定義できるタグ)を用いて、ハッシュを作成し、MTLoop タグで取得するサンプルを示します。
<mt:sethashvar name="week">
<mt:setvar name="mon" value="Monday">
<mt:setvar name="tue" value="Tuesday">
<mt:setvar name="wed" value="Wednesday">
<mt:setvar name="thu" value="Thursday">
<mt:setvar name="fri" value="Friday">
<mt:setvar name="sat" value="Saturday">
<mt:setvar name="sun" value="Sunday">
</mt:sethashvar>
<mt:loop name="week">
<$mt:getvar name="__key__"$> <$mt:getvar name="__value__"$>
</mt:loop>
テンプレートを再構築すると、下のように出力されます。
sun Sunday
fri Friday
tue Tuesday
sat Saturday
mon Monday
wed Wednesday
thu Thursday
配列変数の時と同様、name モディファイアに配列変数名を設定します。ここでは week を設定します。
配列変数 week のキーの値は予約変数 __key__ に、キーに対応する値は予約変数 __value__ に自動的に設定されるので、それぞれ MTGetVar タグの name モディファイアに指定します。
ハッシュは配列のような順序性がありませんが、sort_by モディファイアを設定することで、一定の規則にしたがって出力されます。
キーの文字列順で並べ替え
<mt:loop name="[変数名]" sort_by="key">
キーの文字列順(逆順)で並べ替え
<mt:loop name="[変数名]" sort_by="key reverse">
キーに対応する値の文字列順で並べ替え
<mt:loop name="[変数名]" sort_by="value">
キーに対応する値の文字列順(逆順)で並べ替え
<mt:loop name="[変数名]" sort_by="value reverse">
キーに対応する値の文字を数値として比較・並べ替え
<mt:loop name="[変数名]" sort_by="value numeric">
キーに対応する値の文字を数値として比較・並べ替え(逆順)
<mt:loop name="[変数名]" sort_by="value numeric reverse">
Movable Type 4.1 / MTOS における変数での算術演算子の利用方法
昨日エントリーした「Movable Type 4.1 / MTOS における配列とハッシュの利用方法」に加え、MT4.1/MTOS では算術演算子の利用が可能になりました。
詳細は後述しますが、可能な演算は、
- 加算(+)
- 減算(-)
- 乗算(*)
- 除算(/)
- 剰余(%)
- インクリメント(++)
- デクリメント(--)
で、変数の演算結果を同一変数に保持したり、MTIf タグ等での判定や、判定と同時に演算すること等が可能です。
ということで、こちらについても以下に利用方法をまとめてみました。なお、利用可能と思われるテンプレートタグは下記の通りです。
- MTIf
- MTUnless
- MTGetVar
- MTSetVar
- MTSetVarBlock
- MTSetVarTemplate
1.加算
フォーマット
op モディファイアに"+"または"add"を設定します。定義済みの変数に加算する場合は value モディファイアを記述し、加算したい値を設定します。
値を加算のみする場合
<$mt:setvar name="[変数名]" op="+" value="[加算値]"$>
または
<$mt:setvar name="[変数名]" op="add" value="[加算値]"$>
加算後に表示する場合
<$mt:getvar name="[変数名]" op="+" value="[加算値]"$>
または
<$mt:getvar name="[変数名]" op="add" value="[加算値]"$>
加算した結果を判定する場合(例は等しい場合を判定)
<mt:if name="[変数名]" op="+" value="[加算値]" eq="[比較値]">
または
<mt:if name="[変数名]" op="add" value="[加算値]" eq="[比較値]">
サンプル
変数hogeに+1した結果を設定
<$mt:setvar name="hoge" value="1"$>
<$mt:setvar name="hoge" op="+" value="1"$>
変数hogeに+1した結果を表示
<$mt:setvar name="hoge" value="1"$>
<$mt:getvar name="hoge" op="+" value="1"$>
変数hogeに+1した結果が2であるかを判定
<$mt:setvar name="hoge" value="1"$>
<mt:if name="hoge" op="+" value="1" eq="2">
OK
<mt:else>
NG
</mt:if>
2.減算
フォーマット
op モディファイアに"-"または"sub"を設定します。定義済みの変数に減算する場合は value モディファイアを記述し、減算したい値を設定します。
値を減算のみする場合
<$mt:setvar name="[変数名]" op="-" value="[減算値]"$>
または
<$mt:setvar name="[変数名]" op="sub" value="[減算値]"$>
減算後に表示する場合
<$mt:getvar name="[変数名]" op="-" value="[減算値]"$>
または
<$mt:getvar name="[変数名]" op="sub" value="[減算値]"$>
減算した結果を判定する場合(例は等しい場合を判定)
<mt:if name="[変数名]" op="-" value="[減算値]" eq="[比較値]">
または
<mt:if name="[変数名]" op="sub" value="[減算値]" eq="[比較値]">
サンプル
変数hogeから-1した結果を設定
<$mt:setvar name="hoge" value="10"$>
<$mt:setvar name="hoge" op="-" value="1"$>
変数hogeから-1した結果を表示
<$mt:setvar name="hoge" value="10"$>
<$mt:getvar name="hoge" op="-" value="1"$>
変数hogeに-1した結果が2であるかを判定
<$mt:setvar name="hoge" value="3"$>
<mt:if name="hoge" op="-" value="1" eq="2">
OK
<mt:else>
NG
</mt:if>
3.乗算
フォーマット
op モディファイアに"*"または"mul"を設定します。定義済みの変数に乗算する場合は value モディファイアを記述し、乗算したい値を設定します。
値を乗算のみする場合
<$mt:setvar name="[変数名]" op="*" value="[乗数値]"$>
または
<$mt:setvar name="[変数名]" op="mul" value="[乗数値]"$>
乗算後に表示する場合
<$mt:getvar name="[変数名]" op="*" value="[乗数値]"$>
または
<$mt:getvar name="[変数名]" op="mul" value="[乗数値]"$>
乗算した結果を判定する場合(例は等しい場合を判定)
<mt:if name="[変数名]" op="*" value="[乗数値]" eq="[比較値]">
または
<mt:if name="[変数名]" op="mul" value="[乗数値]" eq="[比較値]">
サンプル
変数hogeに2倍した結果を変数に設定
<$mt:setvar name="hoge" value="1"$>
<$mt:setvar name="hoge" op="*" value="2"$>
変数hogeを2倍した結果を表示
<$mt:setvar name="hoge" value="1"$>
<$mt:getvar name="hoge" op="*" value="2"$>
変数hogeに2倍した結果が6であるかを判定
<$mt:setvar name="hoge" value="3"$>
<mt:if name="hoge" op="*" value="2" eq="6">
OK
<mt:else>
NG
</mt:if>
4.除算
フォーマット
op モディファイアに"/"または"div"を設定します。定義済みの変数に除算する場合は value モディファイアを記述し、除算したい値を設定します。
値を除算のみする場合
<$mt:setvar name="[変数名]" op="/" value="[除数値]"$>
または
<$mt:setvar name="[変数名]" op="div" value="[除数値]"$>
除算後に表示する場合
<$mt:getvar name="[変数名]" op="/" value="[除数値]"$>
または
<$mt:getvar name="[変数名]" op="div" value="[除数値]"$>
除算した結果を判定する場合(例は等しい場合を判定)
<mt:if name="[変数名]" op="/" value="[除数値]" eq="[比較値]">
または
<mt:if name="[変数名]" op="div" value="[除数値]" eq="[比較値]">
サンプル
変数hogeを2で割った結果を変数に設定
<$mt:setvar name="hoge" value="10"$>
<$mt:setvar name="hoge" op="/" value="2"$>
変数hogeを2で割った結果を表示
<$mt:setvar name="hoge" value="10"$>
<$mt:getvar name="hoge" op="/" value="2"$>
変数hogeを2で割った結果が3であるかを判定
<$mt:setvar name="hoge" value="6"$>
<mt:if name="hoge" op="/" value="2" eq="3">
OK
<mt:else>
NG
</mt:if>
5.剰余
フォーマット
op モディファイアに"%"または"mod"を設定します。定義済みの変数に剰余する場合は value モディファイアを記述し、剰余したい値を設定します。
値を剰余のみする場合
<$mt:setvar name="[変数名]" op="%" value="[剰余値]"$>
または
<$mt:setvar name="[変数名]" op="mod" value="[剰余値]"$>
剰余後に表示する場合
<$mt:getvar name="[変数名]" op="%" value="[剰余値]"$>
または
<$mt:getvar name="[変数名]" op="mod" value="[剰余値]"$>
剰余した結果を判定する場合(例は等しい場合を判定)
<mt:if name="[変数名]" op="%" value="[剰余値]" eq="[比較値]">
または
<mt:if name="[変数名]" op="mod" value="[剰余値]" eq="[比較値]">
サンプル
変数hogeを3で割った余りを変数に設定
<$mt:setvar name="hoge" value="5"$>
<$mt:setvar name="hoge" op="%" value="3"$>
変数hogeを3で割った余りを表示
<$mt:setvar name="hoge" value="5"$>
<$mt:getvar name="hoge" op="%" value="3"$>
変数hogeを3で割った余りが1であるかを判定
<$mt:setvar name="hoge" value="7"$>
<mt:if name="hoge" op="%" value="3" eq="1">
OK
<mt:else>
NG
</mt:if>
6.インクリメント
「インクリメント」とは、値に1を加算することを指します。
フォーマット
op モディファイアに"++"または"inc"を設定します。なお、定義済みの変数にしかインクリメントすることはできません。
値をインクリメントのみする場合
<$mt:setvar name="[変数名]" op="++"$>
または
<$mt:setvar name="[変数名]" op="inc"$>
インクリメント後に表示する場合
<$mt:getvar name="[変数名]" op="++"$>
または
<$mt:getvar name="[変数名]" op="inc"$>
インクリメントした結果を判定する場合(例は等しい場合を判定)
<mt:if name="[変数名]" op="++" eq="[比較値]">
または
<mt:if name="[変数名]" op="inc" eq="[比較値]">
サンプル
変数hogeをインクリメント
<$mt:setvar name="hoge" value="1"$>
<$mt:setvar name="hoge" op="++"$>
変数hogeをインクリメントした結果を表示
<$mt:setvar name="hoge" value="1"$>
<$mt:getvar name="hoge" op="++"$>
変数hogeをインクリメントした結果が2であるかを判定
<$mt:setvar name="hoge" value="1"$>
<mt:if name="hoge" op="++" eq="2">
OK
<mt:else>
NG
</mt:if>
7.デクリメント
「デクリメント」とは、値から1を減算することを指します。
フォーマット
op モディファイアに"--"または"dec"を設定します。なお、定義済みの変数にしかデクリメントすることはできません。
値をデクリメントのみする場合
<$mt:setvar name="[変数名]" op="--"$>
または
<$mt:setvar name="[変数名]" op="dec"$>
デクリメント後に表示する場合
<$mt:getvar name="[変数名]" op="--"$>
または
<$mt:getvar name="[変数名]" op="dec"$>
デクリメントした結果を判定する場合(例は等しい場合を判定)
<mt:if name="[変数名]" op="--" eq="[比較値]">
または
<mt:if name="[変数名]" op="dec" eq="[比較値]">
サンプル
変数hogeをデクリメント
<$mt:setvar name="hoge" value="10"$>
<$mt:setvar name="hoge" op="--"$>
変数hogeをデクリメントした結果を表示
<$mt:setvar name="hoge" value="10"$>
<$mt:getvar name="hoge" op="--"$>
変数hogeをデクリメントした結果が1であるかを判定
<$mt:setvar name="hoge" value="2"$>
<mt:if name="hoge" op="--" eq="1">
OK
<mt:else>
NG
</mt:if>
8.注意事項
文字列や数字を含んだ文字列に演算を行っても何も行われません。また、ベータ1a版の動作確認では、他のリスト系テンプレートタグとの組み合わせでは初期値が1でないと機能しないようです(下記)。
NG(初期値0)
<$mt:setvar name="hoge" value="0"$>
<MTEntries>
<$mt:setvar name="hoge" op="++"$>
</MTEntries>
<$mt:getvar name="hoge">
OK(初期値1)
<$mt:setvar name="hoge" value="1"$>
<MTEntries>
<$mt:setvar name="hoge" op="++"$>
</MTEntries>
<$mt:getvar name="hoge">
Movable Type 4.1 / MTOS における配列とハッシュの利用方法
公にアナウンスされていないようですが、MT4.1/MTOS では変数で配列とハッシュの操作が可能になり、変数処理がよりプログラマブルになりました。
ということで、以下に利用方法をまとめてみました。
1.配列
配列とは、同じ型のデータを連続的に並べた集合を指します。同一の変数名にインデックス(添え字)を付与することでデータを識別することができます。
例えば、week という変数に、Monday から Sunday までの文字列を設定するには、
week[0] = 'Monday'
week[1] = 'Tuesday'
week[2] = 'Wednesday'
week[3] = 'Thursday'
week[4] = 'Friday'
week[5] = 'Saturday'
week[6] = 'Sunday'
という感じになります。
MTSetVar による配列の設定
MTSetVar タグで配列を設定する方法は2通りあります。name モディファイアの変数名に直接インデックスを記述して、value モディファイアに値を設定するか(下)、
<MTSetVar name="week[0]" value="Mon">
<MTSetVar name="week[1]" value="Tue">
<MTSetVar name="week[2]" value="Wed">
:
index モディファイアを記述し、そこにインデックスを設定します(下)。value モディファイアは同じです。
<MTSetVar name="week" index="0" value="Mon">
<MTSetVar name="week" index="1" value="Tue">
<MTSetVar name="week" index="2" value="Wed">
:
MTSetVarBlock による配列の設定
MTSetVar タグに配列を設定する方法も、MTSetVar タグと大体同じで、name モディファイアの変数名に直接インデックスを記述し、value モディファイアの代わりにブロック内に値を記述します。
<MTSetVarBlock name="week[0]">
:
</MTSetVarBlock>
<MTSetVarBlock name="week[1]">
:
</MTSetVarBlock>
<MTSetVarBlock name="week[2]">
:
</MTSetVarBlock>
:
または、index モディファイアを記述し、そこにインデックスを設定します(下)。
<MTSetVarBlock name="week" index="0">
:
</MTSetVarBlock>
<MTSetVarBlock name="week" index="1">
:
</MTSetVarBlock>
<MTSetVarBlock name="week" index="2">
:
</MTSetVarBlock>
:
MTFor による配列の設定
単純な数値であれば MTFor で設定することも可能です。
下記に、0~6の値を配列に設定するサンプルを示します。MTFor タグの var モディファイアの変数名に配列のインデックスが設定されます。from モディファイアに最小値、to モディファイアに最大値を設定し、MTFor ブロック内に MTSetVar を記述して、配列のインデックスとなる $x を記述します。
<mt:for var="x" from="0" to="6">
<MTSetVar name="week[$x]" value="$x">
</mt:for>
MTSetVar の name モディファイアと別に、index モディファイアに $x を記述してもOKです。
<mt:for var="x" from="0" to="6">
<MTSetVar name="week" index="$x" value="$x">
</mt:for>
繰り返し処理による配列の設定
下記に、ブログ記事タイトルを配列の値に設定するサンプルを示します。
<MTEntries>
<MTSetVarBlock name="counter"><$MTGetVar name="__counter__"$></MTSetVarBlock>
<MTSetVarBlock name="entrytitle[$counter]"><$MTEntryTitle$></MTSetVarBlock>
</MTEntries>
2行目の counter は、インデックス値となる __counter__ の値を3行目に直接設定できないため、MTSetVarBlock でワンクッションおいてます。3行目でブログ記事タイトルを配列に設定しています。
配列の取得
配列の内容を取得・表示するには、MTGetVar(または MTVar)で name モディファイアにインデックスつきの変数名を指定します。
<MTGetVar name="week[0]">
<MTGetVar name="week[1]">
<MTGetVar name="week[2]">
:
実行結果
Mon
Tue
Wed
:
または、MTGetVar(または MTVar)で name モディファイアと別に index モディファイアにインデックス値を指定します。実行結果は同じです。
<MTGetVar name="week" index="0">
<MTGetVar name="week" index="1">
<MTGetVar name="week" index="2">
:
さらに MTFor タグを使うことで、繰り返しによる取得も可能です。
MTFor タグの var モディファイアの値が配列のインデックス値となります。from モディファイアに最小値、to モディファイアに最大値を設定し、MTFor ブロック内に MTGetVar を記述して配列の値を取得します。MTGetVar の name モディファイアにインデックス値となる $x を記述します。
<mt:for var="x" from="0" to="6">
<MTGetVar name="week[$x]">
</mt:for>
MTGetVar の name モディファイアと別に、index モディファイアに $x を記述してもOKです。
<mt:for var="x" from="0" to="6">
<MTGetVar name="week" index="$x">
</mt:for>
配列の要素数を求める
count 関数により、配列を設定した後の要素数を求めます。
フォーマットは、
<MTGetVar name="count(week)">
で、name モディファイアに要素数を求める関数名(count)と、関数のパラメータ(括弧内)に処理の対象となる配列の変数名を記述します。
実行結果
7
または、
<MTGetVar name="week" function="count">
と書いても同じです。function モディファイアに関数名 count を記述します。
配列の最後からデータを取得する
pop 関数により、配列の最後からデータを取得し、配列から取得データを削除します。
フォーマットは、
<MTGetVar name="pop(week)">
で、name モディファイアに関数名(pop)と、関数のパラメータ(括弧内)に処理の対象となる配列の変数名を記述します。
実行結果(結果には表示されませんが配列のインデックスが-1されています)
Sun
または、
<MTGetVar name="week" function="pop">
と書いても同じです。function モディファイアに関数名 pop を記述します。
配列の先頭からデータを取得する
shift 関数により、配列の先頭からデータを取得し、配列から取得データを削除します。
<MTGetVar name="shift(week)">
で、name モディファイアに関数名(shift)と、関数のパラメータ(括弧内)に処理の対象となる配列の変数名を記述します。
実行結果(結果には表示されませんが配列のインデックスが-1されています)
Mon
または、
<MTGetVar name="week" function="shift">
と書iいても同じです。
2.ハッシュ
ハッシュは、配列のインデックスが文字列となったものです。この文字列となったインデックスを「キー」と呼びます。先の1週間の例では、
week[mon] = 'Monday'
week[tue] = 'Tuesday'
week[wed] = 'Wednesday'
week[thu] = 'Thursday'
week[fri] = 'Friday'
week[sat] = 'Saturday'
week[sun] = 'Sunday'
となります。
MTSetVar にハッシュの設定
MTSetVar タグにハッシュを設定する方法は2通りあります。name モディファイアの変数名に直接キー({}で囲まれた部分)を記述するか(下)、
<MTSetVar name="week{mon}" value="Monday">
<MTSetVar name="week{tue}" value="Tuesday">
:
key モディファイアを記述し、そこにキーを設定します(下)。
<MTSetVar name="week" key="mon" value="Monday">
<MTSetVar name="week" key="tue" value="Tuesday">
:
MTSetVarBlock にハッシュの設定
MTSetVarBlock タグにハッシュを設定する方法も、MTSetVar タグと大体同じで、name モディファイアの変数名に直接キーを記述し、value 属性の代わりにブロック内に値を記述します。
<MTSetVarBlock name="week{mon}">
:
</MTSetVarBlock>
<MTSetVarBlock name="week{tue}">
:
</MTSetVarBlock>
:
または、key モディファイアを記述し、そこにキーを設定します(下)。
<MTSetVarBlock name="week" key="mon">
:
</MTSetVarBlock>
<MTSetVarBlock name="week" key="tue">
:
</MTSetVarBlock>
:
ハッシュの取得
ハッシュの内容を取得・表示するには、MTGetVar(または MTVar)で name モディファイアにキーつきの変数名を指定します。
<MTGetVar name="week{mon}">
<MTGetVar name="week{tue}">
:
実行結果
Monday
Tuesday
:
または、MTGetVar(または MTVar)で name モディファイアと別に key モディファイアにインデックス値を指定します。実行結果は同じです。
<MTGetVar name="week" key="mon">
<MTGetVar name="week" key="tue">
:
ハッシュの要素数を求める
ハッシュを設定した後の要素数は次の方法で求めます。
<MTGetVar name="count(week)">
name モディファイアに要素数を求める関数名(count)と、関数のパラメータ(括弧内)に処理の対象となる配列の変数名を記述します。
実行結果
7
または、
<MTGetVar name="week" function="count">
と書いても同じです。
ハッシュから要素を削除する
ハッシュから指定したキーの要素を取得し、同時にハッシュから該当要素を削除します。
<MTGetVar name="delete(week)" key="a">
name モディファイアに要素数を求める関数名(delete)と、関数のパラメータ(括弧内)に処理の対象となる配列の変数名を記述します。
実行結果(結果には表示されませんがハッシュのキーが削除されています)
Monday
または、
<MTGetVar name="week" key="a" function="delete">
と書いても同じです。
以上です。
さらに複雑な制御も可能と思われますがとりあえずこの辺で。
サイドバーの表示をメインページと同じにする
Movable Type 4 で、サイドバーの表示をメインページと同じにするカスタマイズです。
複数の方から「各ページのサイドバーの表示をメインページを同じしたいのですが」という質問を頂きましたので、このエントリーで紹介致します。
ここでは当ブログの配布テンプレート「Movable Type テンプレート」を例に説明しますが、デフォルトテンプレートでも同様のカスタマイズが可能です。
なお、このエントリーのカスタマイズを行うだけではメインページと全く同じ表示にならないのですが、そのことについては次回のエントリーで解説します。
1.ページによってサイドバーの表示内容が異なる仕組み
ページによってサイドバーの表示内容が異なるのは、サイドバーの各リストを MTIf タグで括り、表示するページを振り分けているためです。MTIf は Movable Type 4 で新たに追加されたテンプレートタグで、ある値を判定することで処理を振り分ける、という機能をもっています。
例えば、タグクラウドがメインページでしか表示されないのは、下のように MTIf タグで全体を括っています。
<MTIf name="main_index">
<dt class="sidetitle">
Tag Clouds
</dt>
<dd class="side">
<ul id="tags">
<MTTags>
<li class="module-list-item taglevel<$MTTagRank$>">
<a href="<$MTTagSearchLink$>"><$MTTagName$></a>
</li>
</MTTags>
</ul>
</dd>
</MTIf>
そして、MTIf タグの name 属性に記述された main_index という変数の値が "1" の場合にのみ、MTIf タグブロック内部が実行(=再構築対象)されます。
main_index という変数は、メインインデックスを再構築する時だけ "1" になる仕組みになっています。
また、月別アーカイブリストは、
<MTIf name="module_monthly_archives">
<MTIfArchiveTypeEnabled archive_type="Monthly">
<dt class="sidetitle">
Monthly Archives
</dt>
<dd class="side">
<ul>
<MTArchiveList archive_type="Monthly">
<li><a href="<$MTArchiveLink$>"><$MTArchiveTitle$></a> [<$MTArchiveCount$>]</li>
</MTArchiveList>
</ul>
</dd>
</MTIfArchiveTypeEnabled>
</MTIf>
と、MTIf タグの name 属性に module_monthly_archives という変数名を用いています。そして月別アーカイブの再構築時だけ module_monthly_archives の値が "1" になり、MTIf タグブロック内が再構築対象となります。
2.メインページと同じ表示にする方法
方法は、各リストを括っているMTIf タグを外すだけです。ただし、「最近のエントリー」については冒頭に記した通り、MTIf タグを外しただけではメインページと同じ表示にならないので、その点は予めご了承ください。
以下、リスト別に示します。赤色部分を削除してください。
最近のエントリー
<MTIf name="module_recent_entries">
<dt class="sidetitle">
Recent Entries
</dt>
<dd class="side">
<ul>
<MTEntries lastn="10">
<li><a href="<$MTEntryPermalink$>" title="e<$MTEntryID$>"><$MTEntryTitle$></a></li>
</MTEntries>
</ul>
</dd>
</MTIf>
タグクラウド
<MTIf name="main_index">
<dt class="sidetitle">
Tag Clouds
</dt>
<dd class="side">
<ul id="tags">
<MTTags>
<li class="module-list-item taglevel<$MTTagRank$>">
<a href="<$MTTagSearchLink$>"><$MTTagName$></a>
</li>
</MTTags>
</ul>
</dd>
</MTIf>
カテゴリーリスト
<MTIf name="module_category_archives">
<MTIfArchiveTypeEnabled archive_type="Category">
<dt class="sidetitle">
Categories
</dt>
<dd class="side">
<div id="categories">
<MTTopLevelCategories>
<MTSubCatIsFirst><ul></MTSubCatIsFirst>
<MTIfNonZero tag="MTCategoryCount">
<li><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><MTCategoryLabel></a> [<$MTCategoryCount$>]
<MTElse>
<li><MTCategoryLabel>
</MTElse>
</MTIfNonZero>
<MTSubCatsRecurse max_depth="3">
</li>
<MTSubCatIsLast></ul></MTSubCatIsLast>
</MTTopLevelCategories>
</div>
</dd>
</MTIfArchiveTypeEnabled>
</MTIf>
月別アーカイブリスト
<MTIf name="module_monthly_archives">
<MTIfArchiveTypeEnabled archive_type="Monthly">
<dt class="sidetitle">
Monthly Archives
</dt>
<dd class="side">
<ul>
<MTArchiveList archive_type="Monthly">
<li><a href="<$MTArchiveLink$>"><$MTArchiveTitle$></a> [<$MTArchiveCount$>]</li>
</MTArchiveList>
</ul>
</dd>
</MTIfArchiveTypeEnabled>
</MTIf>
3.注意事項
タグクラウドは再構築のパフォーマンスに影響があるため、他のアーカイブで表示させない(MTIf タグを外さない)ことをお勧めします。
表示させたい場合は Ajax モジュール化を行ないましょう。
4.サイドバーの MTIf タグに設定されている変数名
参考までに、デフォルトテンプレート(3 カラム)で、各リストの MTIf タグに設定されている変数名をまとめました(配布テンプレートも基本的にこの仕組みにしたがっています)。
| リスト名 | 変数名 |
|---|---|
| タグクラウド | main_index |
| ユーザーアーカイブリスト | module_author_archives |
| 月別アーカイブリスト | module_monthly_archives |
| 月別カテゴリーアーカイブリスト | module_category-monthly_archives |
| 月別ユーザアーカイブリスト | module_author-monthly_archives |
| 最近のエントリー | module_recent_entries |
| アイテムリスト | main_index |
| サブカテゴリーリスト | module_category_archives |
上記の各変数名がどのページで "1" になるかについては「予約変数一覧 for Movable Type 4(その1)」を参考にしてください。
なお、
- main_index
- module_recent_entries
の2つの変数については、どちらもメインページのみで "1" となります。
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.参考
MTSetVarBlock と MTSetVarTemplate の違いについて
Movable Type 4 では、MTSetVar タグや MTSetVarBlock タグを用いた制御が数多く行われています。 本エントリーでは、新たに追加された MTSetVarTemplate タグについて解説します。
1.MTSetVarTemplate タグの機能
MTSetVarTemplate タグで囲まれた内容を、変数として値を設定します。
<MTSetVarTemplate name="foo">
<!-- do something -->
</MTSetVarTemplate>
なお、MTSetVarTemplate タグは、ドキュメントによれば MT 管理画面での使用が目的らしいので、ユーザのテンプレートで用いる可能性は低いかもしれません。
2.MTSetVarBlock タグとの違い
MTSetVarBlock タグは、ブロック内の内容が処理された結果を値として取得しますが、MTSetVarTemplate タグは、ブロックの内容が MTGetVar、あるいは MTVar タグで呼び出された時点ではじめて評価されます。
3.サンプル
ここでは MTIncludeタグ・MTGetVar タグと組み合わせた、MTSetVarBlock タグと MTSetVarTemplate タグの振舞いの違いを示したいと思います。
3.1 MTSetVarBlock + MTInclude + MTGetVar(OK)
MTSetVarTemplate タグは用いず、アーカイブテンプレートの MTInclude タグが実行された時点で MTEntries 全体が評価されるサンプルです。
アーカイブテンプレート
<$MTInclude module="test"$>
<$MTGetVar name="entries"$>
テンプレートモジュール(test)
<MTSetVarBlock name="entries">
<MTEntries>
<$MTEntryTitle$>
</MTEntries>
</MTSetVarBlock>
3.2 MTSetVarBlock + MTInclude + MTGetVar(NG)
アーカイブテンプレートの MTInclude で MTEntryTitle が評価されますが、評価時点では MTEntryTitle が MTEntries コンテキスト外のため、再構築エラーとなるサンプルです。
アーカイブテンプレート
<$MTInclude module="test"$>
<MTEntries>
<$MTGetVar name="entries"$>
</MTEntries>
テンプレートモジュール(test)
<MTSetVarBlock name="entries">
<$MTEntryTitle$>
</MTSetVarBlock>
3.3 MTSetVarTemplate + MTInclude + MTGetVar(OK)
3.2項の MTSetVarBlock タグを MTSetVarTemplate タグに置き換えることで、アーカイブのMTInclude 時点でMTEntryTitleは評価されず、MTGetVar(=MTEntires ブロック内)で評価されるので、期待通りの動作になります。
アーカイブテンプレート
<$MTInclude module="test"$>
<MTEntries>
<$MTGetVar name="entries"$>
</MTEntries>
テンプレートモジュール(test)
<MTSetVarTemplate name="entries">
<$MTEntryTitle$>
</MTSetVarTemplate>
4.参考:MT4 のデフォルトテンプレート
3項でサンプルをいくつか比較しましたが、実際には、デフォルトテンプレートの MTEntries 関連のタグデザインは下記の通りです。
MTGetVar は用いず、アーカイブテンプレートの MTEntries ブロックに直接 MTInclude が記述され、MTEntryTitleが評価されます。
アーカイブテンプレート
<MTEntries>
<$MTInclude module="test"$>
</MTEntries>
テンプレートモジュール(test)
<$MTEntryTitle$>
5.まとめ
MTSetVarTemplate を用いるケースとして、下記が考えられます。
- テンプレートモジュールをひとつにまとめたい
- ブロックタグとファンクションタグのテンプレートを分離したい
- ファンクションタグのテンプレートモジュールに、複数のバリエーションをもたせる(MTGetVar で振り分ける)
管理画面テンプレートは調査していないので、実際にはもう少し適正な使用方法があるかもしれません。
strip 属性で日付の空白を削除する
Movable Type の日付情報から空白を削除する小技です。
例えば、当サイトの配布テンプレートのブログ記事(エントリー)日付は、下記のように「日」の部分が1桁の場合は半角空白があります。

この半角空白をなくすには、ブログ記事(エントリー)日付を表示しているMTタグ
<MTDateHeader>
<p class="date"><$MTEntryDate format="%x"$></p>
</MTDateHeader>
を
<MTDateHeader>
<p class="date"><$MTEntryDate format="%x" strip=""$></p>
</MTDateHeader>
と、空の strip 属性を与えればOKです。

strip 属性は、Movable Type 4 で新しく追加されたグローバル・モディファイアで、Movable Type ドキュメントでは
テンプレートタグの値に含まれる、1つ以上の連続する半角空白文字を指定した内容に置き換えます。
となっています。したがって、何も指定しなければ空白が除去されます。
また、format 属性と順番を入れ替えて、
<MTDateHeader>
<p class="date"><$MTEntryDate strip="" format="%x"$></p>
</MTDateHeader>
としても大丈夫です。
MTIgnore タグ
Movable Type 3.3 では、MTIgnore というコンテナタグが追加されました。このタグで括られた部分は再構築で何も処理されません。HTML のコメントアウト(<!-- ? -->)ではコメントアウトした部分が HTML ソースに残りますが、このタグを使用すれば HTML ソースにも表示されなくなります。
例えば下記のようなタグ、
リスト1.1 MTIgnore タグの使用例1
コメント1
<MTIgnore>コメント2</MTIgnore>
コメント3
とすれば、HTML には
リスト1.2 リスト1.1 のHTMLソース
コメント1
コメント3
という表示になります。
コメント文字列だけでなく、MTタグを MTIgnore で括ることも可能です。リスト1.3 のように括れば、生成された HTML ページに MTEntries タグの内容は何も表示されません。
リスト1.3 MTIgnore タグの使用例2
<MTIgnore>
<MTEntries>
<$MTEntryTitle$><br />
</MTEntries>
</MTIgnore>
実は、不要なMTタグにHTMLコメントアウト(<!-- ? -->)を施ししても、再構築時点ではそのMTタグは処理対象となってしまいます(Movable Type はHTMLコメントアウトを認識しないため)。つまりその分パフォーマンスに影響し、さらにHTMLソースに展開されたMTタグが残ってしまいますのでファイルサイズにも影響します。
HTMLコメントアウトの代わりにこのタグを用いれば、再構築対象にならず、HTMLソースにも残らないため、これらの欠点を一気に解消することができます。
カスタマイズ等で不要なタグを非表示にしたい場合に便利です。
エントリーで table タグを記述する場合の注意
Movable Type のエントリーで table タグを記述すると、テーブルの直前にある段落と大きな余白が生じる場合があります。
例えば以下のようになります。
段落
| あいうえお |
| かきくけこ |
| さしすせそ |
上記サンプルの「段落」という文字と、次に表示されているテーブルの間は、エントリー本文では1回改行しているだけですが、表示させるとこれだけの間隔が空いてしまいます(注:ここで本当にそうやってしまうと、このエントリーが valid な HTML にならなくなるため、便宜上、br 要素を複数回繰り返し挿入し、見た目が同じになるようにしています)。
原因は、エントリーのオプションにある「改行設定」が「改行を変換する」になっている場合、table タグに含まれる改行に全て改行タグが設定されてしまい、その改行が table タグの直前で有効になってしまうためです。
上記の例では、エントリー編集画面では
段落
<table border="1" cellpadding="2" cellspacing="0">
<tr><td>あいうえお</td></tr>
<tr><td>かきくけこ</td></tr>
<tr><td>さしすせそ</td></tr>
</table>
となっていますが、保存すると、
<p>段落<br />
<table border="1" cellpadding="2" cellspacing="0"><br />
<tr><td>あいうえお</td></tr><br />
<tr><td>かきくけこ</td></tr><br />
<tr><td>さしすせそ</td></tr><br />
</table></p>
と、全ての行末に改行マーク(赤色)が挿入されてしまいます。青色はその前後が空行の場合に挿入される段落用の p タグです。
table に改行タグを挿入させない策がいくつかありますのでご紹介します。
1.テーブル中の改行をなくす
これが一番手っ取り早いですが、エントリーの編集でやや見づらくなるのが欠点です。
追記:書き忘れてましたが、table タグが p タグの中に存在すると XHTML検証エラーとなります(つまり上記のリストはNGです)ので、2項を推奨します。
2.table 開始タグの直前に空行をいれる
Movable Type がエントリーに改行を付与する制御の仕組み上、先頭行(その前が空行であること)が下記のいずれかのタグに該当すれば、そのタグが含まれる行から次に空行が現れるまで改行タグおよび段落タグを挿入しない仕組みになっています。
h1|h2|h3|h4|h5|h6|table|ol|dl|ul|menu|dir|p|pre|center|form|fieldset|select|blockquote|address|div|hr
つまり、table タグの直前行に文章を書かなければ、1項の作業を行わなくても正常に表示されるようになります。これも手っ取り早い方法ですが、直前行を空けるという制約があります。
3.プラグインを利用する
The blog of H.Fujimoto の壱さんが「改行を変換する」を改良するプラグインを提供されていますので、これを用いることで正常に出力することができます。
MTLink によるページ作成
Movable Type の変数タグで MTLink というものがあります。Movable Typeユーザー・マニュアル:テンプレート・タグでは下記のような説明になっています。
Index Templateもしくは特定のエントリーへのURLを自動的に生成するためのタグ。
つまり、インデックス・テンプレートまたはある特定のエントリーに対するリンクを設定したい場合に使うためのタグです。
以下、インデックス・テンプレートおよびエントリーのリンク設定方法について説明します。
インデックス・テンプレートへのリンク
インデックス・テンプレートを新しく作成する時に「テンプレートの名前」欄を設定されると思いますが、その名前を MTLink の template 属性に指定することでリンクを生成します。
MTLink を使用しなければ、リンクのURLは
<a href="<$MTBlogURL$>profile.html">プロフィール</a>
と赤色部分のように書かれると思いますが、例えば「テンプレートの名前」を「Profile」と設定している場合、
<a href="<$MTLink template="Profile"$>">プロフィール</a>
と青色部分のように書くことで同様の効果を得ることができます。このタグを用いることによるメリットは、出力ファイル名に依存せずに記述できる、ということです。例えば途中でファイル名を変更するようなケースがあってもテンプレートに書かれたリンクを修正する必要はありません。
特定のエントリーへのリンク
エントリーに付与されるエントリーIDを MTLink の entry_id 属性に指定することで特定のエントリーに対するリンクを生成します。例えば書籍を紹介するエントリーを書き、このエントリーのリンクを作る場合(仮にエントリーIDは"562"とします)、下記の青色部分のように設定します。
<a href="<$MTLink entry_id="562"$>">書籍の紹介</a>
こちらはインデックス・テンプレートと異なり、個別エントリーアーカイブとしても生成されますが、あるエントリーに対して他のエントリーとは別に「おすすめコーナー」のようなリンクを作りたい場合等に役に立つと思います。
また template 属性と同様、個別エントリーアーカイブページのURLを直接記述しないので、URLやファイル名を変更しても、このリンクを修正する必要はありません。
エントリーIDの確認方法ですが、該当のエントリーを公開状態にした後、管理画面の該当のエントリー編集画面に遷移します。そこで表示される URL の query に
http://~/mt.cgi?__mode=view&_type=entry&blog_id=1&id=562&saved_changes=1
と表示されますので、赤色部分がエントリーIDになります。
Movable Type のディレクトリ
Tag:[MovableType, MTBlogArchiveURL, MTBlogSitePath, MTCGIPath, MTStaticWebPath, VariableTag]
Permalink
カスタマイズする際の外部ファイル(JavaScript等)のアップロードで配置するディレクトリに戸惑う方が少なくありません。「どこにアップロードすればよいのでしょうか」という質問も時々頂きます。
その問題が解消されるかどうか定かではありませんが、改めてディレクトリについてまとめてみました。文中でパスとディレクトリの表現が混在していますがあまり気にしないでください。厳密にはファイル名を含むのが「パス」のようですが、Movable Type の画面ではディレクトリを「パス」と表現しているようです。
CGIPath
適切な名称がありませんので mt.cfg の名称を使います(記事の中でも好んで用いています)。端的に言うと、各CGIスクリプトを配置するディレクトリです。レンタルサーバでは cgi-bin というディレクトリ名が付与されています。
このディレクトリには cgi ファイル(mt.cgi/mt-comment.cgi/mt-tb.cgi 等)と、CGIスクリプトを実行するために必要なライブラリのディレクトリ(下記)が配置されます。
- extlib/
- lib/
- php/
- plugins/
- schemas/
- search_templates/
- tmpl/
- tools/
ブラウザから閲覧できるファイルはここには存在しません。JavaScript 等の外部ファイルをここに配置することはありません。また CGIPath は Typekeyの登録URLとしても使われます。index.html があるURLを Typekey登録画面で登録されても Typekey は正常に動作しませんのでご注意ください。
このディレクトリはMT変数タグで
<$MTCGIPath$>
と表現されます。
ローカル・サイト・パス
index.html が配置されるディレクトリです。「ローカル・サイト・パス」は管理画面の基本設定の項目名で使われているので、当サイトではこの名称を好んで使っています。各インデックス・テンプレートを再構築した際に生成されるファイル(index.html/styles-site.css 等)がこのディレクトリに配置されます。カスタマイズ等で外部ファイルをアップロードする際には必ずこのディレクトリにアップロードしてください(プラグインファイルは除外)。
このディレクトリはMT変数タグで
<$MTBlogSitePath$>
と表現されます。これをURLにしたものが
<$MTBlogURL$>
です。
レンタルサーバではCGIスクリプトを特定のディレクトリでしか実行できないように制限していますが、そのような環境設定でない場合、例えば自宅サーバ等ではこのディレクトリにCGIスクリプトを配置して動作させることも可能です。とういか私は当初そのような使い方をしていたため、レンタルサーバご利用者の方に随分わかりにくい説明をしていました。
アーカイブ・パス
管理画面で「ローカル・アーカイブ・パス」と書かれているディレクトリです。再構築されたアーカイブ・テンプレート(カテゴリー・アーカイブ/日付アーカイブ/個別エントリーアーカイブ等)がここに生成されます。デフォルト設定では、ローカル・サイト・パスに archives というディレクトリを作るように仕組まれています。
このディレクトリのURLはMT変数タグで
<$MTBlogArchiveURL$>
と表現されます。
StaticWebPath
これもいい名称がありませんので mt.cfg の名称を使います。これは管理画面の表示に使われる
- styles.css
- mt.js
- images/
- docs/
を配置するためのディレクトリです。mt.cfg で設定する際はドキュメントルートからの指定になります(かつ前後を "/" で括る)のでご注意ください。
このディレクトリが必要な理由ですが、そもそも CGIPath は Apache の ScriptAlias で設定されたディレクトリで、このディレクトリに配置されたファイルは常にCGIスクリプトとして認識されるため、他のファイルやディレクトリを配置しても正常に振舞うことができないためです。ローカル・サイト・パスに配置しても構わないのですが、本来の使用目的から考えると専用のディレクトリに置いた方が好ましいでしょう。
このディレクトリはMT変数タグで
<$MTStaticWebPath$>
と表現されます。
全エントリーリスト・全コメントリスト・全トラックバックリストを表示
Movable Type で全てのエントリー・コメントおよびトラックバックを表示するカスタマイズです。全コメントリストについての参考記事は下記です。ありがとうございました。
まず全コメントリストを表示するためのカスタマイズです。これは「最近のコメント」のタグを修正して
<MTEntries recently_commented_on="<$MTBlogEntryCount$>">
<a href="<$MTEntryLink$>"><MTEntryTitle></a>
<br />
<MTComments>
└ <a href="<$MTEntryLink$>#c<$MTCommentID$>">
<MTCommentAuthor></a> <$MTCommentDate format="%m/%d"$><br />
</MTComments>
</MTEntries>
と、最初の行の recently_commented_on に全エントリー数である <$MTBlogEntryCount$> を指定すれば全てのエントリーに対するコメントを表示できそうですが、この部分にMT変数タグを指定すると再構築でエラーとなります。そこで MTTagInvoke プラグインを利用して、
<MTEntries recently_commented_on="<$MTBlogEntryCount$>">
<MTTagInvoke tag_name="MTEntries">
<MTTagInvokeAttribute name="recently_commented_on"><$MTBlogEntryCount$></MTTagInvokeAttribute>
<MTTagInvokeContent>
<a href="<$MTEntryLink$>"><MTEntryTitle></a>
<br />
<MTComments>
└ <a href="<$MTEntryLink$>#c<$MTCommentID$>">
<MTCommentAuthor></a> <$MTCommentDate format="%m/%d"$><br />
</MTComments>
</MTTagInvokeContent>
</MTTagInvoke>
</MTEntries>
とすることで表示できるようになります。MTTagInvoke プラグインについては個別エントリーアーカイブに同一カテゴリーのエントリーを表示を参照ください。
注:MTTagInvoke のタグ名をバージョン 1.0 の内容に変更しています。
次に、全トラックバックリストはTrackback元記事表示で紹介した MTPingedEntry プラグインを利用した場合、下記のようなタグになります。
<div class="side">
<MTPings sort_order="descend">
<a href="<$MTPingURL$>" target="_blank" title="<$MTPingExcerpt$>"><$MTPingTitle$></a><br />
└ →<MTPingedEntry><a href="<$MTPingedEntryLink$>"><$MTPingedEntryTitle$></a></MTPingedEntry><br/>
[<$MTPingBlogName$>] <$MTPingDate format="%m/%d %X"$><br/>
</MTPings>
</div>
ここでは MTTagInvoke は使用しておりません。これは MTPings タグの仕様で、何も指定しない場合は「システム全体で受けたすべてのトラックバックのリストを表示」になります。
sort_order="descend"
は新着順に表示するための指定です。逆にする場合は
sort_order="ascend"
となります。
全エントリーリストは、Movable Type がデフォルトで用意している「アーカイブページ」のデフォルトで設定されているタグ
<MTArchiveList>
<a href="<$MTArchiveLink$>"><$MTArchiveTitle$></a><br />
</MTArchiveList>
で実現できますが、MTEntries を用いることでも可能ですので紹介しておきます。
次のリストはタイトル順にソートして一覧表示をする例です。
<MTEntries sort_by="title" sort_order="ascend">
<a href="<$MTEntryPermalink$>"><$MTEntryTitle$></a><br />
</MTEntries><br />
カテゴリー別にまとめるには下記のようにします。これはユーザー・マニュアルに掲載されているものです。
<MTCategories>
<$MTCategoryLabel$><br />
<MTEntries sort_by="title" sort_order="descend">
<a href="<$MTEntryPermalink$>"><$MTEntryTitle$></a><br />
</MTEntries><br />
</MTCategories>
MTEntries タグは sort_by を指定することで全てのエントリーを表示してくれるようです。ということで一番最初の全コメントリストは、
<MTEntries sort_by="modified_on">
<a href="<$MTEntryLink$>"><MTEntryTitle></a>
<br />
<MTComments>
└ <a href="<$MTEntryLink$>#c<$MTCommentID$>">
<MTCommentAuthor></a> <$MTCommentDate format="%m/%d"$><br />
</MTComments>
</MTEntries>
とすれば同様の表示をすることができます(こちらはエントリー更新順の模様)。
以上です。いずれも再構築時間の問題がありますので、自動的に再構築しない設定にされることをお勧めします。
2006.10.02
MTTagInvoke 1.0 の記述を追加しました。
2006.11.23
サンプルリストを MTTagInvoke 1.0 の内容に変更しました。
カテゴリーアーカイブで MTCategoryDescription をタイトルに使う
Tag:[Category, Customize, MovableType, MTCategoryDescription, MTCategoryLabel, Plugin]
Permalink
カテゴリーリスト表示で MTCategoryDescription に日本語を設定して MTCategoryLabel の代わりに用いている方は少なくないと思います。この設定にしている理由は、
- Movable Type 2.x の時に MTCategoryLabel に日本語を設定すると不具合が発生していた(この設定を 3.x でも引き継いで使用)
- MTCategoryLabel に順序性のある文字列(01・02…等)を与えてカテゴリーリストを期待する順序に並べる
のどちらかであると考えられます。
この設定を行っている場合、カテゴリーアーカイブでは MTCategoryLabel が MTArchiveTitle として解釈されるので、例えばデフォルトテンプレートでは MTCategoryLabel がタイトルとして表示されるという問題があります。
単純に MTArchiveTitle を MTCategoryDescription に置き換えればよいのですが、ユーザーマニュアルからは MTCategoryDescription が
<MTCategories>
:
</MTCategories>
の中でしか使えないように思えます。ところがカテゴリーアーカイブに限っては MTCategoryDescription を単独で用いることができるようです。
したがって、カテゴリーアーカイブの title タグは
<title><$MTBlogName encode_html="1"$>: <$MTArchiveTitle$><$MTCategoryDescription$> アーカイブ</title>
とすれば「カテゴリーの説明」が表示されます。
また公開テンプレートのカテゴリーアーカイブで、左カラムにカテゴリーのエントリー一覧を表示する部分についても
<div class="sidetitle">
The list of "<$MTArchiveTitle$><$MTCategoryDescription$>"
</div>
と修正すればOKです。
MTCategoryDescription がカテゴリーアーカイブで独立したタグで使えるというのは、Movable Type 公式サイト:Movable Type 3.0 日本語版ベータ2のご提供のOgawa::Memorandaさんのコメントで書かれている記事がありました。
また「MTCategoryLabel に番号をつけて表示する際に番号だけカットする」というプラグインもありますので併せてご紹介させて頂きます。
「最近のエントリー」の日別表示
Tag:[Customize, Entry, MovableType, MTDateFooter, MTDateHeader, MTEntryDate]
Permalink
公開テンプレートの「Recent Entries(最近のエントリー)」というタイトルのメニューリストは、デフォルト状態では直近の10エントリーを単純に並べて表示するだけです。ここではこれを日別に分割して表示するためのカスタマイズをご紹介致します。

カスタマイズ方法ですが、各テンプレートにある「Recent Entries」を表示するMTタグの該当部分について、下記のように青色部分を追加します。修正後のリストは元記事からの引用です。
<div class="sidetitle">
Recent Entries
</div>
<div class="side">
<MTEntries lastn="10">
<MTDateHeader>
<$MTEntryDate format="%m/%d"$><br />
</MTDateHeader>
└ <a href="<$MTEntryPermalink$>"><$MTEntryTitle$></a><br />
</MTEntries>
</div>
MTEntryDateのformat属性は "mm/dd"(例えば02/11)と表示されるように設定しています。この部分の修正で日付表示を変更することができます。フォーマットの詳細はユーザー・マニュアル:日付タグのフォーマットをごらんください。
先日投稿したサイドメニューのツリー化スクリプトに対応させる場合は下記をご利用ください。
<div class="sidetitle">
Recent Entries
</div>
<div class="side">
<MTEntries lastn="10">
<MTDateHeader>
<ul><$MTEntryDate format="%m/%d"$>
</MTDateHeader>
<li><a href="<$MTEntryPermalink$>" title="<$MTEntryTitle$>"><$MTEntryTitle$></a></li>
<MTDateFooter>
</ul>
</MTDateFooter>
</MTEntries>
</div>
最初のリストとの主な変更点を青色で示しています。リスト表示用HTMLタグへの変更と、同日の複数エントリーを構造化する時に利用するMTDateFooterタグを加えています。div タグの id 属性は必要に応じて適宜追加してください。
コメント投稿者の情報表示をカスタマイズする
コメント投稿者の情報表示のカスタマイズについてご説明致します。
表示に使用される変数タグは MTCommentAuthorLink / MTCommentPreviewAuthorLink の2種類で、表示方法の詳細設定にタグアトリビュート(属性)を用います。これによりコメントに入力されたコメント投稿者の情報(URL・メールアドレス等)の表示・非表示やを表示方法等をコントロールすることができます。
カスタマイズ方法です。まず MTCommentAuthorLink / MTCommentPreviewAuthorLink は、下記の各テンプレートの赤色部分に存在します(デフォルトテンプレートで示しています)。カスタマイズされる場合はこれらが一律対象となります。
個別エントリーアーカイブ
<MTComments>
<div id="c<$MTCommentID$>">
<$MTCommentBody$>
</div>
<p class="posted">投稿者 <$MTCommentAuthorLink default_name="Anonymous" spam_protect="1"$> <MTCommentAuthorIdentity> : <$MTCommentDate$></p>
</MTComments>
コメント・プレビュー
<$MTCommentPreviewBody$>
<p class="posted">投稿者 <$MTCommentPreviewAuthorLink spam_protect="1"$> : <$MTCommentPreviewDate$></p>
:
<MTComments>
<$MTCommentBody$>
<p class="posted">投稿者 <$MTCommentAuthorLink default_name="Anonymous" spam_protect="1"$> : <$MTCommentDate$></p>
</MTComments>
コメント・リスト(本テンプレートを使用している場合)
<MTComments>
<$MTCommentBody$>
<p class="posted">投稿者 <$MTCommentAuthorLink default_name="Anonymous" spam_protect="1"$> : <$MTCommentDate$></p>
</MTComments>
次にタグアトリビュート一覧を示します。
名前の入力がない場合のデフォルト名を設定する
default_name="Anonymous"
これは管理メニュー左の「ウェブログの設定」をクリック→次ページ右上の「設定」をクリック→次ページ下の方にある「コメント」の「名前とURLを必須にする」にチェックがついていない場合に有効になります。デフォルトテンプレートではこの属性が付与されていますが、先のチェックがついていれば気にする必要はありません。この属性の設定がなく「名前とURLを必須にする」チェックがついていない状態で名前なしのコメントが投稿されると、コメント欄に投稿者名が表示されません。
なお設定した場合(および無効にした場合)は以前の名無しコメント全てに適用されます。
メールアドレスにリンクしない
show_email="0"
コメントのメールアドレス欄にメールアドレスが入力されてもリンクしません。デフォルトテンプレートではリンクする状態になっています。
URLにリンクしない
show_url="0"
コメントのURL欄にURLが入力されてもリンクしません。デフォルトテンプレートではリンクする状態になっています。
URLをリダイレクトしない
no_redirect="1"
コメントスパムの目的は、リンクがクリックされることにより検索エンジンのランクを向上させることです。この部分でURLをリダイレクトする意味は、コメント投稿者のURLを検索エンジンから直接見えないようにするためです。そうすることでコメント・スパムの検索エンジンでのランク向上を抑制する効果があります。
デフォルト状態ではこのリダイレクト機能を有効にしていますが、リダイレクトを使いたくない場合は上記の設定を追加してください。
メールアドレスをスパム・ボット対策されたアドレスに変更する
spam_protect="1"
スパマーはHTMLソースに記述されるメールアドレスのフォーマットを見つけてスパムメールを送ります。
spam_protect アトリビュートを設定すればメールアドレスのリンクは表示されますが、スパム・ボット対策されたアドレスに変更されます。つまりブラウザ上では正しいメールアドレスとして表示され、実際のHTMLソースには「@」や「.」を含みません。例えばメールアドレスが
- foo@bar.com
であれば、HTMLでは
- foo@bar.com
となります。
デフォルトテンプレートではこの設定になっていますが、先の show_email="0" を指定した場合はメールアドレスにリンクしなくなるため冗長な設定となります。ただし設定が残っていても問題はありません。
下記に設定例を示します。最もポピュラーと思われるケースで「メールアドレスをリンクしない&メールアドレスをスパム・ボット対策されたアドレスに変更する」の設定は、
<$MTCommentAuthorLink show_email="0" spam_protect="1"$>
または
<$MTCommentPreviewAuthorLink show_email="0" spam_protect="1"$>
となります。
属性を記述する場合はその前後に半角空白を挿入します(変数タグの終了を示す"$"との間はなくても大丈夫です)。属性の記述順序に制約はありません。
MTCommentPreviewIsStatic の振る舞いについての改善案
コメントのポップアップ化に関する事項で、投稿後の表示画面選択情報を保持する MTCommentPreviewIsStatic の振る舞いについて改善案を記します。
MTCommentFields タグで MTCommentPreviewIsStatic が指定できない
MTCommentFields はコメント・リスト/コメント・プレビュー/コメント・エラーの各テンプレートでコメント入力フォームを指定するコンテナタグです。MTCommentPreviewIsStatic は、ユーザー・マニュアルでは
特別な秘匿タグで、Comment Preview and Comment Error テンプレートで使います。システムは、コメントを投稿後、どのページを表示したらよいか知るために、このタグを利用します。このタグを使うときは Comment Preview と Comment Error テンプレートの中の HTML フォーム の INPUT HIDDEN の中に埋め込みます。
という説明になっています。これは変数タグで、値と意味は次の通りと考えられます。
- 0:ポップアップ・ウィンドウ
- 1:非ポップアップ・ウィンドウ
MTCommentPreviewIsStatic の元となる情報は、個別エントリーアーカイブではコメントフォームに埋め込まれた
<input type="hidden" name="static" value="1">
またはコメント・リストの
<MTCommentFields static="0">
より取得します。
この値の取得方法は Movable Type ユーザー・マニュアルによると、コメント・プレビュー/コメント・エラーテンプレートのコメントフォーム内に
<input type="hidden" name="static" value="<$MTCommentPreviewIsStatic$>">
を指定するようになっています。
input タグを用いるということは、デフォルトテンプレートで使われている MTCommentFields が適用できないということを暗黙的に指しており、コメント用テンプレートに 個別エントリーアーカイブと同じ(膨大な)テンプレートを貼り付ける必要があります。
これは大きな問題ではありませんが面倒です。また直感的およびポップアップ化によるテンプレート変更の容易性から、コメント・プレビュー/コメント・エラーテンプレートで
<MTCommentFields preview="1" static="<$MTCommentPreviewIsStatic$>">
という指定ができても良いのではないでしょうか(実験しましたが×)。
という訳で上記は改善案として記させて頂きました。またこの指定が可能となるパッチが Orgawa::memoranda さんより公開されることを密かに期待しております。
なお MTCommentPreviewIsStatic 値の取得は、MTCommentFields を残した状態で下記のスクリプト(青色部分)を追加することで実現できます。
<MTCommentFields preview="1">
<script type="text/javascript">
<!--
if (document.comments_form.static)
document.comments_form.static.value = '<$MTCommentPreviewIsStatic$>';
//-->
</script>
この方が、個別エントリーアーカイブよりコメント用フォームをコピー&ペーストし、その中の input タグの指定を変更するという作業を行うよりはるかに簡単です。
コメント・プレビュー/コメント・エラー画面でフォーム情報が引き継がれない
真面目に input タグから MTCommentPreviewIsStatic 値を取得した場合の問題です。
現状の仕様により、MTCommentPreviewIsStatic を使用するためにコメント・プレビュー/コメント・エラーテンプレートの
<MTIfCommentsAllowed>
:
</MTIfCommentsAllowed>
を個別エントリーアーカイブのもの(厳密にはcookie取得用のJavaScriptを含む)に入れ替える必要がありますが、そのままではフォーム入力がプレビュー画面に引き継がれないという問題(カスタマイズ不足?)が発生します。
これについては入れ替えた部分の下記の input タグにvalue 属性等(青色部分)を追加することで解決します。
<input tabindex="1" id="author" name="author" value="<$MTCommentPreviewAuthor encode_html="1"$>"/>
:
<input tabindex="2" id="email" name="email" value="<$MTCommentPreviewEmail encode_html="1"$>"/>
:
<input tabindex="3" type="text" name="url" id="url" value="<$MTCommentPreviewURL encode_html="1"$>"/>
:
<textarea tabindex="4" id="text" name="text" rows="10" cols="50"><$MTCommentPreviewBody convert_breaks="0" encode_html="1"$></textarea>
また入れ替えたタグの直後に下記のスクリプト(Ogawa::memoranda:Movable Type 3.0のMTCommentFields tagより引用)を追加する方法もあります。
<script type="text/javascript">
<!--
if (document.comments_form.author)
document.comments_form.author.value =
'<$MTCommentPreviewAuthor encode_js="1"$>';
if (document.comments_form.email)
document.comments_form.email.value =
'<$MTCommentPreviewEmail encode_js="1"$>';
if (document.comments_form.url)
document.comments_form.url.value =
'<$MTCommentPreviewURL encode_js="1"$>';
if (document.comments_form.text)
document.comments_form.text.value =
'<$MTCommentPreviewBody convert_breaks="0" encode_js="1"$>';
//-->
</script>
仮にこれが不具合であったとしてもシステムとして修正されることは考えにくいので、やはりコメント・プレビュー/コメント・エラーテンプレートでは MTCommentFields の利用が前提ではないかと推測しています。
動作および振る舞いについて認識誤り等ございましたらご指摘ください。
2004.12.23 追記
フォーム情報が引き継がれない問題について、(o)さんよりアドバイス頂いた方法(inputタグに挿入)に修正しました。先に書いたのもとりあえず残してます。
またスクリプトの引用がもれていたので追記しました。
さらにcookie取得用のJavaScriptは不要ですので削除しました(ポップアップでこれが必要なのはコメント・リストテンプレートのみ)。
2006.04.04 追記
リストから language 属性を削除しました(HTML4.01/XHTMLで非推奨あるいは廃止されているため)。
カテゴリーアーカイブで全サブカテゴリーリストを表示
Movable Type 3.11-ja ではサブカテゴリー機能が追加されました。それに伴いサイドバーメニューのカテゴリーリストにはこれまで通りの表示に加え、サブカテゴリー表示もできるタグ
- <MTSubCategories>~</MTSubCategories>
が追加されました(関連タグは割愛)。
ところが、例えばメインページからカテゴリーアーカイブページにジャンプすると、サイドバーのカテゴリーリストにはそのカテゴリー配下のカテゴリーしか表示されなくなります。配下のカテゴリーが存在しない場合は何も表示されません。
カテゴリーリストの表示サンプルを下図に示します。
・メインページで表示されているカテゴリーリスト。ここでは全カテゴリーが表示されています。視覚的にお分かりになると思いますが、トップカテゴリーに「ウェブログ」「趣味」、「ウェブログ」カテゴリーのサブカテゴリーに「こうさぎ」「カスタマイズ」、「カスタマイズ」カテゴリーのサブカテゴリーに「テンプレート」「折りたたみ」、「趣味」カテゴリーのサブカテゴリーに「映画」「読書」があります。 |
・上のカテゴリーリストより「ウェブログ」をクリックしてジャンプしたページで表示されるカテゴリーリストです。「ウェブログ」カテゴリーに関係するサブカテゴリーだけが表示されます。 |
・上のカテゴリーリストより「カスタマイズ」をクリックしてジャンプしたページで表示されるカテゴリーリストです。「カスタマイズ」カテゴリーに関係するサブカテゴリーだけが表示されます。 |
・上のカテゴリーリストより「折りたたみ」をクリックしてジャンプしたページで表示されるカテゴリーリストです。下位のカテゴリーが存在しないため何も表示されません。 |
上記の振る舞いは場合によっては使い道がありますが、サイドメニューとして相応しいかどうかは個人的に疑問があり、当サイトで公開中のテンプレートは以前のMTCategoriesを使ったメニュー表示にしています。
このエントリーではどのカテゴリーアーカイブページにジャンプしても、サンプルの一番上の画像のようなメニューが表示される方法を紹介します。なお日付アーカイブや個別アーカイブではページ自体に「カテゴリー」という概念がない(つまり先のタグがカテゴリーアーカイブ内のような振る舞いをしない)ので全カテゴリーが表示されます。
全カテゴリーを表示するには MTTopLevelCategories を用いることで実現できます。テンプレートの下記の赤色部分を青色に変更してください。
変更前
<div class="sidetitle">
Categories
</div>
<div class="side">
<div id="categories">
<MTSubCategories>
<MTSubCatIsFirst><ul></MTSubCatIsFirst>
<MTIfNonZero tag="MTCategoryCount">
<li><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><MTCategoryLabel></a> [<$MTCategoryCount$>]
<MTElse>
<li><MTCategoryLabel>
</MTElse>
</MTIfNonZero>
<MTSubCatsRecurse max_depth="3">
</li>
<MTSubCatIsLast></ul></MTSubCatIsLast>
</MTSubCategories>
</div>
</div>
変更後
<div class="sidetitle">
Categories
</div>
<div class="side">
<div id="categories">
<MTTopLevelCategories>
<MTSubCatIsFirst><ul></MTSubCatIsFirst>
<MTIfNonZero tag="MTCategoryCount">
<li><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><MTCategoryLabel></a> [<$MTCategoryCount$>]
<MTElse>
<li><MTCategoryLabel>
</MTElse>
</MTIfNonZero>
<MTSubCatsRecurse max_depth="3">
</li>
<MTSubCatIsLast></ul></MTSubCatIsLast>
</MTTopLevelCategories>
</div>
</div>
MTTopLevelCategories についてはMovable Type ユーザマニュアル: テンプレートタグで下記の説明があります。
MTTopLevelCategories
MTSubCategoriesのクローン。ただし、カテゴリー階層の最上位で常に開始します。
上記で全カテゴリーが表示されるようになりますが、カテゴリーリストを独立したインデックステンプレートとして割り充てる方法を併せてご紹介しておきます。これは巷で流行っている(?)「モジュール(部品)化」というものです。
インデックステンプレートはいわゆるメインページや他のアーカイブテンプレートと同じ位置付けで、保存・再構築することで独立したファイルを出力します。モジュール化のメリットはエントリーの再構築時間を短縮と、適用したアーカイブページで常に同じ内容が反映されることです。
以下、カスタマイズ方法です。
1.新しいインデックステンプレートを作成
管理メニューの「テンプレート」をクリックし、次ページの「インデックス・テンプレート」の右端にある「新しいインデックス・テンプレートを作る」をクリック。次ページの各項目に以下の内容を設定してください。
- テンプレートの名前:カテゴリーリスト
- 出力ファイル名:categorylist.html
- このテンプレートにリンクするファイル:(無記入)
- 再構築オプション:チェックをする
- テンプレートの中身:下記をコピー&ペースト(緑色部分は2004.12.01修正箇所)
<div class="sidetitle">
Categories
</div>
<div class="side">
<div id="categories">
<MTTopLevelCategories>
<MTSubCatIsFirst><ul></MTSubCatIsFirst>
<MTIfNonZero tag="MTCategoryCount">
<li><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><MTCategoryLabel></a> [<$MTCategoryCount$>]
<MTElse>
<li><MTCategoryLabel>
</MTElse>
</MTIfNonZero>
<MTSubCatsRecurse max_depth="3">
</li>
<MTSubCatIsLast></ul></MTSubCatIsLast>
</MTTopLevelCategories>
</div>
</div>
ペーストする内容は公開テンプレート(スタイルシート)を前提にしたものです。異なるテンプレートを使用されている場合は div タグのクラス属性等を適宜修正してください。
修正が終わったら、保存・再構築してください。管理メニューの「ウェブログの設定」→「基本設定」で指定したローカル・サイト・パスに categorylist.html が配置されます。
2.カテゴリー・アーカイブテンプレートの修正
先の categorylist.html をインクルードするためにカテゴリー・アーカイブテンプレートの下記の赤色部分を青色部分に修正します(リストは公開テンプレートを例にしています)。
修正前
<div class="sidetitle">
Categories
</div>
<!-- 全カテゴリー用 -->
<div class="side">
<MTCategories>
<a href="<$MTCategoryArchiveLink$>">
<$MTCategoryLabel$></a> [<$MTCategoryCount$>]<br />
</MTCategories>
</div>
<!-- 全カテゴリー用 -->
修正後
<$MTInclude file="categorylist.html"$>
categorylist.html が正常に読み込めない場合は上記のfile属性指定の部分をルートディレクトリからのフルパス指定に変更してください。
修正が終わったら保存・再構築してください。ここまでの作業が済めばカテゴリーアーカイブページのカテゴリーリストは全カテゴリーが表示されるようになっています。
3.他のアーカイブテンプレートの修正
カテゴリー・アーカイブテンプレートを除いた各テンプレートのカテゴリーリストを、MTCategories から MTSubCategories を用いたものに置き換えます。各テンプレートのカテゴリーリストを前記と同様の作業(MTIncludeタグへの変更)を行ってください。公開テンプレートをご利用の方は、下記のようにカテゴリーリストをコメントアウト(赤色部分を削除)し、コメントアウトされたサブカテゴリー部分を有効(青色部分を追加)にされてもOKです。
修正前
<!-- 全カテゴリー用 -->
<div class="side">
:
</div>
<!-- 全カテゴリー用 -->
<!-- サブカテゴリー用
<div class="side">
<div id="categories">
:
</div>
</div>
サブカテゴリー用 -->
修正後
<!-- 全カテゴリー用
<div class="side">
:
</div>
全カテゴリー用 -->
<!-- サブカテゴリー用 -->
<div class="side">
<div id="categories">
:
</div>
</div>
<!-- サブカテゴリー用 -->
修正が終了したらそれぞれ保存・再構築してください。
作業は以上です。なお3.11-ja用公開テンプレートご利用の方はスタイルシートの設定に冗長な部分がございましたので、下記の赤色部分をばっさり削除してやってください。少なくとも一番下の margin-bottom? を削除しないとメニュー下の空白が相当とられてしまいます。
.side #categories {
font-family: Verdana, Arial, sans-serif;
color: #666666;
background: none;
font-size: 9px;
font-weight:normal;
line-height:150%;
text-align: left;
padding:2px;
margin-bottom:25px;
}
2004.12.01 追記
全カテゴリー表示に MTTopLevelCategories タグを用いた方法がありましたので記述を一部修正致します。Note book :: Hibi no Note さんよりご指摘頂きました。ありがとうございました。
MTIfNonZeroタグでコメント表示方法を制御する
個別エントリーアーカイブの中で、「トラックバック数が0件でなければトラックバックを表示する」ために利用する
- MTIfNonZero
というタグが使われています。このタグを使うとちょっとした条件分岐ができ、ページへの表示を制御することができます。
参照サイトは下記です。ありがとうございました。
このエントリーでは MTIfNonZero タグを利用して、コメント投稿数が0件の時に
- 個別エントリーアーカイブの「コメント」タイトルを表示しない
- 個別エントリーアーカイブの「コメント」タイトル下に「コメントがありません」という表示をする
の2通りの方法を紹介します。私のサイトは下の方法でカスタマイズしてみました。
「コメント」タイトルを表示しない
個別エントリーアーカイブテンプレートの下記の部分に青色のタグを挿入すれば、コメントが0件の場合にコメントのタイトルを非表示にすることができます。</MTIfNonZero> の挿入位置は「コメント」と書かれた次の行でも問題ないと思いますが、コメント表示タグ全体を括らないのはスッキリしないので個人的には下記を推奨します。
:
<MTEntryIfAllowComments>
<MTIfNonZero tag="MTEntryCommentCount">
<div id="comments" class="comments-head"><a name="comments"></a>コメント</div>
<MTComments>
<a name="<$MTCommentID$>"></a>
<div id="c<$MTCommentID$>" class="comments-body">
<$MTCommentBody$>
<div class="comments-post">Posted by <$MTCommentAuthorLink default_name="Anonymous" spam_protect="1"$> <MTCommentAuthorIdentity> at <$MTCommentDate$></div>
</div>
</MTComments>
</MTIfNonZero>
<MTEntryIfCommentsOpen>
:
意味的には、MTIfNonZero の tag属性 MTEntryCommentCount(=エントリーのコメント数)が0でなければ <MTIfNonZero>~</MTIfNonZero> で囲まれた部分を表示(厳密には有効に)する、というものです。
「コメント」タイトル下に「コメントがありません」という表示をする
上記同様、青色のタグを該当位置に挿入すれば、コメントが0件の場合にコメントのタイトル下に「コメントがありません。」というメッセージを表示することができます。タイトルはいずれの場合も表示するので MTIfNonZero タグの中に入れないようにします。divタグは公開テンプレート用に併せて書いてありますので適宜変更してください。
:
<MTEntryIfAllowComments>
<div id="comments" class="comments-head"><a name="comments"></a>コメント</div>
<MTIfNonZero tag="MTEntryCommentCount">
<MTComments>
<a name="<$MTCommentID$>"></a>
<div id="c<$MTCommentID$>" class="comments-body">
<$MTCommentBody$>
<div class="comments-post">Posted by <$MTCommentAuthorLink default_name="Anonymous" spam_protect="1"$> <MTCommentAuthorIdentity> at <$MTCommentDate$></div>
</div>
</MTComments>
<MTElse>
<div class="comments-body">コメントはまだありません。</div>
</MTElse>
</MTIfNonZero>
<MTEntryIfCommentsOpen>
:
この処理をおおざっぱに書くと
<MTIfNonZero tag="MTEntryCommentCount">
:
コメントが0件でない時の処理を記述
:
<MTElse>
:
コメントが0件の時の処理を記述
:
</MTElse>
</MTIfNonZero>
という感じになります。MTElse というタグは MTIfNonZero の条件にマッチしなかった場合のものを有効にするためのタグです。
MTEntryLinkとMTEntryPermalinkについて
最近のコメントのアンカー修正で気になったのが、リンク先を表すタグ「MTEntryLink と MTEntryPermalink の違いって何だ?」ってことです(おいおい…)。先のエントリーに MTEntryPermalink は使っていないのですが、他サイトのコメントのリンクで MTEntryPermalink を使っているケースがあるのを見つけたからです。
ということで以下調査メモです。
いずれのタグもエントリーを含むアーカイブページへの絶対URLを示します。そしてこのリンク先のアーカイブ種別によって機能が異なるようです。
リンク先が個別アーカイブ、つまりアーカイブページとエントリーが1:1の場合は機能的に同じですが、例えばカテゴリーアーカイブ等のように一つのページに他のエントリーと一緒にそのエントリーが入っていた場合、MTEntryPermalink を用いれば特定のエントリーを指すためのアンカー (#) が自動的に付与されるようです。MTEntryLink にはアンカーを付与する機能はありません。
なお試しに MTEntryPermalink を用いてコメントのリンクを作ってみたところ、個別アーカイブを指している場合はアンカーは付与されませんでした。
リンクがどのアーカイブを指しているかを示すかは、管理メニューの「ウェブログの設定」→「ウェブログの設定」→ページ真ん中辺りの「アーカイブの設定」の最初にある「優先するアーカイブのタイプ 」で決定されます。デフォルトの設定は「個別」なので設定を変更しなければ個別アーカイブにリンクされるという仕組みです。
設定とは別にアーカイブファイルを変更したい場合はタグに archive_type 属性を付与します。例えばカテゴリーアーカイブにリンクしたい場合は、
<$MTEntryLink archive_type="Category"$>
と記述すればOKです。
MTタグについてはMovable Typeユーザー・マニュアル:テンプレート・タグに掲載されています。
2005.08.09 追記
本文にユーザー・マニュアルのリンクを追加しました。

・メインページで表示されているカテゴリーリスト。ここでは全カテゴリーが表示されています。視覚的にお分かりになると思いますが、トップカテゴリーに「ウェブログ」「趣味」、「ウェブログ」カテゴリーのサブカテゴリーに「こうさぎ」「カスタマイズ」、「カスタマイズ」カテゴリーのサブカテゴリーに「テンプレート」「折りたたみ」、「趣味」カテゴリーのサブカテゴリーに「映画」「読書」があります。
・上のカテゴリーリストより「ウェブログ」をクリックしてジャンプしたページで表示されるカテゴリーリストです。「ウェブログ」カテゴリーに関係するサブカテゴリーだけが表示されます。
・上のカテゴリーリストより「カスタマイズ」をクリックしてジャンプしたページで表示されるカテゴリーリストです。「カスタマイズ」カテゴリーに関係するサブカテゴリーだけが表示されます。
・上のカテゴリーリストより「折りたたみ」をクリックしてジャンプしたページで表示されるカテゴリーリストです。下位のカテゴリーが存在しないため何も表示されません。
