Movable Typeのフォルダリストで特定のフォルダを表示しない方法
Movable Typeのフォルダリストで特定のフォルダ(またはフォルダ)を表示しない方法を紹介します。このカスタマイズはカテゴリにも適用可能です。
1.カスタマイズイメージ
このエントリーでは次の条件のカスタマイズを行います。
- 2階層のフォルダに1つ以上のウェブページが属する
- フォルダリストではサブフォルダを表示しない
- ウェブページのカスタムフォールドを使って、フォルダリスト上のフォルダの表示・非表示を制御
以下、具体的なカスタマイズ例です。
トップレベルフォルダが国名、サブフォルダが首都名で、サブフォルダの中にウェブページがひとつずつ入ってるフォルダリスト(カスタマイズ前)があります。
カスタマイズ前

まず、このフォルダリストからサブフォルダをすべて非表示にします。
サブフォルダを非表示

次に、各ウェブページには「foo」というカスタムフィールドがあり、fooに値を設定していない場合は、ウェブページとウェブページが属する親フォルダをすべて非表示にします。
例えば、上の一覧で「ソウル」ウェブページのfooに値が設定されていない場合、次のように「韓国」フォルダと「ソウル」ウェブページを非表示します。
特定のフォルダとウェブページを非表示

順不同リストのマークアップもvalidな内容で出力します。
2.サブフォルダを表示しないカスタマイズ
フォルダリストですべてのサブフォルダを表示しないようにするには、次のサブテンプレートを使用します。
<mt:TopLevelFolders>
<mt:SubCatIsFirst>
<mt:HasParentFolder>
<mt:else>
<ul>
</mt:HasParentFolder>
</mt:SubCatIsFirst>
<mt:HasParentFolder>
<mt:else>
<li><$mt:FolderLabel$>
</mt:HasParentFolder>
<mt:Pages>
<mt:PagesHeader>
<ul>
</mt:PagesHeader>
<li><mt:PageTitle></li>
<mt:PagesFooter>
</ul>
</mt:PagesFooter>
</mt:Pages>
<$mt:SubFolderRecurse$>
<mt:HasParentFolder>
<mt:else>
</li>
</mt:HasParentFolder>
<mt:SubCatIsLast>
<mt:HasParentFolder>
<mt:else>
</ul>
</mt:HasParentFolder>
</mt:SubCatIsLast>
</mt:TopLevelFolders>
青色の部分がサブフォルダを非表示にするための制御で、MTHasParentFolderタグで親フォルダがない場合、つまりトップレベルのフォルダのみ表示するようにしています。
3.特定のフォルダとウェブページを表示しないカスタマイズ
フォルダリストで、ウェブページのカスタムフィールド「foo」に値が入っていないフォルダとウェブページを非表示にするには、次のサブテンプレートを使用します。赤色は2項から追加した部分です。
<mt:TopLevelFolders>
<mt:Pages>
<mt:unless tag="foo">
<$mt:PageTitle setvar="pages" append="1"$>
<mt:TopLevelFolder>
<$mt:FolderLabel setvar="label"$>
<$mt:SetVar name="folders" value="$label" append="1"$>
<mt:SubFolders>
<$mt:FolderLabel setvar="label"$>
<$mt:SetVar name="folders" value="$label" append="1"$>
</mt:SubFolders>
</mt:TopLevelFolder>
</mt:unless>
</mt:Pages>
<$mt:SubFolderRecurse$>
</mt:TopLevelFolders>
<mt:TopLevelFolders>
<$mt:FolderLabel setvar="folder"$>
<mt:SubCatIsFirst>
<mt:unless name="folders" like="$folder">
<mt:HasParentFolder>
<mt:else>
<ul>
</mt:HasParentFolder>
</mt:unless>
</mt:SubCatIsFirst>
<mt:unless name="folders" like="$folder">
<mt:HasParentFolder>
<mt:else>
<li><$mt:FolderLabel$>
</mt:HasParentFolder>
</mt:unless>
<mt:unless name="folders" like="$folder">
<mt:Pages>
<mt:PagesHeader>
<ul>
</mt:PagesHeader>
<li><mt:PageTitle></li>
<mt:PagesFooter>
</ul>
</mt:PagesFooter>
</mt:Pages>
</mt:unless>
<$mt:SubFolderRecurse$>
<$mt:FolderLabel setvar="folder"$>
<mt:unless name="folders" like="$folder">
<mt:HasParentFolder>
<mt:else>
</li>
</mt:HasParentFolder>
</mt:unless>
<mt:SubCatIsLast>
<mt:unless name="folders" like="$folder">
<mt:HasParentFolder>
<mt:else>
</ul>
</mt:HasParentFolder>
</mt:unless>
</mt:SubCatIsLast>
</mt:TopLevelFolders>
4.サブテンプレートの流れ
サブテンプレートの大きな流れは次の通りです。
- 1回目のフォルダ一覧の繰り返し処理でfooに値が設定されていないウェブページをみつけ、その上位フォルダ(すべて)を変数foldersに保持。ウェブページタイトルも変数pagesに保持。
- 2回目のフォルダ一覧の繰り返し処理で、変数foldersをチェックし、該当フォルダの処理になった時点でトップレベルフォルダを表示しないよう制御
以下、ブロック別に処理を解説します。
5.フォルダ情報の取得
次のMTTopLevelFoldersタグで、1回目のフォルダ一覧の繰り返し処理を行います。
<mt:TopLevelFolders>
<mt:Pages>
<mt:unless tag="foo">
<mt:TopLevelFolder>
<$mt:FolderLabel setvar="label"$>
<$mt:SetVar name="folders" value="$label" append="1"$>
<mt:SubFolders>
<$mt:FolderLabel setvar="label"$>
<$mt:SetVar name="folders" value="$label" append="1"$>
</mt:SubFolders>
</mt:TopLevelFolder>
</mt:unless>
</mt:Pages>
<$mt:SubFolderRecurse$>
</mt:TopLevelFolders>
MTUnlessタグでfooに値がない場合のみ、MTTopLevelFolderタグでトップレベルフォルダのフォルダ名と、MTSubFoldersでその次のフォルダのフォルダ名を変数foldersに保持します。
6.ul開始タグの出力
次のMTTopLevelFoldersタグで、2回目のフォルダ一覧の繰り返し処理を行います。最初にul開始タグの出力部分から解説します。
<mt:TopLevelFolders>
<$mt:FolderLabel setvar="folder"$>
<mt:SubCatIsFirst>
<mt:unless name="folders" like="$folder">
<mt:HasParentFolder>
<mt:else>
<ul>
</mt:HasParentFolder>
</mt:unless>
</mt:SubCatIsFirst>
MTFolderLabelタグで処理中のフォルダ名を変数folderに保持します。MTSubCatIsFirstタグ内の中のMTUnlessタグで、変数folderと1回目のフォルダ一覧の繰り返し処理で設定した変数foldersを比較し、一致するフォルダ名がなければ、さらに親フォルダの有無を判定し、トップレベルフォルダであればul要素を出力します。
7.li要素の開始タグとフォルダ名の出力
次の部分でli要素の開始タグとフォルダ名の出力を行います。変数folderと変数foldersを比較し、一致するフォルダ名がなければフォルダ名を出力します。一致するフォルダ名がある場合でも、MTHasParentFolderで判定し、サブフォルダであればフォルダ名を出力します。これは「アメリカ」フォルダを出力せず、「ニューヨーク」フォルダを出力させるためです。
<mt:unless name="folders" like="$folder">
<mt:HasParentFolder>
<mt:else>
<li><$mt:FolderLabel$>
</mt:HasParentFolder>
</mt:unless>
8.ウェブページタイトル出力
ウェブページタイトルは、処理中のフォルダ(変数folder)と変数foldersを比較し、一致するフォルダ名がなければ出力します。
<mt:unless name="folders" like="$folder">
<mt:Pages>
<mt:PagesHeader>
<ul>
</mt:PagesHeader>
<li><mt:PageTitle></li>
<mt:PagesFooter>
</ul>
</mt:PagesFooter>
</mt:Pages>
</mt:unless>
9.li終了タグの出力
再帰処理用のMTSubFolderRecurseの後にli終了タグの出力制御を行っています。
<$mt:FolderLabel setvar="folder"$>
<mt:unless name="folders" like="$folder">
<mt:HasParentFolder>
<mt:else>
</li>
</mt:HasParentFolder>
</mt:unless>
先程と同様、変数folderと変数foldersを比較し、一致するフォルダ名がなければさらに親フォルダの有無を判定し、トップレベルフォルダであればli要素の終了タグを出力します。
10.ul終了タグの出力
最後にul終了タグの出力制御を行います。MTSubCatIsLastタグ内の中のMTUnlessタグで、変数folderと1回目のフォルダ一覧の繰り返し処理で設定した変数foldersを比較し、一致するフォルダ名がなければ、さらに親フォルダの有無を判定し、トップレベルフォルダであればul要素の終了タグを出力します。
<mt:SubCatIsLast>
<mt:unless name="folders" like="$folder">
<mt:HasParentFolder>
<mt:else>
</ul>
</mt:HasParentFolder>
</mt:unless>
</mt:SubCatIsLast>
</mt:TopLevelFolders>
11.サブフォルダを出力したい場合
3項のサブテンプレートは、2項の「サブフォルダを出力しないカスタマイズ」を含んでます。
「特定のフォルダとウェブページは表示したくないけど、表示するフォルダについてはサブフォルダも出力したい」という場合は、3項のサブテンプレートから青色のタグをすべて除去してください。
フォルダアーカイブとフォルダアーカイブ一覧を作る
Movable Type 4.2 でフォルダアーカイブとフォルダアーカイブ一覧を作るカスタマイズを紹介します。
Movable Type 4.2 標準の機能ではフォルダアーカイブを作成することができません。将来的に機能追加されるかもしれませんが、ここではプラグインを利用して Movable Type 4.2 でフォルダアーカイブページを作成する方法を紹介します。
次のようなフォルダとウェブページの構成を想定します。
フォルダ1
├ ウェブページ1-1
├ ウェブページ1-2
└ ウェブページ1-3
フォルダ2
├ ウェブページ2-1
├ ウェブページ2-2
└ ウェブページ2-3
この構成であれば、フォルダアーカイブには、次のようにフォルダに属するウェブページの一覧を表示することができます。
フォルダ1のフォルダアーカイブページ

