SuperSortプラグインでの同カテゴリ内の前後エントリーへのリンクの応用

昨日、MTQに以下のような質問があがっていました。

以下のようなことを行いたいです。

  • 個々のブログ記事で、同一カテゴリ内で前後の記事にリンクするようにしたい。
  • 前/後の記事へのリンクの間に、同一カテゴリ内での記事の順序の番号と、全記事数を出力したい。
  • 同一カテゴリ内の最後の記事で「次」のリンクをクリックすると、最初の記事に移動するようにしたい。
  • 同一カテゴリ内の最初の記事で「前」のリンクをクリックすると、最後の記事に移動するようにしたい。

拙作のSuperSortプラグインEntryCategoriesExプラグインを使えば、上記の希望はすべてクリアすることができますので、ご紹介します。

1.並び順の初期化

SuperSortプラグインでは、個々のブログ記事に、同一カテゴリ内での並び順の番号を内部的に振って、ブログ記事を並べ替えています。
また、その並び順の番号を出力することもできます。

並び順を初期化する際に、出力したい並び順の番号に応じて、初期化の方法を選びます。
例えば、古い記事から順に番号を振りたい場合は、ブログ記事の並び順の初期化方法として「ブログ記事の日付順」を選びます。

並び順の初期化

2.同一カテゴリ内の前後の記事へのリンク

SuperSortプラグインでは、同一カテゴリ内の前後の記事の情報を出力するには、MTSortedEntryPrevious/MTSortedEntryNextタグのブロックを使います。
例えば、「Prev」の文字を前の記事へのリンクにしたい場合だと、以下のようにテンプレートを組みます。

<mt:SortedEntryPrevious>
    <a href="<$mt:EntryPermalink$>">Prev</a>
</mt:SortedEntryPrevious>

3.並び順の番号の出力

同一カテゴリ内での並び順の番号は、SuperSortプラグインの「MTEntryOrderNumber」というテンプレートタグで出力することができます。
また、同一カテゴリ内の全ブログ記事数は、MTCategoryCountタグで出力することができます。

ただ、ブログ記事テンプレートにMTCategoryCountタグを直接に書くとエラーになります。
そこで、EntryCategoriesExプラグインの「MTEntryPrimaryCategory」というタグで囲んで、主カテゴリのブログ記事数を出力するようにします。

例えば、「1 / 5」など、「並び順 / 全記事数」のように出力するには、以下のようにタグを組みます。

<$mt:EntryOrderNumber$> / <mt:EntryPrimaryCategory><$mt:CategoryCount$></mt:EntryPrimaryCategory>

4.リング状のリンク

最後の記事で「次」をクリックしたときに、最初の記事に移動する(同様に、最後から最初に移動する)ようにするには、少し工夫が必要です。

一般的には、最初より前の記事は存在しないと考えますし、最後より後の記事も存在しないと考えます。
そのため、最初の記事では、MTSortedEntryPreviousタグのブロックは何も出力しません。
同様に、最後の記事では、MTSortedEntryNextタグのブロックは何も出力しません。

この「何も出力しない」という性質を利用して、最初(または最後)の記事であるかどうかを判断して、処理を分けるようにします。
MTSortedEntryPreviousタグのブロックが何も出力しなかった場合、その記事は最初の記事です。
その時は、最後の記事を読み込んで、その記事へのリンクを出力するようにします。
同様に、MTSortedEntryNextタグのブロックが何も出力しなかった場合、その記事は最後の記事です。
その時は、最初の記事を読み込んで、その記事へのリンクを出力するようにします。

SuperSortプラグインには、「MTSortedEntries」というテンプレートタグがあります。
このテンプレートタグに「sort_order="descend" lastn="1"」のモディファイアを付ければ、最後の記事1件を読み込むことができます。
また、「sort_order="ascend" lastn="1"」のモディファイアを付ければ、最初の記事1件を読み込むことができます。
さらに、MTSortedEntriesタグのブロックをMTEntryPrimaryCategoryタグのブロックで囲めば、記事の主カテゴリと同じカテゴリに属する記事を読み込むことができます。

ここまでの話から、前の記事へのリンク(ただし、最初の記事では最後の記事へのリンク)を出力する部分を作ると、以下のようになります。

<mt:SetVarBlock name="prev_link">
    <mt:SortedEntryPrevious>
        <a href="<$mt:EntryPermalink$>">Prev</a>
    </mt:SortedEntryPrevious>
</mt:SetVarBlock>
<mt:SetVarBlock name="prev_link"><$mt:GetVar name="prev_link" trim="1"$></mt:SetVarBlock>
<mt:If name="prev_link">
    <$mt:GetVar name="prev_link"$>
<mt:Else>
    <mt:EntryPrimaryCategory>
        <mt:SortedEntries sort_order="descend" lastn="1">
            <a href="<$mt:EntryPermalink$>">Prev</a>
        </mt:SortedEntries>
    </mt:EntryPrimaryCategory>
</mt:If>

1~5行目は、前の記事へのリンクを、「prev_link」という名前の変数に代入する処理です。
そして、6行目の文は、変数prev_linkの先頭と最後にあるホワイトスペースを削除する処理です。
この結果、変数prev_linkの値は、前の記事があればその記事へのリンクになり、前の記事がなければ空の文字列になります。

次に、7行目のMTIfタグで、変数prev_linkに値がある(=前の記事がある)かどうかで処理を分けます。
前の記事があれば、変数prev_linkには、1~6行目の処理で前の記事へのリンクが入っています。
したがって、条件が成立して8行目に進み、変数prev_linkの値(=前の記事へのリンク)を出力します。

一方、変数prev_linkに値がない(=前の記事がない)場合は、7行目の条件が成立しないので、9行目のMTElseタグ以降に進みます。
そして、10行目のMTEntryPrimaryCategoryタグと11行目のMTSortedEntriesタグで同一カテゴリの最後の記事を読み込み、12行目でその記事へのリンクを出力します。

同様に、次の記事へのリンク(ただし、次の記事がなければ最初の記事へのリンク)を出力する部分は、以下のようになります。

<mt:SetVarBlock name="next_link">
    <mt:SortedEntryNext>
        <a href="<$mt:EntryPermalink$>">Next</a>
    </mt:SortedEntryNext>
</mt:SetVarBlock>
<mt:SetVarBlock name="next_link"><$mt:GetVar name="next_link" trim="1"$></mt:SetVarBlock>
<mt:If name="next_link">
    <$mt:GetVar name="next_link"$>
<mt:Else>
    <mt:EntryPrimaryCategory>
        <mt:SortedEntries sort_order="ascend" lastn="1">
            <a href="<$mt:EntryPermalink$>">Next</a>
        </mt:SortedEntries>
    </mt:EntryPrimaryCategory>
</mt:If>