QG : Akiary Labo
2005年10月26日(水) BlogPet再設置
リニューアル前は1つの日記にBlogPetのウトギも投稿させていたのですが、複数ユーザ対応になったのでウトギ専用の日記に投稿させるようにしました。
自分の投稿がないと、BlogPetの投稿ばかり続いてしまいましたし。
言葉を憶えるRSSはQGのRSSを設定。
投稿用APIは前回同様kkojimaさん作ak-xmlrpc.cgiで、サーバのPerlがバージョン5.8未満なのでJcode.pm版を使用。
取り敢えず初回はテストも兼ねて、ウトギっぽい文章で自ら投稿しましたが、今後自動で投稿が成功すること祈る。
2005年10月19日(水) 文字列URLエスケープ
旧Akiary改造ログをHTML文法チェックにかけていて気付いたのですが、アドレスに「&」が含まれていると、不明な実態参照扱いになっているとエラーが出ました。
「文字コード」では、チルダ「~」の文字化けを「%7E」にして回避する方法を書いていますが、「&」までは気付かなかったようで。
「&」は「%26」にして、ジャンプも成功。
変換には「文字列URLエスケープ」を利用しました。
2005年10月18日(火) Akiary v.0.51改造ログ
目次のバックナンバー項目に、「Akiary v.0.51での改造」を追加しました。
普通に記事を貼り付けても良かったんですが、折角のphpを生かそうと思って、使いそうな構文などを調べて試行錯誤していたら、実現するのにかなり日を食ってしまいました。
表示させるページと、ログファイルは別になっていて、任意の記事数以上になると次のページに移動するリンク(ページング)が出てきます。
ログファイルはタブ区切りテキストで、UNIX時間で書かれた日付、タイトル、本文の順に拾っていきます。
1行が1記事なので、PREタグ内にある改行はBRタグなどを使わざるを得ませんでした。
それにしてもAkiary改造をしている時期って、去年も同じ頃だったんだなあ。
スケジュール的な関係もありますが、秋はクリエイティブ向きな季節なのかも。
phpで他にも何か作ってみたいと思いました。
2005年10月13日(木) tDiary対応Akiaryテンプレート
これまで「Akiary Labo」はAkiary v.0.61のテンプレートを基本にして使っていましたが、cssのクラス名などをtDiaryに合わせたテンプレートとcssを作りました。
見た目は同じなので特にメリットがあるわけではないですが、tDiaryのテーマ集からすげ替えられます。
XTML準拠で、文字コードはEUCになっています。
あと、目次ページはn3kitのタイトルリスト流用で、タイトルに記事へのリンクをつけています。
<td class="title"><a href="<!--akiary_bndate-->.html#<!--akiary_did-->">
<!--akiary_title--></a></td>
「目次から記事へのリンク」の年月とDIDのタグを、akiary.cgiに追加する必要があります。
リンクが不要の場合はこの部分を外し、
<td class="title"><!--akiary_title--></td>
とします。
2005年10月13日(木) 特殊文字を使う
aki2rss.cgiでは、最新版日記から文字を切り出すときに「##entry##」などを区切り文字列にしているので、「日記本文も含めて、各カラムには上記の区切り文字列を含まないこと。」と書かれています。
それでも日記ページからのコピペでも使えるように「#」は半角で書きたかったので、数値参照型の特殊文字にしました。
#
本当は、PREタグ中などで多用している特殊文字は、どれもそうするべきなんでしょうね。
akiary.cgiでは本文中の特殊文字で特にエラーが出ないので意識していなかったのですが、RSS出力をしているトップページの本文に「##entry##」を書いたら、aki2rss.cgiでエラーになって気付きました。
文字参照型の特殊文字一覧はよく見かけますが、数値参照型の変換には「特殊文字変換(数値参照型)」が便利です。
2005年10月12日(水) aki2rss.cgiでDIDへのリンク
「100点満点への道」で記事毎にアンカーが張られているとばかり思っていたのですが、よく見たらページ後のリンクは年月日だけになっていました。
年月日だけのアンカーはやめて、DID(DiaryID)だけのアンカーしか張っていないので、これではそのページにしか飛ばなかったのです。
そこで、aki2rss.cgiの「# uriを探す。」でDIDを参照するように書き換えました。
最新版日記から作成されるnew.txtの「##entry##」に書かれるDIDを探し、そこからリンクを組み立てます。
# uriを探す。
$$refanchor =~ m/(\d{6})(\d{2})_(\d{10})/;
$uri = $1 . '.php#' . $1 . $2 . '_' . $3;
DIDは8文字+_(アンダーバー)+10文字になっているので、これを6文字+2文字+_+10文字に分解し、年月+日+_+UNIX時間 (1970年1月1日からの秒数) という形にします。
uriが、年月+拡張子#+年月日+_+UNIX時間となるように組み合わせます。
また、DIDの内容さえ「##entry##」にあればよいのにも気付きました。
「目次のテーブル復活」ではアンカーが作成される部分のnameもしくはdid属性値からdidを探していると思って「name="20051012_1234567890"」のように書き込まれるように<!--akiary_name-->
なんてタグを追加していました。
$tmp=~s/<!--\s*akiary_name\s*-->/name=\"$_\"/g;
そのままDIDが書き込まれれば良いので、ここは削ります。
new.txtのテンプレート(tmpnew.txt)の「##entry##」欄は「目次から記事へのリンク」で追加したDID用のタグを流用します。
##entry##<!-- akiary_diary reverse latest_times="10" --><!-- akiary_did -->
ついでに、aki2rss.cgiの「# dateを探す。」と「 # didを探す。」も単純化。
# dateを探す。
$$refanchor =~ m/(\d{8})/;
$date = $1;
# didを探す。
$$refanchor =~ m/(\d{8})_(\d{10})/;
$date = $date || $1;
$time = $2;
$did = $1 . '_' . $2;
2005年10月11日(火) 変換まわりのまとめ
こっちを引っ込めるとあっちが飛び出すといった具合に、akiary.cgiの編集画面と作成される日記間での変換に四苦八苦したわけでありますが、部分部分の説明だったり、トータルを見て修正した箇所などあるので、ここいらで現在の変換まわりをお見せします。
perlスクリプトは上から読み込んでいくので、書く順番もポイントでした。
「処理実行」の新規日記用の「更新」とバックナンバーなどオプショナル日記用の「修正」中にある、「更新実行」で本文が変換される部分は同一にしています。
また、XTML準拠にしているため、BRタグとかはタグ内で閉じています。
「処理実行」-「更新」/「修正」-「更新実行」-本文変換部分(262行目~/294行目)。
$BODY{$dids[0]}=~s/\x0D\x0A/<br \/>/g; # 改行コード変換(Win)
$BODY{$dids[0]}=~s/\x0D/<br \/>/g; # 改行コード変換(Mac)
$BODY{$dids[0]}=~s/\x0A/<br \/>/g; # 改行コード変換(UNIX)
$BODY{$dids[0]}=~s/<br \/><br \/>/<\/p><p>/g;
$BODY{$dids[0]}=~s/\A/<p>/g;
$BODY{$dids[0]}=~s/\Z/<\/p>/g;
$BODY{$dids[0]}=~s/<pre>(.*?)<\/pre>/<\/p><div class=\"pre\"><pre>$1<\/pre><\/div><p>/g;
$BODY{$dids[0]}=~s/<ul(.*?)>(.*?)<\/ul>/<\/p><ul$1>$2<\/ul><p>/g;
$BODY{$dids[0]}=~s/<div(.*?)>(.*?)<\/div>/<\/p><div$1>$2<\/div><p>/g;
$BODY{$dids[0]}=~s/<p><br(.*?)><\/p>/<br$1>/g;
$BODY{$dids[0]}=~s/<p><br s(.*?)><br \/>/<br s$1><p><br \/>/g;
$BODY{$dids[0]}=~s/<p><p>/<p>/g;
$BODY{$dids[0]}=~s/<\/p><\/p>/<\/p>/g;
$BODY{$dids[0]}=~s/<p><\/p>//g;
「ページ表示」-「修正表示」-「更新/削除」-本文変換部分(643行目~)。
$body=~tr/\x0D\x0A//d; # 改行コード削除
$body=~s/<br \/>/\n/ig;
$body=~s/<\/p><p>/\n\n/ig;
$body=~s/<br s(.*?)><p>/<br s$1>/ig;
$body=~s/<\/p><ul>/<ul>/ig;
$body=~s/<\/ul><p>/<\/ul>/ig;
$body=~s/<\/p><div(.*?)>/<div$1>/ig;
$body=~s/<\/div><p>/<\/div>/ig;
$body=~s/<div class=\"pre\"><pre>/<pre>/ig;
$body=~s/<\/pre><\/div>/<\/pre>/ig;
$body=~s/\A<p>//ig;
$body=~s/<\/p>\Z//ig;
ブロック要素は今のところPRE・UL・DIVだけに対応しています。
この辺は使うブロック要素に合わせて増減していくつもりで。
同じような変換方法が続くので、もっと省略できる気もするのですが。
たとえば、区切り記号「|」なんかで同じ変換方法を取るブロック要素は並べて書きたいのですが、配列を記憶させるにはまだどうすればいいか分からず。
MacのIEで見たら、PRE要素の中身がごっそり見えなくなってしまっていたので、DIVタグで囲むようにしました。
これはきっとブラウザのバグなんだろうなあ。
2005年10月10日(月) PとBRとの格闘
改行まわりでベストな変換結果を得るために、苦戦しました。
まだ汎用性という意味では未完成ですが、現在のところ修正を繰り返しても動かなくなったので、なんとか使用可能レベルに。
矛盾が生じていると、修正を繰り返すたびに変化してしまいます。
たとえば、単純にBRタグが並んでいた時はP閉じ・開始タグに変換するわけですが、
$BODY{$dids[0]=~s/<br\/><br\/>/<\/p><p>/g;
結果↓
</p><p>
BRタグに属性を持たせた時は、それを生かしたいので、
<br style="clear:all; /><p>
のようにしたいのです。
属性を持つBRタグを、br
以降はタグの終わりまでどんな文字が入っていてもマッチするように、<br(.*?)>
とし、
$BODY{$dids[0]=~s/<br(.*?)><br\/>/<br$1><p>/g;
なんて書くと、BRタグの最短一致で属性があろうとなかろうとマッチしてしまい、他のところで不都合が生じます。
そこで、属性を持つBRタグだけに対応するようにします。
どのみちスタイル属性style
くらいしか使わないので、始まりにs
があればマッチするように、<br s(.*?)>
としました。
$BODY{$dids[0]=~s/<br s(.*?)><br \/>/<br s$1><p>/g;
ただ、基本的に文章と文章の間はPタグで囲んでいるので、上のように書くと、
<p><br style="clear:all; /><p><br /></p>
のような部分が生じてきます。
そのため、
<p><br style="clear:all; /><br />
のような並びになった場合には、
<br style="clear:all; /><p><br />
と変換することで対処するようにしました。
$BODY{$dids[0]}=~s/<p><br s(.*?)><br \/>/<br s$1><p><br \/>/g;
また、プレーンなBRタグでないため編集画面で直書きすると文章とみなされ、Pタグで囲まれてしまうので、
$BODY{$dids[0]}=~s/<p><br(.*?)><\/p>/<br$1>/g;
と、Pタグを外すようにします。
そして、編集画面に戻った時にP開始タグがくっついてこないように、
$body=~s/<br s(.*?)><p>/<br s$1>/ig;
を「修正表示」の「更新/削除」に書き加えます。
2005年10月9日(日) 本文全体をPタグで囲む
「改行をPタグへ」では、日記ファイル作成時に本文全体をPタグで囲む処理にしていました。
ただこの方法だと、何が何でもPタグで囲んでしまいます。
PREタグなど段落以外のタグで始まったり終わったりした時に、外側にあるPタグは不要になります。
現在PREタグ前後にP閉じタグ・P開始タグを入れるようにしているので、本文前後に<p></p>
のように空タグが生じます。
またバックナンバーでは本文$bnbody{$_}
をPタグで囲むと編集画面でP閉じタグが残ってしまう問題があったので、それを囲むAkiaryタグの外側にPタグを入れるようにしていたのですが、本文の要素はできれば中に入れておきたいところでした。
さすがにコードから使用例を探し出すのは限界で、perlの基本を調べました。
今までやってきた変換処理のようなものは「正規表現」関連事項でした。
それまで顔文字に見えていた(.*?)
とかの意味が分かったりと発見が多かったです。
それはさておき、akiary.cgiで本文をPタグで囲む方法の見直しです。
まずはもう使わない、日記ファイル作成時に本文をPタグで囲んでいた処理を囲まれないデフォルトに戻します。
バックナンバー。
1414行目 $tmp=~s/<!--\s*akiary_body\s*-->/
<!--akiary_body-->$bnbody{$_}<!--\/akiary_body-->/;
最新版日記。
1696行目 $tmp=~s/<!--\s*akiary_body\s*-->/$body{$_}/g;
次に更新と修正の「更新実行」時に、本文をPタグで囲みます。
テキスト全体の最初の位置にヒットする\A
の次にP開始タグを入れ、テキスト全体の最後の位置にヒットする\Z
の手前にP閉じタグを入れるようにします。
更新は264行目・修正は296行目の「# 改行コード変換(UNIX)」の次あたりに追加。
$BODY{$dids[0]}=~s/\A/<p>/g;
$BODY{$dids[0]}=~s/\Z/<\/p>/g;
また、<p></p>
のような空タグを発生させなくするために、更新と修正の「更新実行」時の最後に1行書き加えます。
$BODY{$dids[0]}=~s/<p><\/p>//g;
PREタグのように他にも前後の処理を追加させたい時は、この上に書き加えていきます。
そして、編集画面の「修正表示」で「更新/削除」時に、追加したPタグを取り除きます。
644行目にある「# 改行コード削除」の次に「改行をPタグへ」で追加した次あたり。
なんとなく最後のまとめな感じなので、処理のラストに書き加えました。
$body=~s/\A<p>//ig;
$body=~s/<\/p>\Z//ig;
2005年10月8日(土) PREタグ前後の処理
編集画面での改行は、本文に自動で改行タグが入るのに都合が悪い時があります。
本文全体をPタグで囲むようにしているのですが、整形済みテキスト<PRE>
・テーブル<TABLE>
・リスト<OL>や<UL>
・レイヤー<DIV>
・引用<BLOCKQUOTE>
などはPタグで囲まれないようにする必要があります。
またPREタグなどは、その意味からも間に何らかのタグがあってはならないです。
いっそのこと全てタグを手書きする方法もありますが、折角改行タグに気を回さずに書き込めるので、できるだけ自動処理させるための改造です。
取り敢えず多用しているPREタグの前後は、P閉じタグで終わりP開始タグで始まる変換処理をakiary.cgiに追加します。
場所は「更新実行」の、新規は264行目・修正は296行目にある「改行コード変換(UNIX)」の次あたり。
「改行をPタグへ」で追加した行の次に書きました。
$BODY{$dids[0]}=~s/<pre>(.*?)<\/pre>/<\/p><pre>$1<\/pre><p>/g;
編集画面に戻った時に、PREタグ前後に追加されたPタグを消去する変換処理を追加します。
場所は「修正表示」の「更新/削除」で644行目にある「# 改行コード削除」の次あたり。
同じく「改行をPタグへ」で追加した行の次。
$body=~s/<\/p><pre>/<pre>/ig;
$body=~s/<\/pre><p>/<\/pre>/ig;
Pタグを追加する処理と同様に1行で済ませたいのですが、うまい方法が分からず2行になっています。
それと、PREタグで囲まれた部分に入るBRタグを改行文字\n
に変換する方法は研究中です。
2005年10月7日(金) 目次のテーブル復活
HTML文法チェックで高得点獲得のためとはいえ、目次ページの記事一覧をレイヤーで組んだのには気になる点がありました。
現時点では月日が1桁+2桁と2桁+1桁で、それぞれ合計3桁になるため続くタイトルが揃って見えているのですが、2桁+2桁あるいは1桁+1桁になると揃わなくなってきます。
日付表示フォーマットを0付きの月日にするか、日付のレイヤー幅を固定にする対策も考えられます。
日付表示は今のが気に入っているので、変えるのには気が進みません。
レイヤー幅を固定にした場合、閲覧環境によって文字の大きさが変わってタイトルとの
間が開きすぎたりタイトルと文字が重なる可能性を考慮した幅にする必要があります。
そもそも「100点満点への道」で、aki2rss.cgiが参照する日時や記事へのリンクのためにname属性値としたDID(DiaryID)を個々記事の直前に書き込ませていて、テーブルで組むとおかしな場所に入れられてしまうのを回避するためのレイヤー組みでした。
ならば書き込ませなければ、テーブル組みで構わないわけです。
テーブル組みなら日付は一番開いた幅で揃えてくれるし、HTML文法的にも一覧表なんかはテーブル向きです。
まずはakiary.cgiで、最新版日記の日付とタイトルの直前に何も書き込まれないようにします。
1688行目 $ret.="";
そして、name属性値としたDID用のタグ<!--akiary_name-->
を追加します。
場所は「(3)最新版日記を変数上で作成」の1688行目 $tmp=$match;
と1697行目 $ret.=$tmp;
の任意の場所で認識しますが、「目次から記事へのリンク」で追加した年月とDIDのタグの後に書きました。
$tmp=~s/<!--\s*akiary_name\s*-->/name=\"$_\"/g;
aki2rss.cgiはRSS生成時に、記事の日時・日付・タイトル・本文が書き込まれるテキストデータ「new.txt」を参照するので、日時の部分(##entry##)にname属性値としたDIDの値が書き込まれるようにします。
このテキストデータの元になるテンプレートファイル(tmpnew.txt)を編集。
日時の部分の記事開始タグ後に、name属性値としたDID用のタグを追加します。
##entry##<!-- akiary_diary reverse latest_times="10" --><!--akiary_name-->
この結果、「new.txt」には次のように書かれます。
##entry##
name="20051007_000000000"
##date##2005年10月7日(金)
##title##タイトル
##body##本文
なぜかname属性値としたDIDは改行されていますが、データ参照には問題ありませんでした。
これでオプショナル日記である最新版日記と目次の個々記事直前に無意味な記述もなくなるので、テーブルを復活させることが出来ました。
2005年10月6日(木) 100点満点への道
HTML文法チェックで特に引っかかった点には、アンカー関連が目立ちました。
- <a>にはname属性とid属性の両方を指定するようにする。
- <a>のname属性値とid属性値は、同一タグ中では同じでなければならない。
- <a>のid属性値は、英字または_から始まる:を除く名前文字列(ID)でなければならない。
- <a>と<a>の間が空。
- <a>のアンカー名 `XXXX` 中に空白文字が含まれている。
「RSSの修正」、アンカーをname属性とid属性を用いて年月日とDID(DiaryID)を併用していたのですが、name属性値とid属性値が違ってしまいます。
かといって片方の属性値を削除すると、対応する年月日か時間が参照されず、RSSが扱う日時データのように記事の日付か時間が0の並びになってしまいます。
また、DID側を削除すると200510.php#
のようになり、個々記事へのリンクも切れてしまうため、最低DID側は削れません。
CGI作者のSample Akiaryの最新版日記ページを見ると、<a name="200510"</a><a name="200510_1234567890"</a>
のように年月日用とDID用のそれぞれのアンカーが2つ並んでいました。
その手があったかと、akiary.cgiのバックナンバー記事作成部分を書き換えました。
1688行目 $ret.="<a name=\"$date{$_}"</a><a name=\"$_\"</a>\n";
属性はnameでもidでも参照できるようaki2rss.cgiで設定されているのですが、idだと数字で始まるため減点になるのでnameを使用しました。
ですがソース的にスマートでないのと、「<a>と<a>の間が空」というエラーが増えるのが気になりました。
RSSの年月日はaki2rss.cgiで、
436行目 $$refanchor =~ m/\D(\d{8})\D\D+/;
と、アンカー中の年月日が書かれた8桁の数を探すようでした。DIDにもアンダーバーより前は20051006_0000000000
のように、年月日が含まれています。時間の取得はその下の項「# didを探す。」で、
440行目 $$refanchor =~ m/(id|name)\s*=\s*[\"\']?(\d{8})_(\d{9,10})[\"\']?/;
441行目 $date = $date || $2;
442行目 $time = $3;
443行目 $did = $2 . '_' . $3;
と書かれています。
$2に対応する部分がDIDの年月日部分なので、
436行目 $$refanchor =~ m/\s*[\"\']?(\d{8})/;
と書き換え、これを流用できるようにしました。
これでアンカーは1つで済むようになりました。
RSSは最新版日記のアンカーからnameまたはidを参照するようですが、日記上では個々記事へのリンクはバックナンバーのアンカーへ張っているので最新版日記の個々記事アンカーは使用していません。
それなら最新版日記に個々記事アンカーはRSS生成の事を考えなければ必要ないし、削ればアンカー関連のエラーも一気に消えます。
aki2rss.cgiをよく見てみると、アンカーが作成される部分のnameもしくはdid属性値からdidを探しています。
この部分をアンカーにせず、単純に属性値を表記させるようにakiary.cgiを書き換え。
1688行目 $ret.="name=\"$_\"\n";
aki2rss.cgiは無事didを取得しました。
日記ではこの部分が丸見えになってしまうので、cssで見えなくします。
1688行目 $ret.="<span style=\"display:none;\">name=\"$_\"</span>\n";
バックナンバーの個々記事アンカーには、「<a>と<a>の間が空」である問題が残っています。
アンカーの間に文字を入れるのには迷ったのですが、HTML文法チェックで高得点獲得のためにと思って決断(笑)。
akiary.cgiではバックナンバー記事作成で<--akiary_diary-->
の直前にアンカーが書き込まれます。name属性値はDIDにしています。
1405行目 print FH "<a name=\"$_\"></a>\n";
アンカーを別の場所に書くので丸ごとここは削ってもいいのですが、ソースを改行させたかったので書き換え。
1405行目 print FH "\n";
テンプレートファイルのカスタマイズにもよりますが、デフォルトでは個々記事へジャンプするとタイトル部分がページの最上部になります。
タイトルの文字列にアンカーを張っても同じ結果になるので、ここにアンカーが書かれるようにします。
1412行目 $tmp=~s/<!--\s*akiary_title\s*-->/
<a name=\"$_\"><!--akiary_title-->$bntitle{$_}<!--\/akiary_title--><\/a>/;
アンカー関連のCGI編集はひと段落です。
あとはテンプレートファイルでエラーの出た箇所を見直していきます。
tDiaryテーマ対応テンプレートのn3kitのテンプレートファイルは、bodyの最上部にtopのアンカーが書かれています。
<a name="top"></a>
「<a>と<a>の間が空」のエラーになるので、減点対象外のごく軽度のエラーである空白文字を入れるか、あるいはcssで見えなくなることを前提に任意の文字を入れておきます。
<a name="top" id="top" style="display:none;">top</a>
目次テンプレートは、記事一覧がテーブルで組まれています。
<table>
<!-- akiary_diary reverse latest_times="999" -->
<tr><td><!-- akiary_date --></td>
<td><!--akiary_title--></td></tr>
<!--/akiary_diary-->
</table>
記事が増えていくたびに、日付とタイトルの行が追加されていきます。
同時にアンカーも追加されるのですが、テーブル開始タグ<table>
と行開始タグ<tr>
の間に書き込まれてしまいます。
画面表示では解釈されずテーブルは作成されますが、HTML文法チェックでは「○○を<table>~</table>内に書くことはできない」のエラーが出ます。
取り敢えず、テーブルを使わずレイヤーで一覧を組みました。
「目次から記事へのリンク」も同時にさせています。
<!-- akiary_diary reverse latest_times="999" -->
<div style="float:left;"><!-- akiary_date --></div>
<div style="float:left;margin-left:0.5em;">
<a href="<!--akiary_bndate-->.php#<!--akiary_did-->">
<!--akiary_title--></a></div>
<br style="clear:all" />
<!--/akiary_diary-->
アンカーではなくしたname属性だけのname=20051006_0000000000
のようなDID記述は、個々記事の開始を表す<!-- akiary_diary reverse latest_times="999" -->
の次に書き込まれます。
<span style="display:none;">name=20051006_0000000000</span>
<div style="float:left;">年月日</div>
<div style="float:left;margin-left:0.5em;">
<a href="200510.php#20051006_0000000000">タイトル</a></div>
<br style="clear:all" />
DID記述はcssで見えなくなるようにakiary.cgiを書き換えています。
1688行目 $ret.="<span style="display:none;">$_</span>\n";
これが連続すると、下のように表示されます。
ここまでの作業で、最新版日記ページと目次ページは100点満点、アンカーのあるバックナンバーページは「<a> の属性 `name` はあまり薦められない属性です。id 属性を使いましょう。」と「<a> には name 属性と id 属性の両方を指定するようにしましょう。」のエラーが出るため97点と、高得点を獲得することが出来ました。
2005年10月5日(水) RSSが扱う日時データ
基本的な日記システムの構造が出来てきたので、ここいらでHTML文法チェックをしてみました。
最新版日記ページは最初「もうすこしがんばりましょう」の29点で、取り敢えず直せる部分に手を入れたら「ふつうです」の39点になりました。
直しにくい箇所は、Aタグが何も囲まないアンカー部分で、更にその中でname属性とid
属性の名前が違ってしまうところと、name属性は月日名のため、同日複数記事の場合に日付分同じname属性を持つアンカーが出来てしまうところです。
この3つの問題が1つでも解決できれば、記事数分点数が上がるはず。
なので出来るだけアンカーを使用しないでおけないものかと、akiary.cgiをいじっていました。
日記の更新に関しては、最新版日記のアンカーを削っても問題はありませんでした。
また、目次から記事へのリンクのためにアンカー用のタグを設定していましたが、これは最新版日記作成部分にあると機能することが分かったので、バックナンバー作成部分の記述は削除しました。
そしてRSS出力をしてみると、記事の日付と時間などが0000-00-00 09:00:00+09:00
のように全部0になってしまっています。
末尾の+09:00
は記事投稿時刻を日本のタイムゾーンで示している部分(GMT+9とも書く)で、時刻が9時になっているのもそのためです。
海外のブログサービスを使っていると、ローカルタイムゾーンで表現されて時間がおかしくなっていることがあります。
再び最新版日記のアンカーを復活させてみると、aki2rss.cgiはRSSを吐き出す時、アンカーの年月名で書かれたname属性を日記ファイル名、DID(DiaryID)で書かれたid属性を個々の記事名として参照していることが分かりました。
また、この2つのデータからRSSの日時も取得していました。
というわけで、HTML文法チェックでは大幅な減点対象になってしまうものの、最新版日記のアンカーは削れないのでした。
2005年10月5日(水) 汎用リンク作成
事始めとして、サイドバー項目の幾つかを外部呼出しにしてみたのですが、日記と違う階層に呼び出し先がある場合リンク切れになってしまうため、日記の場合は一旦上の階層に出て再び同じ階層に入るように、別コンテンツの場合は上の階層に出て任意の階層に入るように設定しました。
../日記URL
同じ階層に日記と別コンテンツを置いて、リンクが汎用できるようにしたわけです。今までもよく使っていた手ではありますが、文章にするとややこしいようで単純な方法です。
日記URLは日記設定ファイル(diary.cfg)に項目を追加して設定。
# 目次フォーマット: 日記URL
index_format_diary="../update/"
akiary.cgi側に、この項目が使えるようデフォルト値を設定。
84行目 # 目次フォーマット: 日記URL
85行目 'index_format_diary'=>'',
そして、オプショナル日記の<!-- akiary_index -->
の置換部分で、各月へのリンクに日記URLを入れ込みます。
1615行目 $index{$y} .= "<a href=\"$CFG{'index_format_diary'}$rp$_\">
$tmp</a>"
2005年10月4日(火) 目次から記事へのリンク
デフォルトの目次には日付とタイトルが並ぶだけなので、タイトルから記事へのリンクを作成しました。
akiary.cgiのバックナンバーと最新版日記の作成部分に、年月とDID(DiaryID)のタグを設定します。バックナンバーは1407行目以下、最新版日記は1689行目以下に追加。
# アンカー
$ym=substr($date{$_}, 0, 6);
$tmp=~s/<!--\s*akiary_bndate\s*-->/$ym/g;
$tmp=~s/<!--\s*akiary_did\s*-->/$_/g;
追加部分の解説をします。
$ym=substr($date{$_}, 0, 6);
Akiaryのデータベースを兼ねた月毎ファイル名は200510.html
のように年月名で作成されるので、年月の関数を$ym
とし、年月日の関数$date
から年月までの文字数をsubstr
で取り出します。
$tmp=~s/<!--\s*akiary_bndate\s*-->/$ym/g;
年月のタグを<!--akiary_bndate-->
とし、$ym
に書き込まれるようにします。
$tmp=~s/<!--\s*akiary_did\s*-->/$_/g;
DIDのタグを<!--akiay_did-->
とし、$_
に書き込まれるようにします。
目次のテンプレートファイル(tmpl_index.php)に記事へのリンクを作成します。
tDiaryテーマ対応テンプレートのn3kitに入っている目次のテンプレートファイルを流用したので、テーブルを使用しています。
<table>
<!-- akiary_diary reverse latest_times="999" -->
<tr><td><!-- akiary_date --></td>
<td><a href="<!--akiary_bndate-->.php#<!--akiary_did-->">
<!--akiary_title--></a></td></tr>
<!--/akiary_diary-->
</table>
記事タイトル<!--akiary_title-->
に、年月+拡張子+#+DIDで200510.php#200510_0000000000
のような形になるようにしてリンクを張ります。
2005年10月3日(月) RSSの修正
日記の拡張子をPHP化したことで、デフォルトのaki2rss.cgiから出力されるRSSで記事へはリンク切れになる点を修正しました。
407行目 return join('', ($ym, '.html#', $ym, $d));
↓
407行目 return join('', ($ym, '.php#', $ym, $d));
413行目 return join('', ($ym, '.html#', $did));
↓
413行目 return join('', ($ym, '.php#', $did));
431行目 if ($$refchunk =~ m|href\s*=\s*[\"\']?
(\d{6}\.html#\d{8})(_\d{9,10})[\"\']?|) {
↓
431行目 if ($$refchunk =~ m|href\s*=\s*[\"\']?
(\d{6}\.php#\d{8})(_\d{9,10})[\"\']?|) {
できればDID(DiaryID)へリンクを張りたかったのですが、プログラミングは手探り状態でして、頑張って探してもDIDを入れ込む方法が分かりませんでした。
CGI作者のページを見てみると、RSS中のリンクは年月日に張られ、記事毎のアンカーはname属性とid属性を用いて、年月日とDIDを併用していました。
作者がそうしているなら素直に真似するかと、akiary.cgiを再び修正。
1405行目 print FH "<a name=\"$bndate{$_}\"id=\"$_\"></a>\n";
1688行目 $ret.="<a name=\"$date{$_}\" id=\"$_\"></a>\n";
2005年10月2日(日) 改行をPタグへ
Akiary V.0.51とスクリプトの記述順が変わったこともあるので、改めて改行をBRタグからPタグへ修正する手順をメモ。akiary.cgiに手を加えます。
更新処理時に2つ続くBRタグをPタグに変換するよう、書き加え。
バックナンバーは、265行目以下。
264行目 $BODY{$dids[0]}=~s/<br><br>/<\/p><p>/g;
最新版日記は、298行目以下。
296行目 $BODY{$dids[0]}=~s/<br><br>/<\/p><p>/g;
そして編集画面でプレーンな表示に戻すため、644行目以下に書き加えます。
645行目 $body=~s/<\/p><p>/\n\n/ig;
これによって最初と最後の段落が最初の行</p><p>最後の行
のように開いたままのタグになる状態を回避するため、<p>最初の行</p><p>最後の行</p>
のように本文の前後をPタグで閉じるようにします。
バックナンバーは、本文の前後にPタグを挿入。$bnbody{$_}関数の直前直後にすると、編集画面で更新するたびに直接Pタグが追加されるようになってしまったのでakiary_bodyタグの直前直後に挿入しました。
1414行目 $tmp=~s/<!--\s*akiary_body\s*-->/
<!--akiary_body-->$bnbody{$_}<!--\/akiary_body-->/;
↓
1414行目 $tmp=~s/<!--\s*akiary_body\s*-->/
<p><!--akiary_body-->$bnbody{$_}<!--\/akiary_body--><\/p>/;
最新版日記はバックナンバーファイルから読み取られるので編集画面に影響はなくakiary_bodyタグの直前直後に挿入。
1696行目 $tmp=~s/<!--\s*akiary_body\s*-->/$body{$_}/g;
↓
1696行目 $tmp=~s/<!--\s*akiary_body\s*-->/<p>$body{$_}<\/p>/g;
2005年10月2日(日) 記事毎アンカー作成
akiaryが個々の記事に付けているperlの時間を表すDID(DiaryID)を利用します。
改装前はアンカーマークに設定したかったため複雑なことをやっていましたが、akiary.cgiにシンプルに手を加えました。
なお、デフォルト状態の行数ですが、エディタの幅で前後するので参考程度に。
1425行目の不可視タグを見ると、DIDは「$_」で扱われています。
バックナンバーのアンカーは、
1405行目 print FH "<a name=\"$bndate{$_}\"></a>\n";
↓
1405行目 print FH "<a name=\"$_\"></a>\n";
最新日記版のアンカーは、
1688行目 $ret.="<a name=\"$date{$_}\"></a>\n";
↓
1688行目 $ret.="<a name=\"$_\"></a>\n";
2005年10月2日(日) EUC-JP化
RSS配信にあたって改装前と同様、いしだなおとさん作「aki2rss.cgi」のお世話になることにしました。
頭から何文字という形で切り出される要約は、EUC版で行の切れ目で文字数を検査し自然な切れ具合らしいので、この際文字コードをEUC-JPにすることにしました。
まずは、全てのファイルのエンコードをエディタなどでEUC-JPに変換して保存します。
テンプレートファイルは、内部コードもエンコード指定を修正して保存。
Akiary.cgiは編集画面のエンコードが記述されておらず、ブラウザで開くと文字化けを起こします。そのため、867行目の後に一行追加します。
868行目 <meta http-equiv="Content-Type" content="text/html;
charset=EUC-JP">