フォルダ2のフォルダアーカイブページ

サブフォルダがある場合も、独立したアーカイブページとして作成可能です。
フォルダアーカイブの作成に伴い、フォルダアーカイブページへのリンク(フォルダ一覧)の作成方法もあわせて説明します。

1.フォルダアーカイブの作成
フォルダアーカイブの作成は、The blog of H.Fujimoto の藤本壱さんが作成された WriteToFile プラグインを利用します。
1.1 WriteToFile プラグインのダウンロード
下記のページより、WriteToFile プラグインをダウンロードしてください。
The blog of H.Fujimoto - テンプレートの再構築結果を部分的にファイルに出力するプラグイン
ダウンロードしたプラグインアーカイブを展開し、plusins ディレクトリにアップロードします。
プラグインの一覧で「WriteToFile」が表示されれば OK です。

1.1 フォルダアーカイブ用テンプレートの作成
フォルダアーカイブ用テンプレートはインデックステンプレートで作成します。
ブログ管理画面の「デザイン」→「テンプレート」で「インデックステンプレートを作成する」をクリック。

表示されたテンプレート作成画面で、次の内容を設定。
- テンプレートの名前
- フォルダアーカイブ(何でも構いません)
- テンプレートの内容
- ご利用のメインページの内容をそのままコピー&ペースト。
- ファイル名
- dummy.dat(このファイルはダミーなので使いません)
- その他
- 変更せずそのまま
1.2 フォルダアーカイブ用テンプレートの修正1
フォルダアーカイブ用テンプレートの先頭と末尾に、テンプレートタグ(青色部分)を追加します。
<MTTopLevelFolders>
<MTSetVarBlock name="fname"><MTFolderPath>/index.html</MTSetVarBlock>
<MTWriteToFile file="$fname">
[1.1項でペーストしたメインページの内容]
</MTWriteToFile>
<MTSubFolderRecurse>
</MTTopLevelFolders>
1.3 フォルダアーカイブ用テンプレートの修正2
テンプレート内にある MTEntries タグを MTPages タグに変更します。
配布テンプレート
変更前(赤色を削除)
...前略...
<div id="content">
<div class="blog">
<mt:entries>
<mt:entryTrackbackData />
<mt:include module="ブログ記事の概要" />
</mt:entries>
</div>
</div>
...後略...
変更後(青色を追加)
...前略...
<div id="content">
<div class="blog">
<mt:Pages>
<mt:PagesHeader>
<h2 class="date"><$MTFolderLabel$>のウェブページ一覧</h2>
<div class="entry">
<ul>
</mt:PagesHeader>
<li><a href="<$MTPagePermalink$>"><$MTPageTitle$></a></li>
<mt:PagesFooter>
</ul>
</div>
</mt:PagesFooter>
</mt:Pages>
</div>
</div>
...後略...
完成例

