管理 | 差分 || 新規作成 || カテゴリ一覧 | ページ一覧 | 更新履歴 | 差分履歴 || アンテナ || PUT || more≫ ≫omit
shortcut: FrontPage || WikiLab | StoreRoom/最新 | 日々の泡 | むず痒いパソコン日記/最新 || HelpPage ||[edit]
category: WebsiteWork/CgiPerl/KoroboRoom

WebsiteWork/CgiPerl/KoroboRoom/3 - 検索・過去ログカスタマイズ編。2002/11/27-2002/11/28

LastModified :
[管理]

検索・過去ログカスタマイズ編。2002/11/27-2002/11/28

| むず痒いパソコン日記 | WebsiteWork | WebsiteWork/CgiPerl || 関連ページ:KoroboRoom |

2002/11/27(wed)(深夜というか早朝)

[TOP↑] [管理]

ほとんど申し分のない korobo だけど、一つだけ不満がある。せっかく検索する項目など条件など絞り込めるのに、ヒットした発言が一つだけ表示されて、スレッド全体を見るには過去ログに行かなくてはいけない。過去ログも検索も「ひと月ずつ」しか表示できないので、これなら最初から過去ログをブラウザの検索機能で検索するほうがずっと早い。どうせ一月分のログなんて大した量じゃないんだし。

よく行く掲示板は KENT WEB の [Web Forum] というのを使っているんだけど、これは [関連記事] というスレッド全体へのリンクがあって、とても便利。これをなんとか korobo でもできないかしら。スレッドを切り出して表示するのは面倒というか私には難しそうだけど、[過去ログ]画面の各記事に a タグの name 属性に $num で属性値を付けておいてジャンプできるようにすればいいんじゃないかしら。

まずは、メインの CGI にある、過去ログ用と検索用のテンプレートをごそっとコピーして、[past.html]と[retrieval.html]というスキンを作る。過去ログ用のスキン、[past.html] の [$num] の部分を <a name="$num">[$num]</a> に書き換える。ところでこの過去ログ表示のテンプレート、例によってテーブル3重構造で外側を大きなテーブルで括ってある。これは書き換えたほうが表示が早くなるかもしれない。 ま、その辺は後でやるとして、次はいよいよ [retrieval.html] のカスタマイズ。

過去ログの URL は、[form=$form_name&option.mode=past&date=??????]。 ?????? のところはファイル名に含まれる「年・月」の6桁の数字。メインのCGIを漁ると [$year$month] で生成できるらしい。 [$date] のヨコに [<a href="$script?form=$form_name&option.mode=past&date=$year$month#$num">過去ログ[$num]へ</a>] というリンクを添える。

さて、これで「過去ログ」はまんまと巧く行った。問題は現行ログだ。現行ログには、当然 [$year$month] では飛べない。せめて、現行ログのときはこのリンクを表示しないように出来るといいんだけど、「もし、現行ログなら、リンクを表示しない」というのをお願いするにはなんて書けばいいんだろう。

ログを選択するセレクトボックスは [$files] で生成されている。現行ログは [current] ということになっているらしい。「もし、$files に current が含まれていたら」? 本によると文字列の検索は

[index 検索対象, 検索文字列, (検索開始位置)]らしい。 
* * *

ここまでにしてもう寝ようと中断してしばらく、現行ログを過去ログのテンプレートに流し込めないかと考えつく。でももう寝るのだ。

2002/11/27(wed)(お昼)

[TOP↑] [管理]

寝る前に思いついた「現行ログを過去ログのテンプレートに流し込む」を実験する。データファイルの名前から、[date=bbs]でアクセスしてみる。成功。と、いうことは、「最終返信の日付」に倣って、

スクリプト部分。

$log_dat = index $files, current;<ここ適当。
---------------
if ($log_dat = true なら) {<とても適当。
$log_dat_link = "<a href="$script?form=$form_name&option.mode=past&date=bbs#$num">ログ[$num]へ</a>";
} else {
$log_dat_link = "<a href="$script?form=$form_name&option.mode=past&date=$year$month#$num">過去ログ[$num]へ</a>";
}
---------------
html部分。
$log_dat_link

でいいんじゃないですかね?

と、適当な部分を含みつつ考えていて、気が付いた。 「$files に current が含まれていたら」じゃダメなんじゃないの? $files はセレクトボックスの option を生成してるわけで、セレクトボックスには常に、現行ログである[value="current"] が含まれている。 「選択された $files が current なら」と書かなくてはいけないんじゃないの? …で、ソレはどう書けばいいのでしょうね…。

2002/11/28(thu)

[TOP↑] [管理]

懸案の、「選択された項目が、"current"だったら」の件。

最初はとりあえず昨日考えていたスクリプトを試してみる。 巧く行かないのは覚悟の上だったが、巧く行かない方向が違っていた。いきなり InternalServerError。 …なんで? なんでも何も、ダブルクォーテーションをエスケープするのを忘れてた。 上の適当スクリプトを見ても、忘れてます。

さて、[\]を4つばかり書き込んで再チャレンジ。 巧く行かないのは覚悟の上だったが、巧く行かない方向が違っていた。 予想では全て現行ログへのリンクになるはずだったんだが、暗に相違して、全て過去ログへのリンクになってしまった。なんで? よくわからない。でも、何にしてもこの方法がダメなのは了承済み。

さて、「選択された項目」ってのはどうやって調べるんでしょうね。 パラパラと手元の本をめくると、「フォームの入力内容が数値かどうかチェックする」というスクリプトを発見。

…似てる…。

お手本は、こう。

