カテゴリとフォルダを混合して並べ替えるカスタマイズ - グローバルナビゲーション
目次
Movable Type でカテゴリを並べ替えるには、プラグインを利用したり、カテゴリ名の頭に数字をいれて、カテゴリ名を表示させるときにその数字を取っ払うなど、以下のようないくつかの方法があると思います。
- プラグインを使う
- カテゴリの「説明」欄やカスタムフィールドを利用して並べ替える
- カテゴリ名の頭に <0100> などをいれて並べ替え、remove_html モディファイアで取っ払う
- カテゴリ名の頭に (0100) などを入れて並べ替え、regex_replace モディファイアで取っ払う
今回は、カテゴリ名の頭に数字を入れて並べ替え、regex_replace モディファイアで取っ払う方法をベースに、グローバルナビゲーションを作りました。
ポイントは、「カテゴリもフォルダも混合して並べ替えることができ、サブカテゴリやサブフォルダが何階層になっても大丈夫」なところです。
また、グローバルナビゲーションを「カテゴリ」と「フォルダ」にすることによって、「ブログ公開ディレクトリにあるウェブページ」はグローバルナビゲーションとは別にガイドナビとして使い分けられます。これにより、企業サイトでいえば「サイトマップ」や「プライバシーポリーシー」のような1ページものはグローバルナビゲーションとは別枠のメニューで自動生成することができるというのも便利です。
カテゴリとフォルダの並べ替え
カテゴリとフォルダの頭に「0100_」のように数字をつけて並べ替えます。
このように、頭に数字をつけるカテゴリの並べ替えの方法は、「<0100>」をつけて remove_html="1" で除去する方法もありますが、これだと管理画面側では数字が表示されないというデメリットがあります。
また、「説明」欄に数字を入れて、再構築する際に並べ替える方法もありますが、こちらは管理画面側では並び替えが反映されず、さらに数字も表示もされないデメリットがあります。
その点、頭に「0100_」をつける方法であれば、管理画面側でも並べ替えが反映され、さらに数字も表示され、さらに可読性も良いというメリットがあるのでお勧めです。
完成したソース
まずはじめに、完成したソースを置いておきます。テンプレートの仕組みを分かりやすくするために回りくどい記述があったり、そもそも他にもっといい方法があるかもしれませんが、こんな方法もあるんだということで参考になれば幸いです。でも、これでもかなり試行錯誤して練ってはいます。
<$mt:CategoryLabel$>
<$mt:CategoryLabel$>
<$mt:CategoryLabel$>
<$mt:GetVar name="currentCat" regex_replace="/,.*/",""$>
<$mt:FolderLabel$>
<$mt:GetVar name="currentFld" regex_replace="/,.*/",""$>
<$mt:CategoryLabel$>
<$mt:CategoryLabel regex_replace="/_.+/",""$>
current"> title="<$mt:CategoryDescription$>"><$mt:CategoryLabel$>@subcat@
<$mt:FolderLabel$>
<$mt:FolderLabel regex_replace="/_.+/",""$>
current"> title="<$mt:FolderDescription$>"><$mt:FolderLabel$>@subfld@
解説
では順を追って解説してみます。
現在表示されているページの最上位のカテゴリを記憶
まず最初のブロックで、現在表示されているページが属するトップレベルカテゴリまたはトップレベルフォルダを、それぞれ変数 currentCat 、currentFld に記憶させます。
これは、グローバルナビゲーション上で、現在表示されているページが属するカテゴリに特定のクラス名をつけて、CSS で表示を変えられるようにするためです。
【表示されているページがカテゴリアーカイブの場合】
【そのカテゴリに親カテゴリがある場合】
【最上位の親カテゴリのカテゴリ名を currentCat に代入】
<$mt:CategoryLabel$>
【そのカテゴリに親カテゴリがない場合】
【そのカテゴリのカテゴリ名を currentCat に代入】
<$mt:CategoryLabel$>
【表示されているページがブログ記事の場合】
【そのブログ記事が属するカテゴリをトップレベルから順に「 , 」で区切ってリストアップし、currentCat に代入】
<$mt:CategoryLabel$>
【上で currentCat に代入された値の最初の「 , 」以下を削除してトップレベルのみにして、再度 currentCat に代入】
<$mt:GetVar name="currentCat" regex_replace="/,.*/",""$>
【表示されているページがウェブページの場合】
【そのブログ記事が属するフォルダをトップレベルから順に「 , 」で区切ってリストアップし、currentFld に代入】
<$mt:FolderLabel$>
【上で currentFld に代入された値の最初の「 , 」以下を削除してトップレベルのみにして、再度 currentFld に代入】
<$mt:GetVar name="currentFld" regex_replace="/,.*/",""$>
トップレベルカテゴリをリストアップ
【リストアップされているカテゴリ名を listCat に代入】
<$mt:CategoryLabel$>
【カテゴリを並べ替えるための先頭の数字「0100_」などを gNavKey に代入】
<$mt:CategoryLabel regex_replace="/_.+/",""$>
【配列変数 gNav を作成。
キー : 先ほど「0100_」などを記憶した gNavKey を代入
値 : カテゴリ名
※ここで、「現在表示されているページが属するトップレベルカテゴリ」と「今リストアップされているトップレベルカテゴリ」が同じ場合は、li 要素に class="current" を付けます。(赤字部分)
※さらに、サブカテゴリを持っているトップレベルカテゴリに関しては、行末に「@subcat@」を付けます。(青字部分)
class="current" > title="<$mt:CategoryDescription$>"><$mt:CategoryLabel$>@subcat@
トップレベルフォルダをリストアップ
トップレベルカテゴリをリストアップするときと同様にトップレベルフォルダをリストアップして配列変数 gNav に代入します。
<$mt:FolderLabel$>
<$mt:FolderLabel regex_replace="/_.+/",""$>
class="current"> title="<$mt:FolderDescription$>"><$mt:FolderLabel$>@subfld@
トップレベルカテゴリとトップレベルフォルダを 1 つにまとめる
ここまででリストアップしたトップレベルカテゴリ(変数 gNav )とトップレベルフォルダ(変数 gNav )を、それぞれ mt:Loop タグを使って、まとめて gNav に代入し、配列変数を作成します。
このとき、gNav のキーには gNav と gNav のキー(「0100_」などの数字)を当てます。
<$mt:GetVar name="__value__"$>
<$mt:GetVar name="__value__"$>
トップページへ戻る「HOME」の挿入
グローバルナビゲーションでトップページへ戻る「HOME」は欠かせないでしょうから、最初に記述します。
ホーム
ホーム
グローバルナビゲーションの出力
さて、ここから mt:Loop タグを使って、配列変数 gNav の値を、キーを基準にソートして出力します。このとき、regex_replace モディファイアを使用して、頭の数字とアンダーバーと、トップレベルカテゴリなどをリストアップした時に追加した @subcat@、@subfld@ (サブカテゴリやサブフォルダがあるというマーク)を削除します。
<$mt:GetVar name="__value__" regex_replace="/([0-9]+_)|(@subcat@)|(@subfld@)/g",""$> 続いて、Loop の中で、もし @subcat@ があったら、つまりサブカテゴリを持っていたら、そのサブカテゴリを表示します。
【次の3行で、余分なタグを削除してカテゴリ名だけを catName に代入する】
<$mt:GetVar name="__value__" regex_replace="//",""$>
<$mt:GetVar name="catName" regex_replace="//",""$>
<$mt:GetVar name="catName" regex_replace="/<\/a>@subcat@/",""$>
【そのカテゴリ( catName の値)のサブカテゴリを階層分すべてリストアップする】
title="<$mt:CategoryDescription$>" ><$mt:CategoryLabel regex_replace="/[0-9]+_/",""$><$mt:SubCatsRecurse$>
同様に、フォルダに関してもリストアップします。
<$mt:GetVar name="__value__" regex_replace="//",""$>
<$mt:GetVar name="fldName" regex_replace="//",""$>
<$mt:GetVar name="fldName" regex_replace="/<\/a>@subfld@/",""$>
<$mt:FolderLabel$>
title="<$mt:FolderDescription$>" ><$mt:FolderLabel regex_replace="/[0-9]+_/",""$><$mt:SubFolderRecurse$>
最後に、div や ul で囲って終了です。
まとめ
このグローバルナビゲーション、すこしややこしいソースになってしまいましたが、配列や mt:Loop タグ、条件分岐、regex_replace をうまく使えれば、色々なことが可能になるというのを感じました。
ちなみに、このブログのグローバルナビゲーションは、jQueryの droppy - Nested drop down menusというプラグインを使用しています。
- 【2008-09-05 追記】
- ウェブページに適用させたいときの archive_type モディファイアの値が「 webpage 」になっていたので、「 Page 」に修正しました。
- 【2008-08-20 追記】
ソースの無駄を少し省きました。トップレベルカテゴリ、トップレベルフォルダをリストアップするときに、直接 gNav に代入するようにしました。
最初は、分かりやすいために gNavCat などに一度代入していたのですが、無駄な Loop が増えるのでやめました。