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


CMSと静的ファイル管理に関する考察の続き。


公開日 : 2007-04-28 16:55:47


こちら↑の続き。考察だけじゃなんだから少し実証もしてみよう。 せっかくゴールデンウィークだし...

そないに難しく考えずにファイル構築の際にページの文字列まるごととアドレスをデータベースに保存してmod_rewriteで動的に処理させればよいような気が…
わりとすぐに出来そう…

さて、すぐにできるだろうか。

テーブル(mt_content)の追加


# sqlite3 mt.db
sqlite> create table mt_content(
content_id INTEGER PRIMARY KEY,
content_file text,
content_content text); (return)

MT::ObjectのサブクラスMT::Contentの作成(lib/MT/Content.pm)


package MT::Content;
use strict;

use MT::Object;
@MT::Content::ISA = qw( MT::Object );
__PACKAGE__->install_properties({
  columns => ['id', 'file', 'content',
   ],
 indexes => {
  id => 1,
  file => 1,
 },
 datasource => 'content',
});

プラグインの作成

再構築時にファイルを書き出さずにDBへコンテンツを入れる(plugins/Content.pl )


package MT::Plugin::AltDynamicPublishing;
use strict;
use MT;
our $VERSION = "0.1";
@MT::Plugin::AltDynamicPublishing::ISA = qw(MT::Plugin);

my $plugin = new MT::Plugin::AltDynamicPublishing({
 name => 'AltDynamicPublishing',
 version => $VERSION,
});

MT->add_plugin($plugin);
MT->add_callback('BuildFileFilter', 1, $plugin, ¥&_addContent);

sub _addContent {
 my ($eh, %args) = @_;
 my $ctx = $args{'Context'};
 my $blog = $args{'Blog'};
 my $file = $args{'File'};
 my $tmpl = $args{'Template'};
 my $cond;
 my $html = undef;
 $ctx->stash('blog', $blog);
 $html = $tmpl->build($ctx, $cond);
 use MT::Content;
 my $content = MT::Content->load({ file => $file });
 unless (defined $content) {
  $content = MT::Content->new;
 }
 $content->file($file);
 $content->content($html);
 $content->save or die $content->errstr;
 if (-f $file) {
  rename($file, $file.'.static');
 }
 return 0;
}
1;

閲覧用CGIの作成(mt-view.cgi)


#!/usr/bin/perl -w
use strict;

use lib qw (/Applications/MAMP/htdocs/mt/lib/);
use lib qw (/Applications/MAMP/htdocs/mt/extlib/);
my $file = '/Applications/MAMP/htdocs';
my $index = 'index.html';

use MT;
use MT::Content;
my $mt = MT->new(Config => '/Applications/MAMP/htdocs/mt/mt-config.cgi');

print "content-type: text/html¥n¥n";
$file .= $ENV{"REDIRECT_URL"};
if ($file =~ /¥/$/) {
 $file .= $index;
}
my $content = MT::Content->load({ file => $file });
if (defined $content) {
 print $content->content;
} else {
 print <<HTML;
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head>
<body>
404
HTML
}

.htaccess


ErrorDocument 404 /online/mtview.cgi
ErrorDocument 403 /online/mtview.cgi

で、ここからが考察というか本題。

これで"とりあえず" 動くようだ(というか目の前では動いている)。
負荷は(たぶん)たいして減らない。再構築は多少速くなるが(再構築が必要)閲覧時にDBにアクセスするからその分は負担になる(それでも「構築」は済んでいるから「ダイナミック」に生成するよりは速い。ただし公開サイトでやると[現状では]かえって負荷は増えるかも)。

テーブルにタイムスタンプとダイジェスト, ファイルサイズを加えて条件を満たした時だけ更新するようにして、mt-view.cgi をConditional GET 対応するようにすれば使い物になるだろう。

殆どのプラグインもそのまま動作するだろうし、スタティック、ダイナミックの切り替えも容易だ。

この例では再構築をBuildFileFilterコールバックに "0" を返すことで無効にしているが、1を返してやればファイルはそのまま生成され、管理するためだけのDBができる(この場合はファイルの中身をDBに入れる必要はないだろう)。

主目的はファイルの管理なのでその点で考えると、DBに入っているファイルはMTが吐き出したものであるから、

  • すべてを再構築してDBを更新。更新されていないもの(再構築時点より古いタイムスタンプのもの)はイコール「ゴミ」ファイルなので削除する
  • ただし手動でアップしたファイルである可能性があるのでファイルのタイムスタンプと長さとダイジェストをチェックする

という処理が可能になると思う。

同様に 画像等のファイル管理用テーブルを作って CMSUploadImage が呼ばれた時に情報を登録すればファイルマネージャーができそう。

※というか、誰かやらんかね


※再構築の前に一旦ファイルを全削除して(その間はダイナミックにページを送り出す)、再度書き出し直せば「ゴミ」は出来ないよな。色々応用が効きそう。


→さらに続く。



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

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