PHP化したテンプレート間での情報のやりとりにPHPUtilプラグインを活用する

先日、MTQ以下のような質問が上がっていました。

  • 年別アーカイブリストの部分をインデックステンプレートで出力し、他のページからPHPでインクルードしたい
  • ブログ記事および年別アーカイブのページに年別アーカイブリストを組み込む際に、その記事またはアーカイブの年にcurrentのクラスを指定したい

拙作のPHPUtilプラグインを使うと、Movable Typeのテンプレートタグの書き方で、上記のような処理を組むことができます。

1.基本的な考え方

質問された方は、MTIf等のテンプレートタグを使って、ブログ記事や年別アーカイブの年を判断し、currentのクラスを付けようとされていました。
しかし、テンプレートタグが処理されるのは、再構築の時点です。
再構築によって、テンプレートタグの処理が行われ、サーバーにはHTMLのみのファイルが出力されます。

一方、PHPによるインクルードは、ユーザーがページにアクセスした時点で行われます。
そのため、再構築済み(=テンプレートタグ処理済み)のHTMLファイルをインクルードすることになり、期待したような動作にはなりません。
テンプレートをPHP化してインクルードするなら、年の判断はページにアクセスがあった時点でPHPで行う必要があります。

テンプレートにPHPのコードを直接に書いて、条件を判断することもできます。
ただ、Movable Typeのテンプレートの中に、PHPのコードが入っているのは、あまり美しくありません。

そこで、拙作のPHPUtilプラグインを使います。
PHPUtilプラグインでは、PHPでの基本的な処理(変数や条件判断など)を、Movable Typeのテンプレートタグの記法で書くことができます。

今取り上げている例なら、以下のような方法で処理することができます。

  • ブログ記事および年別アーカイブのテンプレートで、記事/アーカイブの年をPHPの変数に代入して、年別アーカイブリストのインデックスのページをインクルードします。
  • 年別アーカイブリストのインデックステンプレートに、記事/アーカイブの年と、個々のアーカイブリストの年とをPHPで比較して、currentのクラスを付ける処理を追加します。

なお、このPHPUtilプラグインでは、MTPHPIncludeタグを使って、あるPHPのページに、他のPHPのファイルをインクルードすることができます。
ただし、この機能を使うには、mt-config.cgiに以下の行を追加する必要があります。

AllowPHPInclude 1

2.ブログ記事/年別アーカイブの書き換え

まず、ブログ記事と年別アーカイブの各アーカイブテンプレートを書き換えて、年をPHPの変数に代入する処理と、年別アーカイブリストのインデックスページをインクルードする処理を追加します。

ブログ記事アーカイブでは、個々の記事の日付はMTEntryDateタグで得ることができます。
ここから年を取り出して、PHPUtilプラグインの「php_setvar」モディファイアで、PHPの変数に代入します。
また、他のページをインクルードする処理は、MTPHPIncludeタグで行うことができます。

個々の記事の年を「current_year」という変数に代入するとします。
また、インクルードするPHPのファイル名が、「yearly_archive.php」だとします。
この場合、ブログ記事テンプレートの中で、年別アーカイブリストを出力したい位置に、以下を追加します。

<$mt:EntryDate format="%Y" php_setvar="cur_year"$>
<$mt:PHPInclude file="yearly_archive.php"$>

また、年別アーカイブテンプレートの中では、個々のアーカイブの年はMTArchiveDateタグで得ることができます。
そこで、年別アーカイブテンプレートの中で、年別アーカイブリストを出力したい位置には、以下を追加します。

<$mt:ArchiveDate format="%Y" php_setvar="cur_year"$>
<$mt:PHPInclude file="yearly_archive.php"$>

3.年別アーカイブリストのインデックステンプレートの書き換え

一方、年別アーカイブリストのインデックステンプレートでは、MTArchiveListタグのブロックでアーカイブの年を順に出力する際に、ブログ記事/年別アーカイブの年と、個々のアーカイブの年を比較して、一致した時だけcurrentのクラスを付けるようにします。

個々のアーカイブの年を、PHPの「archve_year」という変数に代入するとします。
また、クラシックブログのテーマを使っているとします。
この場合だと、年別アーカイブリストのインデックステンプレートを以下のように組みます。

<mt:IfArchiveTypeEnabled archive_type="Yearly">
    <mt:ArchiveList archive_type="Yearly">
        <$mt:ArchiveDate format="%Y" php_setvar="archive_year"$>
        <mt:ArchiveListHeader>
<div class="widget-archive-monthly widget-archive widget">
    <h3 class="widget-header"><$mt:ArchiveTypeLabel$> <a href="<$mt:Link template="archive_index"$>">アーカイブ</a></h3>
    <div class="widget-content">
        <ul>
        </mt:ArchiveListHeader>
<mt:PHPIf name="archive_year" eq="{$cur_year}">
            <li class="current"><a href="<$mt:ArchiveLink$>"><$mt:ArchiveTitle$> (<$mt:ArchiveCount$>)</a></li>
<mt:PHPElse>
            <li><a href="<$mt:ArchiveLink$>"><$mt:ArchiveTitle$> (<$mt:ArchiveCount$>)</a></li>
</mt:PHPIf>
        <mt:ArchiveListFooter>
        </ul>
    </div>
</div>
        </mt:ArchiveListFooter>
    </mt:ArchiveList>
</mt:IfArchiveTypeEnabled>

この中で重要のは、以下の各行です。

3行目

php_setvarモディファイアを使って、個々のアーカイブの年(MTArchiveDateタグ)を、PHPの変数archive_yearに代入します。

10行目/14行目

MTPHPIfタグのブロックを使って、変数archive_year(個々のアーカイブの年)と、変数cur_year(ブログ記事/年別アーカイブの年)が一致しているかどうかを判断します。
なお、MTIfタグで変数どうしを判断する場合、判断先の変数は「モディファイア="$変数名"」で表しました。
一方、MTPHPIfタグでPHPの変数どうしを判断する場合、判断先の変数は「モディファイア="{$変数名}"」と表します。

11行目

10行目の条件が成立した時には、11行目によって、li要素に「current」のクラスを付加して出力します。

12行目/13行目

10行目の条件が成立しなかった場合は、12行目のMTPHPElseタグのブロックが処理されます。
その結果、13行目のcurrentなしのli要素が出力されます。