静的生成と動的生成, 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(だったかな?)コールバックが呼ばれた時にそれぞれ「更新」「削除」すれば良いでしょう。
さらに続きはこちら