印刷用表示へ切り替え 通常表示へ切り替え 更新履歴を表示 更新履歴を隠す
MovableType 長年日記を PHP で実装する

Movable Type の日別アーカイブを tDiary 風の長年日記にするカスタマイズを PHP で実装する。

■ ■ ■

はじめに

このブログは作者の予想以上に長く続いてしまい,記事数は800を超えた。記事数の増加にともない,再構築に時間がかかるようになってきた。現在のサーバの CPU の周波数は 1 GHz だが,先日 200 MHz に落ちていた際には,全ての記事の再構築に 24 時間以上かかるという異常事態が発生。1つの記事の再構築でも10分以上かかるため,戻ってこなくなってしまった。しかし,よく考えてみれば Movable Type 2.661 ではこのくらいの記事数では問題ないはずである。問題は,再構築に時間がかかるようなカスタマイズを多くやってしまっているということだ。

再構築の時間を引き延ばしているカスタマイズは,日別アーカイブを tDiary 風にする「長年日記」である (nlog(n): Movable Type で長年日記)。このカスタマイズでは,1日分の日別アーカイブを再構築するだけのために,全ての記事の日付をチェックする。当然,記事が多くなればなるほど時間がかかるようになる。

そこで,多少不本意ではあるが,日別アーカイブを部品化して PHP で動的に読み込むように変更することにした。これまでは,記事はすべて静的に作ることにしていたので,PHP に頼るというのが不本意なのだ。しかし,背に腹は代えられない。背を腹に代えて,前も後も腹にしてしまえば背骨がなくなって背が縮むというスルドい手もあるが,そうなるともう何がなんだかで本末転倒なのでヤメ。

「長年日記」とは,前年以前の同じ日の日記を一度に参照できるページを生成する機能のことである(tDiary.org - 「長年日記」をmain trunkにマージ)。

環境

環境は Movable Type 2.661 + 日本語パッチ(nlog(n): MovableType 2.661),PHP 5.2.0 である。ファイルの拡張子は .html のまま PHP スクリプトが動作するように設定しているが(nlog(n): 拡張子を変更せずに MT を PHP 化),これは本質に関係することではない。

前提条件としては,日別アーカイブと月別アーカイブのテンプレートを分けてあることである(nlog(n): Movable Type で長年日記)。以下では,日別アーカイブテンプレートを修正していく。

方針

方針は次の通り。

MTEntries 部分を分離
MTEntries 部分を分離


日別アーカイブテンプレートから,MTEntries 部分を抜き出し,

生成されたファイルを PHP で読んで表示
生成されたファイルを PHP で読んで表示


抜き出したテンプレートからファイルを生成して,これを動的に読み込むようにする。

  1. 日別アーカイブテンプレートから,MTEntries 部分を削除する (「表示用日別アーカイブテンプレート」と呼ぶ)
  2. MTEntries 部分だけからなる日別アーカイブテンプレートを新規に作成する (「部品用日別アーカイブテンプレート」と呼ぶ)
  3. 部品用日別アーカイブテンプレートを再構築し,ファイルを生成する
  4. 生成されたファイルを,表示用日別アーカイブテンプレートで,PHP により動的に読み込んで表示する

テンプレート名と生成されるファイル名との対応は以下の通りとする。

テンプレート名 生成したファイルの場所と名前
Daily Archive
(表示用日別アーカイブテンプレート)
archives/YYYY_MM_DD.html
Daily Archive Abstract
(部品用日別アーカイブテンプレート)
archives/abstract/YYYY_MM_DD.html

つまり,ファイル名の形式が決まっていれば,必要なファイルは PHP で簡単にピックアップできるという性質を利用する訳である。全ての記事の日付をチェックする必要はなくなり,再構築の時間が短縮される。部品化したファイルを月別アーカイブにも使えば,さらに再構築の時間は短くできる。

さらに細かくは,色付けの設定を次のように行う。具体的には,対象となっている年の blogbody クラスに,1つクラスを追加し色づけすることにする。表示用の日別アーカイブでは,複数年の同じ日付の記事が並ぶことになる。それらの記事のうち,対象となる年の色だけを変更する。方針としては,各部品に「yearYYYY」の形のクラスをつけておき,表示をする際にこのクラスの名称を変更する。対象となる年のクラスを「thisyear」クラスにし,他の年の「yearYYYY」クラスは削除する。

  1. 部品用の日別アーカイブでは,blogbody クラスに「year2007」など「yearYYYY」形式のクラスを追加する
  2. 表示用の日別アーカイブでは,部品アーカイブを読み込み,表示の際に「year2007」のクラスの名称を変更する
    • 対象となっている年の場合「yearYYYY」→「thisyear」
    • 対象となっていない年の場合「yearYYYY」→削除

部品用日別アーカイブの作成

