静的生成と動的生成, Webページをビルドするコストは最初の訪問者に支払ってもらいましょう(続き)。
公開日 : 2007-06-26 12:26:07
追記(2007年6月29日):
一連のエントリーで作成したものを取りまとめて公開しました。
もうちょっとだけやります。えーっと必要な方は是非完成させてください(で、完成させたら僕にください!)。前回のエントリーの続き。
さらに続きまで書いてしまった...
先のエントリーで何だか面倒だったのがbasenameからentryを検索するところ。File:: Basenameを使うともう少し楽か...。ただbasenameは一意な値じゃないからやっぱり検索は非効率です。
そこで、データベースを拡張することにします(実は本題はここだったりする)。
Movable Type10分間Cooking!
データベースにmt_permalinkというテーブルを追加し MT::Objectのサブクラスを作成して利用します。
| permalink_id | int(11) | entry_idと対応したユニークな数字 | 
|---|---|---|
| permalink_blog_id | int(11) | ブログID | 
| permalink_permalink | varchar(255) | URL(Permalink) | 
| (追加) permalink_modified_on | timestamp | 更新日時 | 
データベースはMySQL。もちろんPostgreSQLでもSQLiteでも良いです(そこがMTの特長)。
CREATE TABLE `mt_permalink` (
  `permalink_id` int(11) NOT NULL,
  `permalink_blog_id` int(11) NOT NULL,
  `permalink_permalink` varchar(255) collate utf8_unicode_ci NOT NULL,
  `permalink_modified_on` timestamp NULL default CURRENT_TIMESTAMP,
  UNIQUE KEY `permalink_id` (`permalink_id`),
  KEY `permalink_blog_id` (`permalink_blog_id`),
  KEY `permalink_modified_on` (`permalink_modified_on`),
  KEY `permalink_permalink` (`permalink_permalink`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;続いて MT::Objectのサブクラス「MT::Permalink」を作成。
Permalink.pm として mtディレクトリの lib/MT/ 以下に置きます。(mt/lib/MT/Permalink.pm)
package MT::Permalink;
use strict;
@MT::Permalink::ISA = qw( MT::Object );
__PACKAGE__->install_properties({
	column_defs => {
		'id' => 'integer not null',
		'blog_id' => 'integer not null',
		'permalink' => 'string(255)',
		'modified_on' => 'integer',
	},
	indexes => {
		blog_id => 1,
		permalink => 1,
		modified_on => 1,
	},
	child_of => 'MT::Blog',
	datasource => 'permalink',
	primary_key => 'id',
});
1;これで下準備OK。エントリーのpermalink, id, blog_id をデータベースに登録するスクリプトを書いてシェルから実行。
#!/usr/bin/perl -w
use strict;
use lib qw (/path/to/mt/lib/);
use lib qw (/path/to/mt/extlib/);
use MT;
use MT::Entry;
use MT::Permalink;
my $mt = MT->new(Config => '/path/to/mt/mt-config.cgi');
my $blog_id = 3;
my $iter = MT::Entry->load_iter({
	blog_id => $blog_id,
	status => 2 },{
	sort => 'modified_on',
	direction => 'descend',
});
while (my $entry = $iter->()) {
	my $permalink = MT::Permalink->new;
	$permalink->id($entry->id);
	$permalink->blog_id($entry->blog_id);
	$permalink->permalink($entry->permalink);
	$permalink->modified_on($entry->modified_on);
	$permalink->save;
}phpMyAdminで確認する。
ちゃんと入っているな。
これで, 前回のmtview.cgiの前半部分がすっきりして無駄な検索処理もなくなる。
my $request = $ENV{"REDIRECT_URL"};
my $url = $base_url.$request;
my $blog = MT::Blog->load({ id => $blog_id });
my $permalink = MT::Permalink->load({permalink => $url});
if (defined $permalink) {
	my $entry = MT::Entry->load({id => $permalink->id});
	if (defined $entry) {
...新しいテーブルを作るのは面倒...な場合はサイトの運用にあわせて使っていないフィールド(entry_keywordsとか)に対してINDEX指定しておいてpermalinkを放り込んでおくという手もあるか。まぁ本来の? 使い方ではない方法で拡張するのは気持ち悪いし、MT::Objectのサブクラスの作成, 利用方法を理解していると何かと便利。SQL文を書かなくて良い(データベースの種類にかかわらず同じ書き方ができる)ところがMTのGoodなところ。
今回は本当に10分間クッキング。でもやっぱりエントリー書くのに15分かかった...
MT::Objectについては以下のページを参照くださいませ。
残りタスク
前回の残りタスクも放ったらかしですが, mt_permalinkを作ったのでエントリーを追加したり削除したりした場合にデータベースも更新しないといけない。これはプラグインで書くことになります。post_save_entry, post_delete_entry(だったかな?)コールバックが呼ばれた時にそれぞれ「更新」「削除」すれば良いでしょう。
さらに続きはこちら
