なんとなく、いつも良くみるサイトの新着情報なんかをサイドメニューに表示してみようと思い、CPAN の新着モジュール情報 と RssRolling の新着タイトルを載せてみました。どちらも RSS から HTML に変換して SSI で取り込んでいます。
MovableType のサイドメニューに RSS を整形して取り込むっていうのは mt-rssfeed プラグインを使うと可能ですが、mt-rssfeed を使い始めると Main Index を定期的にリビルドする羽目になり嫌んな感じなので、敢えて SSI で取り込む用のスクリプトを自作しました。といってもしょっぱいスクリプトが数十行と言ったところですが。
#!/usr/local/bin/perl
# $Id:$
# rss2ssi.pl
#
# RSS を整形して出力するスクリプト (主にSSIでMTのサイドに取り込む用)
# usage: rss2ssi.pl RSS_URL HTML_TMPL OUTPUT_FILE
# option: -l n ... max length of each title (default undef = not truncate)
# -c n ... max item counts (default undef = all items)
# -e s ... output encoding (default EUC-JP)
#
# Naoya Ito <naoya@naoya.dyndns.org>
use strict;
use warnings;
use Encode;
use XML::RSS;
use HTML::Template;
use LWP::Simple;
use Getopt::Long;
my $count = undef;
my $length = undef;
my $encode = 'EUC-JP';
my $option = GetOptions("l=i" => \$length,
"c=i" => \$count,
"e=s" => \$encode);
our $URL = shift;
our $TMPL = shift;
our $OUTPUT = shift;
die "usage: $0 RSS_URL HTML_TMPL OUTPUT_FILE\n"
if (not defined $URL or
not defined $TMPL or
not defined $OUTPUT);
eval {
my $tmpl = HTML::Template->new(
filename => $TMPL,
die_on_bad_params => 0
);
my $rss = XML::RSS->new;
$rss->parse(LWP::Simple::get($URL));
my $i = 0;
my @items = ();
for my $item (@{$rss->{items}}) {
push @items, {
title => &truncatestr($item->{title}, $length),
link => $item->{link}
};
$i++;
last if (defined ($count) and $i == $count);
}
$tmpl->param(items => \@items);
my $fh;
open $fh , ">" , $OUTPUT or die "cannot open $OUTPUT : $!";
print $fh encode($encode, $tmpl->output);
close $fh;
}; if ($@) {
die $@;
}
sub truncatestr {
my ($str, $length) = @_;
if ($length) {
my $substring = substr($str, 0, $length);
$substring .= "..." if (length($substring) < length($str));
return $substring;
} else {
return $str;
}
}
このスクリプトを cron で回して、SSI で取り込む用の HTML を更新しています。HTML は無駄にテンプレートで定義してみたり。表示するアイテムの数とかタイトルの長さを、取り込む対象ごとにカスタマイズしたり、あるいは更新頻度(要はcronで回る周期)を対象ごとに変えたりといったことは自作ならではです。 :)