効率の良いBlosxomプラグイン

Blosxomではプラグイン同士が連携することはほとんど考慮されていない。プラグインで何でも出来るけど、なんでも効率的にできるわけではないということで、ここらへんはBlosxomの語られていない闇の部分(誰も興味ないから)。例えばhead.flavourでエントリーのタイトルとかを利用しようとするとプラグインが必要になるので書くわけだけど、いずれblosxom.cgiが読んでくれるファイルを自前で読まなくてはならなくてスーパー非効率的。

上で例として挙げたpermalinkでエントリーのタイトルをtitle要素にぶち込むプラグインというのを考えてみる。ストレートに実装すると、better_titlestorytitleentry_titleみたいにheadサブルーチンでエントリーファイルを読んでタイトルを切り出して変数に格納することになる。これをどうにかして自前でファイルを読まないようにするには一工夫が必要。

# Blosxom Plugin: permalink
# Author(s): Kyo Nagashima <kyo@hail2u.net>
# Version: 2012-04-05T15:28:39+09:00
# Blosxom Home/Docs/Licensing: http://blosxom.sourceforge.net/

package permalink;

use strict;
use vars qw($title $title_sep);

# --- Configurable variables -----------

# separator string between $blog_title and $title
my $str_title_sep = " - ";

# --- Plug-in package variables --------

my $title_placeholder = '{{{permalink::title}}}';
my $t;

# --------------------------------------

sub start {
  if ($blosxom::path_info !~ /\.\Q$blosxom::flavour\E$/) {
    return 0;
  }

  $title     = $title_placeholder;
  $title_sep = $str_title_sep;

  return 1;
}

sub story {
  my($pkg, $path, $filename, $story_ref, $title_ref, $body_ref) = @_;

  $t = $$title_ref;

  return 1;
}

sub last {
  $blosxom::output =~ s/$title_placeholder/$t/m;
}

1;
# vim:ft=perl:

最終的にはrss10プラグインなどでも使われているプレースホルダーを作ってlastサブルーチンで置換するというテクニックを使うわけだけど、flavourにも$permalink::titleなどと書けるようにしてある。permalinkではない場合は$permalink::titleは空になるので、head.flavourでは以下のように書くだけで良い。

<title>$permalink::title$permalink::title_sep$blog_title</title>

これでインデックスページではこうなり、

<title>Weblog - hail2u.net</title>

permalinkでの出力はこうなる。

<title>効率の良いBlosxomプラグイン - Weblog - hail2u.net</title>

flavourに{{{plugin:placeholder}}}みたいに書かせると、常にそのプラグインを有効化しておかないとHTMLに無意味な文字列が出てしまうことがあるし(コメントとかにすれば少しは改善するけど)、必要のない時も置換しないといけなくてちょっとアレなので上記のような実装が一番効率的なんじゃないかと思う。

久々にBlosxomプラグインを書いたのでなんか見落としてそう。