ウェブサイトの過去ニュース管理用MovableType風スクリプト
スポンサードリンク
ウェブサイトの過去のニュースを、個別ページとして生成させたくなって、XMLをソースとした書き出しシステム(MovableType風)ができたので、それのソースです。Linuxのコマンドラインで実行します。
Filename: past.pl
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use DateTime::Format::W3CDTF;
use Encode;
use FindBin::Real;
use File::Path;
use File::Spec;
use File::Basename;
use HTML::Template;
use XML::LibXML;
use YAML;
binmode STDOUT => ':utf8';
chdir FindBin::Real::Bin();
my $sourcefile = 'news.xml';
my $individualtmplfile = 'tmpl/individual.tmpl';
my $baseurl = 'http://www.example.com/past/';
my @index_template = qw(
tmpl/index.html.tmpl
tmpl/sitemap.txt
);
# XMLファイルを一気読み
open my $fh, '<', $sourcefile or die $!;
my $source = do { local $/; <$fh> };
# XMLパース&処理
my $list = xmlparse($source);
# Publish前データ処理
pre_publish(\$list);
# individual archive処理
{
my $t = HTML::Template->new(
filename => $individualtmplfile,
filter => sub { utf8::decode( ${ shift() } ); },
die_on_bad_params => 0,
);
map {
$t->param( $_ );
open $fh, '>', $_->{file} or die $!;
binmode $fh => ':utf8';
print $fh $t->output;
close $fh;
} @$list;
}
# index template処理
map{ main_index( $_ ); } @index_template;
exit;
# XMLパース
sub xmlparse {
my $source = shift;
# XML::LibXMLパーザ
my $parser = XML::LibXML->new(
suppress_errors => 1,
suppress_warnings => 1,
recover => 2,
);
my $dom = $parser->parse_string($source);
# DOMインタフェースでノードリスト選択
my @xfolk = $dom->findnodes('//o:xfolkentry');
# XMLから要素を読み込む(ここでは読み込む専門、加工は最低限)
foreach my $x ( @xfolk ) {
my $body;
foreach my $i ( $x->find('o:body')->[0]->childNodes ) {
$body .= $i->toString();
}
my $description = $x->findvalue('o:body');
my $extended_body;
if ( $x->exists('o:extended_body') ) {
foreach my $i ( $x->find('o:extended_body')->[0]->childNodes ) {
$extended_body .= $i->toString();
}
$description .= $x->findvalue('o:extended_body');
}
my $items = {
date => $x->findvalue('o:date'),
title => $x->findvalue('o:title'),
body => $body,
extended_body => $extended_body,
description => $description,
};
#$items->{extended_body} = $extended_body if $extended_body;
push @$list, $items;
}
return $list;
}
# XMLから解析済みの要素
sub pre_publish {
my $lst = shift;
map {
my $dt = DateTime::Format::W3CDTF->parse_datetime($_->{date})->set_time_zone('Asia/Tokyo');
my $filepath = $dt->strftime('%Y/%m');
mkpath $filepath;
my $date_id = $dt->strftime('%Y%m%d');
my $basename = $_->{basename}
|| $dt->strftime('%m%d%H%M%S').".html";
print "$filepath/$basename\n";
$_->{basename} = $basename;
$_->{filepath} = $filepath;
$_->{datetime} = "$dt";
$_->{ymd} = $dt->ymd;
$_->{date_id} = $date_id;
$_->{permalink} = "${baseurl}$filepath/$basename";
$_->{file} = "$filepath/$basename";
} @$$lst;
}
# index template書き出し テンプレート名を入れると
# テンプレート名から.tmplをとったファイルで
# カレントディレクトリへ書き出します。
sub main_index {
my $tmplfile = shift;
my $t = HTML::Template->new(
filename => $tmplfile,
filter => sub { utf8::decode( ${ shift() } ); },
die_on_bad_params => 0,
loop_context_vars => 1,
);
$t->param( list => $list, baseurl => $baseurl );
my $outputfile = fileparse($tmplfile, ".tmpl");
open $fh, '>', $outputfile or die $!;
binmode $fh => ':utf8';
print $fh $t->output;
close $fh;
}
__END__
XMLは、こんな感じです。
Filename: news.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<o:info
xmlns="http://www.w3.org/1999/xhtml"
xmlns:o="http://www.example.com/">
<o:xfolkentry>
<o:date>2011-07-01</o:date>
<o:title>計画停電実施に伴う営業時間の短縮について</o:title>
<o:body>
<p>当地区では2011年7月1日午後9時~午後12時まで、計画停電が実施されることになりました。</p>
<p>つきましては、営業時間を短縮させていただきますのでお知らせします。</p>
</o:body>
<o:extended_body>
<dl>
<dt>営業時間</dt>
<dd>午後1時~午後18時</dd>
</dl>
<p>社員の帰宅時の交通安全を確保する目的で、停電終了時刻から1時間遅れて営業を開始いたします。ご理解のほどよろしくお願いします。</p>
</o:extended_body>
</o:xfolkentry>
</o:info>
o:ていうプリフィクスは名前空間です。こうやると、XHTMLの名前空間は省略できるのですね。
のこり、テンプレート。
Filename: tmpl/index.html.tmpl
<!DOCTYPE html>
<html>
<head profile="http://microformats.org/profile/xfolk">
<meta charset="utf-8">
<title>
過去のニュース
</title>
</head>
<body>
<article class="xfolkentry" id="d<tmpl_var name="date_id">">
<p><tmpl_var name="ymd"></p>
<h3><a href="<tmpl_var name="filepath">/<tmpl_var name="basename">"><tmpl_var name="title"></a></h3>
<tmpl_var name="body">
<tmpl_if name="extended_body">
<p style="text-align: right;">
<a href="<tmpl_var name="filepath">/<tmpl_var name="basename">#more">続きを読む</a></p>
</tmpl_if>
</article>
</tmpl_loop>
</body>
</html>
Filename: sitemap.txt.inc
<tmpl_loop name="list"><tmpl_var name="permalink"> </tmpl_loop><tmpl_var name="baseurl">
Filename: tmpl/individual.tmpl
<!DOCTYPE html>
<html>
<head profile="http://microformats.org/profile/xfolk">
<meta charset="utf-8">
<title>
<tmpl_var name="title">
</title>
</head>
<body>
<article class="xfolkentry" id="d<tmpl_var name="date_id">">
<p><tmpl_var name="date"></p>
<h3><tmpl_var name="title"></h3>
<div id="body">
<tmpl_var name="body">
</div>
<div id="more">
<tmpl_var name="extended_body">
</div>
<div class="metadata">
<a href="<tmpl_var name="permalink">"><tmpl_var name="date"></a>
</div>
</article>
</body>
</html>
~~~
大体3時間でできたので、MovableTypeやWordPress入れるよりもかえって早いぐらいだと思うんですが、CMSを自作しても将来性がないのでWordPress入れたほうがいいよ、て言われるとグウの音も出ないよね……
スポンサードリンク
トラックバック(0)
トラックバックURL: http://blog.dtpwiki.jp/MTOS/mt-tb.cgi/3625





![: Amazon.co.jp: プラスティック・メモリーズ 1【完全生産限定版】(イベントチケット優先販売申込券付) [Blu-ray]](/lists/_9/B00VWX66E8.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 2【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX66K2.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 3【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX6MV0.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 4【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX66IO.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 5【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX6Y0E.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 6【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX69D6.jpg)


コメントする