アルファサード株式会社 代表取締役 野田 純生のブログ


静的生成と動的生成, Webページをビルドするコストは最初の訪問者に支払ってもらいましょう(続き)。


公開日 : 2007-06-26 12:26:07


追記(2007年6月29日):
一連のエントリーで作成したものを取りまとめて公開しました。


もうちょっとだけやります。えーっと必要な方は是非完成させてください(で、完成させたら僕にください!)。前回のエントリーの続き。

さらに続きまで書いてしまった...

先のエントリーで何だか面倒だったのがbasenameからentryを検索するところ。File:: Basenameを使うともう少し楽か...。ただbasenameは一意な値じゃないからやっぱり検索は非効率です。

そこで、データベースを拡張することにします(実は本題はここだったりする)。

Movable Type10分間Cooking!

データベースにmt_permalinkというテーブルを追加し MT::Objectのサブクラスを作成して利用します。

テーブル:mt_permalinkの構造
permalink_idint(11)entry_idと対応したユニークな数字
permalink_blog_idint(11)ブログID
permalink_permalinkvarchar(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で確認する。

テーブル:mt_perm/online/2007/06/26/permalink.jpg

ちゃんと入っているな。
これで, 前回の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(だったかな?)コールバックが呼ばれた時にそれぞれ「更新」「削除」すれば良いでしょう。

さらに続きはこちら



このブログを書いている人
野田純生の写真
野田 純生 (のだ すみお)

大阪府出身。ウェブアクセシビリティエバンジェリスト。 アルファサード株式会社の創業者であり、現役のプログラマ。経営理念は「テクノロジーによって顧客とパートナーに寄り添い、ウェブを良くする」。 プロフィール詳細へ