&ReadParse(*input_data);
$year = $input_data{'year'};
----- 中略 -----
if($year = ~/[^0-9]/){
&ystatus = 1;
}
----- 中略 -----
print "数値かどうかチェックする";
if($ystatus==1){
print "年に数値以外の値が入っています";
----- 後略 -----

入力された文字列はPOST形式でWebサーバーに送られ、「cgi-lib.pl」のサブルーチンである ReadParse サブルーチンで連想配列 %input_data に格納されます。この %input_data からフォームでの name 属性の値になっている「year」、「month」、「date」という文字列をキーワードにして、ユーザーが入力した文字列をそれぞれ変数 $year、$month、$date に格納します。

1行目に何が書いてあるのか知りたかったのだが、全く何のことか解らない。 「連想配列」ってなんだよ。「配列」っていうか、列というほどのこともなく、current 一つでいいんだけど、そういうこととは関係ないの? 一応「連想配列」のページに目を通す。全く何のことか解らない

こういう説明って「なんとなく」でも解り始めてから読むと「なるほど」と思うし、「確かにこれ以外に説明のしようがないよね」と思うんだけど、全く何も解らないうちに読むと、本当に何のことか解らない。 解らない言葉をそれからそれへ調べ始めても、無限ループに陥ってしまうだけ。 理解してからやろうなんてのは甘い、体で覚えろ

機械には機械的に当てはめてやるまでだ。とにかく、{'year'}のところに、こっちの都合に合わせてセレクトボックスの name の属性値 log を押し込める。

&ReadParse(*input_data);
$log_dat = $input_data{'log'};

こんなもんか。…で、ところでコレを、この場合、どこに書けばいいのでしょうね。 「最終返信の日付表示」の時はなんかバラして書いてましたが。 メンドくさいので、一塊にして <!-- CHOP --> の下に放り込んでみる。

経緯を簡略化して言うと、巧くいかなかった。今度は全て現行ログへのリンクになってしまった。 やっぱりダメかとしばらくウロウロ。再びチャレンジ。 今度はエラー。よく見ると ReadParse のスペルミス。再チャレンジで成功したというわけだ。 最初に巧く行かなかったのが何でかはよく解らない。 どうせ、またしても毎度おなじみ タイプミスなんだ。 ともかく、完成したのは、以下。

&ReadParse(*input_data);
$log_dat = $input_data{'log'};
if ($log_dat == "current") {
$log_dat_link = "<a href=\"$script?form=$form_name&option.mode=past&date=bbs#$num\">▼ログ[$num]へ</a>";
} else {
$log_dat_link = "<a href=\"$script?form=$form_name&option.mode=past&date=$year$month#$num\">▼過去ログ[$num]へ</a>";
}

それにしても、タイプミスは「あてずっぽうスクリプト」の大敵だ。 巧く動かなかったりエラーが出ると、てっきり「根本的」に間違っていると思ってしまう。 でも今のところ、多分 3割は、タイプミスのせいなのだ。

* * *

ちょっと変更。現行スレッドをムリに過去ログのテンプレートに流し込まなくても、「返信画面」に飛ばしたほうが親切だと思った。 というわけで、上のスクリプトの4行目変更。

$log_dat_link = "<a href=\"$script?res_num=$num&form=$form_name&mode.thread=1\">▼現行スレッドへ</a>";。 

ただし、これ気を付けないと、「スキンのHTMLがない」と言われる場合が出てしまう。 もちろん、[view]しかない場合は最初のを使う。 [view]と[res]のスキンが一対になってる場合は特に気にすることはなし。

気をつけるのは、例えば、[bbs.view][bbs_subjeclist.view][bbs.res] なんて風に、 必ずしも[view]と[res]のスキンが一対になっていない場合。 対になる返信画面のない [bbs_subjectlist.view] に [検索] へのリンクをつけるときは、 変数でなく[form=bbs]と明示しないと、[▼現行スレッドへ]行こうとして[bbs_subjectlist.res.html]が見つからない、ということになってしまう。 ついでに、検索画面と過去ログ画面、お互いにリンクを張ったので、[過去ログ]>[検索]と辿られた場合のために、[過去ログ]のリンク先も[form=bbs]とする必要がある。

…まあ、[bbs_subjeclist.view] から検索に入って [back to bbs] で戻ろうとすると [bbs.view] に出てしまうという弊害はあるが、「スキンがない」という事態よりはマシ、ということで 気にしてはいけない。 もちろん、複数の掲示板で検索画面や過去ログ画面を使いまわすのでなければ、一つ一つリンクを明示すればいいだけだけど、ウチの場合は既に、辞書と外部CSSの4つのファイルを含めて、38ものファイルが skin ディレクトリにひしめいているのだった。

* * *

さらにちょっとヘマの修正。 id でディレクトリを指定してるので、

[$script?res_num=$num&form=$form_name&id=$log_id&mode.thread=1]

でないとダメだった。ついでに、

$log_dat_link = "<a href=\"$script?res_num=$num&form=$form_name&id=$log_id&mode.thread=1#[$num]\">▼現行スレッド[$num]へ</a>";

に変更。

ところで今、ハタと思い出した。リンク内の[&]も[&amp;]にしないといけないんだっけ? う〜ん、めんどくさい。修正は後日。 というわけで単語登録しました。[あm]で[&amp;]に変換。

| むず痒いパソコン日記 | WebsiteWork | WebsiteWork/CgiPerl || KoroboRoom2へ | KoroboRoom4へ |

shortcut: FrontPage || WikiLab | StoreRoom/最新 | 日々の泡 | むず痒いパソコン日記/最新 || HelpPage || [edit]
select css: default | sakura | mono | greenheck | snow | NN4.x用(多分) || LinuZau!! | VikiWiki!? || others |

管理 | 差分 || 新規作成 || カテゴリ一覧 | ページ一覧 | 更新履歴 | 差分履歴 || PUT