部品用の日別アーカイブを新規に作成する。これまで使っていた日別アーカイブの <MTEntries> から </MTEntries> までをコピーし,アーカイブとして保存する。テンプレートの名前は何でもよく,例えば「Daily Archive Abstract」としておく(本文のうち,概要(abstract)だけが書かれているという意味)。

blogbody の div には次のように書いておく。

<div class="blogbody <$MTEntryDate format="year%Y"$>">

再構築すると,「<div class="blogbody year2007">」などとなる。

テンプレートの修正が終わったら,このテンプレートを日別アーカイブとして関連付ける。「ブログの設定」→「アーカイブの設定」で,アーカイブファイルのテンプレートを「Daily」として追加し,「アーカイブファイルのテンプレート」欄には「abstract/<$MTArchiveDate format="%Y_%m_%d.html"$>」と書いておく。アーカイブを再構築すると,archives/abstract/2007_03_20.html」などの静的ファイルが生成される。

スタイルシートの修正

スタイルシートを修正して,色づけのための thisyear クラスを追加する(nlog(n): Movable Type で長年日記)。

.thisyear { background-color: #D7D4FF; }

これは thisyear のような色である。

表示用日別アーカイブテンプレートの修正

PHP でアクセスできるかのテスト

生成されたファイルが読めるかどうかを,簡単なコードでテストする。表示用日別アーカイブテンプレートを開き,削除した MTEntries の部分に次のコードを書いて再構築する。色づけのことを考えなければ,このコードでよい。

<?php
$thisday = '<$MTArchiveDate format="%m_%d"$>';
$files = glob("abstract/????_" . $thisday . "*.html");
rsort($files);
foreach($files as $file){
  include($file);
}
?>

目的の動作をする PHP のコード

正しく表示できることを確認したら,上のコードを本番のコードで置き換える。

<?php
$thisday = '<$MTArchiveDate format="%m_%d"$>';
$thisyear = '<$MTArchiveDate format="%Y"$>';
$search = '<div class="blogbody year';
$searchmore = '<div class="blogbody year' . $thisyear . '">';
$replacethis = '<div class="blogbody thisyear">';
$replacenone = '<div class="blogbody">';
$files = glob("abstract/????_" . $thisday . "*.html");
rsort($files);
foreach ($files as $file) {
  foreach (file($file) as $line) {
    if (ereg($search, $line)) {
      if (ereg($searchmore, $line)) {
        $line = str_replace($searchmore, $replacethis, $line);
      } else {
        $line = $replacenone;
      }
    }
    echo $line;
  }
}
?>

再構築して,色づけができていることを確認すれば完了である。

その他のバリエーション

yearYYYY クラスの色を決めて,削除せずに残していくというバリエーションもある。

<?php
$thisday = '<$MTArchiveDate format="%m_%d"$>';
$thisyear = '<$MTArchiveDate format="%Y"$>';
$search = '<div class="blogbody year' . $thisyear . '">';
$replace = '<div class="blogbody thisyear">';
$files = glob("abstract/????_" . $thisday . "*.html");
rsort($files);
foreach ($files as $file) {
  foreach (file($file) as $line) {
    $line = str_replace($search, $replace, $line);
    echo $line;
  }
}
?>

スタイルシートには,yearYYYY クラスを書いておく。例えば,thisyear, year2004, year2005, year2006, year2007 のようなグラデーションにするという手もある。

.thisyear { background-color: #D7D4FF; }
.year2004 { background-color: #ECFFFF }
.year2005 { background-color: #E3FFFF }
.year2006 { background-color: #D7FFFF }
.year2007 { background-color: #C8FFFF }

年の色というのを決めて,サイト全体で統一するというのもいいかも。

Posted by n at 2007-03-20 22:59 | Edit | Comments (0) | Trackback(1)
Trackbacks

  • 「手違いで複数トラックバックを送ってしまった!」という場合でも気にしないでください (重複分はこちらで勝手に削除させていただきます)
  • タイムアウトエラーは,こちらのサーバの処理能力不足が原因です (詳細は トラックバック送信時のエラー をご覧ください)
  • トラックバックする記事には,この記事へのリンクを含めてください(詳細は 迷惑トラックバック対策 をご覧ください)
Movable Typeについて
過去記事 2007: 長年日記を PHP で実装する 再構築の時間を引き延ばしているカスタマイズは,日別アーカイブを tDiary 風にする「長年日記」である ... Trackbacked from: WordPressとか at March 22, 2009 01:43
Comments
Post a comment
  • 電子メールアドレスは必須ですが,表示されません (気になる場合は「メールアドレスのような」文字列でもOKです)
  • URL を入力した場合はリンクが張られます
  • コメント欄内ではタグは使えません
  • コメント欄内に URL を記入した場合は自動的にリンクに変換されます
  • コメント欄内の改行はそのまま改行となります
  • 「Confirmation Code」に表示されている数字を入力してください (迷惑コメント対策です)


(必須, 表示されます)


(必須, 表示されません)


(任意, リンクされます)


Confirmation Code (必須)


Remember info (R)?