Wikiってあんまりちゃんと触ったことないなぁ・・・
というわけではてなの人や多くのWiki制作者に多大な影響を与えたYukiWikiのコードを読んでみよう。
http://www.hyuki.com/yukiwiki/
まずはminiから・・・
解凍してみる。ファイルは4つしかない。
[mikeda@cent ykwk]$ unzip ykwkmini_102.zip Archive: ykwkmini_102.zip inflating: ykwkmini.cgi inflating: .htaccess inflating: ykwkmini.txt inflating: jcode.pl
CGI本体はykwkmimi.cgi。先頭のperlのパスは必要に応じて修正。
改行コードがCrLfなので修正しておく。
そのままだと「Premature end of script headers」というエラーがでる。先頭のperlの後に「 -」を足すだけでも可。
[mikeda@cent ykwkmini]$ cat -A ykwkmini.cgi #!/usr/bin/perl^M$ #^M$ # YukiWikiMini Version 1.0.2^M$ .... [mikeda@cent ykwkmini]$ perl -i -pe 'tr/\r//d' ykwkmini.cgi [mikeda@cent ykwkmini]$ cat -A ykwkmini.cgi | head #!/usr/bin/perl$ #$ # YukiWikiMini Version 1.0.2$ #$ ...
それじゃCGIの中身を見てみよう。定数宣言の後に以下のコード。
フォームデータと保存データの定義。jcode.plの読込み。main関数の実行。終了。
my %form; my %database; require 'jcode.pl'; &main; exit(0);
メイン関数はこんな感じ。
sub main { &init_form; &sanitize_form; foreach (keys %form) { if (/^($WikiName)$/) { $form{mycmd} = 'read'; $form{mypage} = $1; last; } } unless (dbmopen(%database, $dbname, 0666)) { &print_error("(dbmopen)"); } $_ = $form{mycmd}; if (/^read$/) { &do_read; } elsif (/^write$/) { &do_write; } elsif (/^edit$/) { &do_edit; } elsif (/^index$/) { &do_index; } else { $form{mypage} = $frontpage; &do_read; } dbmclose(%database); }
まずは最初に呼ばれてるinit_form関数。
sub init_form { my ($query); if ($ENV{REQUEST_METHOD} =~ /^post$/i) { read(STDIN, $query, $ENV{CONTENT_LENGTH}); } else { $query = $ENV{'QUERY_STRING'}; } my @assocarray = split(/&/, $query); foreach (@assocarray) { my ($property, $value) = split /=/; $value =~ tr/+/ /; $value =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg; &jcode'convert(\$value, $kanjicode); $form{$property} = $value; } }
- クエリストリングの読込み。POSTの場合は標準入力から、GETの場合は環境変数から。
- フォームデータの取り出し。(クエリストリングを&でsplit)
- コントロール名と値に分割。(=でsplit)
- URLエンコードを復元
- 「+」を半角スペースに
- 「%16進文字コード」を文字に戻す
- 文字コードを変換
- ハッシュ(%form)にセット
今日はここまで。