昨年末、web拍手の改造についてのご質問をいただいたのだった。web拍手解析画面の表示に関し、公式スクリプトのそれに近づけたいという、そういう要望であった。具体的にいうと、書き込み時刻とメッセージ欄についてである。幸いどちらもそれほど難しくはないため、今回一気に片付けてしまおう。
書き込み時刻についての改造はいったいどういうものであったかというと、分及び秒の表示において、常に二桁で表示をさせたいというものだ。具体的にいうと、
例えば5時2分であれば5:2を5:02といった感じに表示
するようにしたいというものである。
さて、ここで思い出さねばならないことがある。デフォルトのweb拍手CGIは書き込みの時間こそは記録するが、分秒までは記録してくれないのであった。なので、以前紹介した改造を施す必要がある。そしてそれは二種類あったのだった。
ややこしいことに、簡単編を選択したユーザーと困難編を選択したユーザーで、改造箇所が違ってくる。よって、それぞれを説明するので、読者の皆様方におかれましては、なにとぞご自身のなされた改造に則した方をお選びになるよう、ご注意いただきたい。
簡単編を選んだユーザーの場合、改造対象はclap.cgiである。拍手のなされた時刻をログファイルに書き込む、その箇所を少し書き換えてやろうというわけだ。改造箇所は、無改造のclap.cgiなら118行目にあたる箇所。
#---------------------------------------一言メッセージ処理
if ($hitokoto ne ''){
$mesdata = "$getdate<>$tohour<>$hitokoto<>\n";
簡単編の改造例は以下のとおりであった。
#---------------------------------------一言メッセージ処理
if ($hitokoto ne ''){
$mesdata = "$getdate<>$tohour:$min:$sec<>$hitokoto<>\n";
変数$minと$secのそれぞれに分と秒がセットされているのであった。なので、それぞれが10より小さい(つまり一桁)である場合、その前に文字列0を連結することとする。このように、条件によって処理が分岐する場合には、ifステートメントを使うのであった。条件は分の場合$minが10より小さい、すなわち$min < 10
である。
最初に、時刻の文字列を取り扱うための変数を用意しておこう。私はこれを$timestring
とした。もちろん名前はわかりやすければなんでもいい。$timestring
に時間$tohour
をセットしておき、分が10より小さい場合には、:0をはさんで$minを、10以上だったら0をはさまない:に続いて$minを連結していく。文字列の連結にはドットを使うが、この時、ドットに繋いでイコールを書くことによって記述を省略することができる。$timestring .= ":0$min"
だったら、$timestring = $timestring.":0$min"
と同じ意味だ。
上に説明したことをPerlで書くと以下のようになる。なお、前半が分、後半は秒である。
my $timestring = $tohour;
if ($min < 10) {
$timestring .= ":0$min";
} else {
$timestring .= ":$min";
}
if ($sec < 10) {
$timestring .= ":0$sec";
} else {
$timestring .= ":$sec";
}
この数行を、さっき紹介した118行目、一言メッセージ処理の直前に挿入し、こうして作られた$timestring
を、ログに書き込むようにする。この一連の処理をまとめて書くと次のようになる。
my $timestring = $tohour;
if ($min < 10) {
$timestring .= ":0$min";
} else {
$timestring .= ":$min";
}
if ($sec < 10) {
$timestring .= ":0$sec";
} else {
$timestring .= ":$sec";
}
#---------------------------------------一言メッセージ処理
if ($hitokoto ne ''){
$mesdata = "$getdate<>$timestring<>$hitokoto<>\n";
簡単編の改造は以上だ。
困難編も別に難しいことはしやしない。やることといったら、上に説明したことと基本的に一緒だ。ただし、こちらの改造対象は、kaiseki.cgiである。
以前の改造では、メッセージの書き込み時間が$meshour、分が$mesmin、秒が$messecとなるように説明した。なので今回もこれを踏襲する。
最初に$timestring
を用意してやろう。ここでやってることは簡単編の改造と同じだから、説明しない。
my $timestring = $meshour;
if ($mesmin < 10) {
$timestring .= ":0$mesmin";
} else {
$timestring .= ":$mesmin";
}
if ($messec < 10) {
$timestring .= ":0$messec";
} else {
$timestring .= ":$messec";
}
この数行を、一言メッセージを表示する箇所、具体的にいうとkaiseki.cgiの122行目の前に書いてやる。本当に直前。spritで$mes[$i]が分けられた後に書いてやらないといけないので、注意して欲しい。
なお、122行目というのは次のような部分。
print "<td><p align=\"right\">$meshour時</p></td>\n";
改造後だとこんな風になってるはず。
print "<td><p align=\"right\">$meshour:$mesmin:$messec</p></td>\n";
これを書き換える。すると次のようになる。
my $timestring = $meshour;
if ($mesmin < 10) {
$timestring .= ":0$mesmin";
} else {
$timestring .= ":$mesmin";
}
if ($messec < 10) {
$timestring .= ":0$messec";
} else {
$timestring .= ":$messec";
}
print "<td><p align=\"right\">$timestring</p></td>\n";
以上で時刻に関する改造は終了だ。
web拍手CGIでは、一言メッセージがない場合にはなにも表示されないようになっている。正確にいえば、中身が空っぽのテーブルが出力されているのだが、まあそんなの見えないからないのと一緒だ。
さて、これを、
メッセージが無かった時にメッセージ欄に「今日はまだメッセージがありません」と表示
するようにしたい。
これは純粋にweb拍手解析画面だけの問題なので、当然改造箇所はkaiseki.cgi。無改造なら、114行目から129行目を改造する。なお、さっきの改造をした場合には改造範囲が広がっていることに注意しておく必要がある。
#----------------------メッセージ表示
print "今日送られたメッセージ<br>\n";
print "<table border>\n";
for ($i=0 ; $i<=$#mes ; $i++){
($mesday,$meshour,$message) = split(/<>/,$mes[$i]);
print "<td><p align=\"right\">$meshour時</p></td>\n";
print "<td>$message</td><tr>\n\n";
$sousinmessage = "$sousinmessage\n$message";
}
print "</table><br>\n";
基本的な考え方はこんな感じ。メッセージの収められている配列@mesを評価して、メッセージがあれば上記のコードのテーブルを出力する部分を実行、メッセージがなければメッセージがありませんと表示する。なのでここでもifステートメントを使うわけだ。
Perlは非常に便利なことに、配列をそのまま評価対象にすることができる。具体的にいうと、ひとつでも要素があれば真に、まったく要素がなければ偽と判断される。これを模式的に書けば次のようになる。
if (@mes) {
# 真、つまりメッセージがある場合
} else {
# 偽、つまりメッセージがない場合
}
最初に示した、改造対象範囲、テーブルの出力が開始される行、
print "<table border>\n";
から、テーブルの出力が終わる行、
print "</table><br>\n";
までをifステートメントの真の部分に押し込めてやろう。するとこんな感じ。
#----------------------メッセージ表示
print "今日送られたメッセージ<br>\n";
if (@mes) {
print "<table border>\n";
for ($i=0 ; $i<=$#mes ; $i++){
($mesday,$meshour,$message) = split(/<>/,$mes[$i]);
print "<td><p align=\"right\">$meshour時</p></td>\n";
print "<td>$message</td><tr>\n\n";
$sousinmessage = "$sousinmessage\n$message";
}
print "</table><br>\n";
} else {
# ここにメッセージがない旨の通知を書く
}
メッセージがない旨の通知は、p要素あたりで出力してやるといいだろう。ということは、こんな感じ。
print "<p>今日はまだメッセージがありません</p>\n";
ただしこれでは不完全だ。というのは、過去の日付に遡った場合、今日と表示されるのはおかしいからだ。もしそれをおかしいと思わない場合は、改造はここで終わり。けど、私はおかしいと思ったからまだ続ける。
kaiseki.cgiでは、$logdayという変数でもって、表示される日を管理している。これは、今日から数えて何日前を表示するかを示していて、つまり今日なら0、昨日なら1といった感じで過去に向かって数字が増えていく仕組みだ。
Perlでは0は偽、それ以外の数は真と判断される。便利! つまりここでもifステートメントを使う。こんな感じ。
if ($logday) {
print "<p>メッセージはありません</p>\n";
} else {
print "<p>今日はまだメッセージがありません</p>\n";
}
これを、先ほどのelse以下、メッセージがない旨の通知を書くといっていた場所に書いてやればいいのだ。
#----------------------メッセージ表示
print "今日送られたメッセージ<br>\n";
if (@mes) {
print "<table border>\n";
for ($i=0 ; $i<=$#mes ; $i++){
($mesday,$meshour,$message) = split(/<>/,$mes[$i]);
print "<td><p align=\"right\">$meshour時</p></td>\n";
print "<td>$message</td><tr>\n\n";
$sousinmessage = "$sousinmessage\n$message";
}
print "</table><br>\n";
} else {
if ($logday) {
print "<p>メッセージはありません</p>\n";
} else {
print "<p>今日はまだメッセージがありません</p>\n";
}
}
そして、私はまだ満足しなかった。一番最初。今日送られたメッセージの部分だ。これを今日以外の日には、何月何日に送られたと表示することにしたい。考え方は、さっきのメッセージに関する通知と一緒だ。するとこうなる。
#----------------------メッセージ表示
if ($logday) {
print "$tomon月$today日に送られたメッセージ<br>\n";
} else {
print "今日送られたメッセージ<br>\n";
}
if (@mes) {
print "<table border>\n";
for ($i=0 ; $i<=$#mes ; $i++){
($mesday,$meshour,$message) = split(/<>/,$mes[$i]);
print "<td><p align=\"right\">$meshour時</p></td>\n";
print "<td>$message</td><tr>\n\n";
$sousinmessage = "$sousinmessage\n$message";
}
print "</table><br>\n";
} else {
if ($logday) {
print "<p>メッセージはありません</p>\n";
} else {
print "<p>今日はまだメッセージがありません</p>\n";
}
}
改造箇所、付け加えた部分はわかりやすく強調してある。
以上で改造は終わりだ。思った以上に説明がくどくなってしまって、これをお読みになった皆様には申し訳ない。というわけで、本年2008年もよいweb拍手ライフが送られますよう、お祈りいたす次第。これを役立てていただければ、幸いだ。
< web拍手支援cgi:一言メッセージ拒否機能について web拍手改造:web拍手支援cgiに各種設定変更機能を追加 >