既定のブログ
変更前(赤色を削除)
...前略...
<div id="alpha">
<div id="alpha-inner">
<mt:Entries>
<mt:Ignore><!-- Use the Entry Summary module for each entry published on this page --></mt:Ignore>
<$mt:Include module="ブログ記事の概要"$>
</mt:Entries>
<div class="content-nav">
<a href="<$mt:Link template="archive_index"$>">アーカイブ</a>
</div>
</div>
</div>
...後略...
変更後(青色を追加)
...前略...
<div id="alpha">
<div id="alpha-inner">
<mt:Pages>
<mt:PagesHeader>
<h2 class="archive-title"><$MTFolderLabel$>フォルダの一覧</h2>
<ul>
</mt:PagesHeader>
<li><a href="<$MTPagePermalink$>"><$MTPageTitle$></a></li>
<mt:PagesFooter>
</ul>
</mt:PagesFooter>
</mt:Pages>
<div class="content-nav">
<a href="<$mt:Link template="archive_index"$>">アーカイブ</a>
</div>
</div>
</div>
...後略...
完成例

設定が完了したら再構築してください。
再構築でエラーが発生した場合、4項に該当していないか確認してください。
2.フォルダアーカイブ一覧の作成
下記のサブテンプレートをウィジェットで作成します。ただしフォルダアーカイブに表示させる場合はインデックステンプレートで作成して、モジュール化を行ってください(理由は3項参照)。
配布テンプレートの場合
<mt:ifArchiveTypeEnabled archive_type="Page">
<mt:if tag="blogPageCount">
<dt class="sidetitle">フォルダ一覧</dt>
<dd class="side">
<mt:topLevelFolders>
<mt:folderHeader>
<ul>
</mt:folderHeader>
<li><a href="<mt:blogURL /><mt:folderPath />/index.html"><mt:folderLabel /></a> [<mt:folderCount />]
<mt:subFolderRecurse />
</li>
<mt:folderFooter>
</ul>
</mt:folderFooter>
</mt:topLevelFolders>
</dd>
</mt:if>
</mt:ifArchiveTypeEnabled>
完成例

既定のブログの場合
<mt:IfArchiveTypeEnabled archive_type="Page">
<div class="widget-pages widget">
<h3 class="widget-header">フォルダ一覧</h3>
<div class="widget-content">
<mt:TopLevelFolders>
<mt:folderHeader>
<ul>
</mt:folderHeader>
<li class="folder folder-<$mt:FolderID$>"><a href="<mt:blogURL /><mt:folderPath />/index.html"><mt:folderLabel /></a> [<mt:folderCount />]
<$mt:SubFolderRecurse$>
</li>
<mt:folderFooter>
</ul>
</mt:folderFooter>
</mt:TopLevelFolders>
</div>
</div>
</mt:IfArchiveTypeEnabled>
完成例

3.注意事項1
MTWriteToFile タグの中にカテゴリーリストやフォルダリストのサブテンプレートがあると、そこにある MTSubCatsRecurse や MTSubFolderRecurse タグが干渉して、サブフォルダのアーカイブが作成されないようです。
フォルダリストにカテゴリーリストやフォルダリストを含める場合はカテゴリーリストやフォルダリストをインデックステンプレートでモジュール化してください。
インデックステンプレートで作成したフォルダリストの出力ファイル名を folder.html とした場合、例えば次の方法で表示できます。PHP化する必要はありません。
<mt:BlogSitePath cat="folder.html" setvar="folder" />
<mt:include file="$folder" />
4.注意事項2
ウェブページのないフォルダがあると、フォルダアーカイブの再構築で次のようなエラーが発生します。

サイトマップを作る for Movable Type 4
Movable Type 4 で新しく追加されたフォルダとウェブページを使って、ウェブサイト内の構成を俯瞰する、いわゆる「サイトマップ」を作成する方法を紹介します。
上のサイトマップのサンプルは、「フォルダx」がフォルダ名、「ウェブページx」がフォルダ配下に配置されたウェブページを示しています。フォルダの下にあるサブフォルダおよびウェブページは階層化表示されます。
下のタグをテンプレートの任意の位置に貼り付ければ上記のようなサイトマップが表示されます。
フォルダ名は「フォルダのパス」ではなく「フォルダの名前」を表示するようにしています。
<MTTopLevelFolders>
<MTSubCatIsFirst>
<ul>
</MTSubCatIsFirst>
<MTIfNonZero tag="MTFolderCount">
<li><$MTFolderLabel$>
<ul>
<MTPages>
<li><a href="<$MTPagePermalink$>" title="<$MTPageTitle$>"><$MTPageTitle$></a></li>
</MTPages>
</ul>
</MTIfNonZero>
<MTSubFolderRecurse>
</li>
<MTSubCatIsLast>
</ul>
</MTSubCatIsLast>
</MTTopLevelFolders>
フォルダ関連タグはサブカテゴリー関連タグと同じなので、サブカテゴリー関連タグが理解できていれば比較的簡単に扱えるでしょう。
なお、フォルダにはMTSubCatIsFirst/MTSubCatIsLastに対応するタグがないため、サブカテゴリー用のタグで代用しています。
