[ # 2 ] C o u n t e r   ( N o   S S I )
Top > Entrance > Tutorial > [#2] Counter (No SSI)

Frame Counter Layer Counter HD Counter

 

  ●● Introduction ●●●●●
ミナ 前回、[ SSI ]ていうしくみを使って、アクセスカウンタを使ったじゃないですか。でも、SSI使えないけどオリジナルのカウンタを使いたい! ていう人が多いみたいなんです。
先生 ふむ。そういうコトもあろうかと思ってたよ。
そこで今回は、CGIチュートリアルという観点からはちょっとズレるが、ちょいとウラワザ的なテクニックを使ってカウンタを起動する方法を考えよう。しかも可能な限り前回のスクリプトに手を加えないラクなやり方でだ。
ミナ 先生ぇスゲエッス。ゴマカシ人生爆進中ッスね。
先生 だんだん台詞キツくなってきたな〜〜〜。




  ●● [A] Frame Counter ●●●●●
先生 さて。まずは<FRAMESET>タグを使用したやり方だ。
ミナくん、フレームタグは知ってるかね?
ミナ は、はい。アレですよね、ブラウザ上の表示エリアをいくつかに分割して、ナビゲーションのページと内容のページを分けたりとかする・・・。
先生 うむその通り。ちょっと別の話になるが、ピクセルレベルでの正確な画像の配置をしたい場合なんかも、上下左右にサイズ可変のフレームを切って内容の部分のサイズをきっちり一定にする、なんてテクにも使えるアレだ。
例えば上のフレームにサイトナビ、下にメインの内容を表示したいといった場合、ナビを表示するHTMLファイル、内容部分のHTMLファイルに加え、フレームを定義するHTMLファイル、の3つが必要になる。
ミナ ふむふむ。その3つのファイルで、1ページを表示するんでしたよね。
先生 で、大抵の場合、カウンタを設置するのはサイトのトップ、つまり(基本的に)「index.html」というファイルの中に表示することが多いよな? そこで、このindex.htmlをフレーム定義ファイルにする。フレームを上下に切り、上をサイズ可変、下を固定値(カウンター画像の高さに数ピクセル足したぐらいが妥当)にする。
ミナ ほほう。トップページからイキナリフレームですか。
先生 そして、ちゃんとした普通のトップの内容を記述したファイル(本来ならindex.htmlとなるべきファイル)を、まあtop.htmlとでもしておこうか。それをフレームの上部に当て、フレーム下部にはさっき作った[ count.cgi ]を当てるんだ。こうすればメインの内容と同時にカウンターのスクリプトも読み出せる。
ミナ ホントだ、カウンターが出た! へええなるほどお。でも数字が左端によっちゃってますよ?
先生 イメージ出力の際にセンタータグをかけていないからな。
これはスクリプト側を修正するしかない。数字をセンターに出したいなら、さっきの[ count.cgi ]19行目以降を以下のように修正するといい。


19 #表示
20 print "Content-type: text/html¥n¥n";
21 print "<center>";
22 foreach $key ( @counter ){
23 print "<img src=¥"images/$key.gif¥">";}
24 print "</center>";

21行目でセンター開始、24行目で終了しているので、ちょうど真ん中にカウンタが来る。
ミナ あっ今度は真ん中に来ました! フレームの切り方工夫すれば、いろんな見せかたが出来そうですね!
先生 そうだな。その辺はもうこのサイトの範疇外なのでホームページを作る人自身にがんばってもらいたい。
最後に、この「フレームカウンター」のHTMLソースを参考までに示しておこう。

[ index.html ]

<html>
<head>
<title>[#2-A] フレームカウンター</title>
</head>

<frameset rows="*,40" frameborder="NO" border="0" framespacing="0">
<frame name="mainFrame" src="top.html">
<frame name="bottomFrame" scrolling="NO" noresize src="count.cgi">
</frameset>

</html>




  ●● [B] Layer Counter ●●●●●
先生 次の方法だ。ミナくん、「レイヤー」というのは知ってるか?
ミナ えいやあぁぁっ!!!
先生 ハッキリ言ってサッパつまらんし。
「レイヤー」というのは、もともと画像系のソフトなんかにあった概念で、一枚の絵の上に透明なシートをかぶせて、下の絵に影響なく絵を描ける、と言うやつだ(漠然とした言い方だが)。
ミナ ああハイハイ! アレですね、良くアニメなんかの「セル画」に例えられるヤツですよね。
先生 そうそう。画像系ソフトでは必須の機能だけど、なんとこのしくみがヴァージョン4以上のブラウザでも採用されてきたのだ。(この「デジタル・シュリーマン」でも入口のページなどで使用してる)
で、ココで紹介するのは、その「レイヤー」からCGIを起動してしまおうというもの。
ミナ そ、そんなコトが出来るんですか?
先生 うむ。ただし、タグの扱いの関係上、これは「Netscape」ブラウザ(ナビゲータ4以上)でしか動作しない。そのかわり、IEには「フローティングフレーム」というしくみがある。概念的には良く似ているので、まとめて解説していくぞ。
ミナ はあ。でもなぜIEのレイヤーではダメなんですか?
先生 なぜかというと、普通レイヤーを貼るのに使うタグは<DIV><SPAN>のどちらかなんだけど、ネスケの場合は「拡張タグ」というやつで、<LAYER><ILAYER>と言うタグでレイヤーを貼るんだ。で、この2つのタグは、なんとそのレイヤーの中身として外部ファイルを読み込めるんだが、<DIV><SPAN>はそれが出来ない。
一方、「フローティングフレーム」ていうのはIEの拡張タグだから、ネスケでは認識されない。レイヤーのように「一枚上」に書かれるものではないが、まあ外部ファイルを中身に指定できるというイミでは使い方にはそんなに差がない。
ミナ じゃあ、クライアントの環境を考えて、同じHTMLファイル内に「レイヤー」も「フローティングフレーム」もどっちも記述しておく、てのはアリなんですか?
先生 アリアリだよ。むしろそうすべき。良いコトに気付いたね。
と言うコトで、2つの記述のサンプルを下に書いておこう。
前提として、16(横ピクセル)*30(縦ピクセル)の数字画像を6桁並べる(画像全体としては16(横ピクセル)*6(桁)=96ピクセル)カウンタを想定して記述する。

[ Netscape (<Layer>)]

<layer id="Layer1" left="312" top="480" width="96" height="30" z-index="1" src="count.cgi">
</layer>


【属性解説】
id レイヤーの名前。カウンターのためだけに使うなら適当で良し。
left レイヤーの左端をブラウザの絶対座標でドコにするか。
数字をいろいろいじってみて最適な場所を見つけてくれ。
top レイヤーの上端をブラウザの絶対座標でドコにするか。
これも前述と一緒。
width レイヤーの横の幅。今回のケースでいえば96
height レイヤーの縦の幅。今回のケースでは30になる。
z-index レイヤーのレベル(水平)的高さ。
複数のレイヤーを使わなければ1で良い。
src レイヤーに読み込みたいファイルを指定。
ココでカウンターのスクリプトを指定するのがキモだ!!

[ IE (<IFRAME>)]

<iframe width="96" height="30" align="center" marginwidth="0" marginhright="0" scrolling="no" src="count.cgi">
</iframe>


【属性解説】
width フレームの横の幅。今回のケースでいえば96
height フレームの縦の幅。今回のケースでは30になる。
align 位置あわせ。考え方はテーブルとかと一緒。
marginwidth フレームの中身と、フレームの横端との間のマージン。
今回のケースでは0が好ましい。
marginheight フレームの中身と、フレームの縦端との間のマージン。
今回は明示的に(省略せず)0とした方が見た目が良い。
scrolling スクロールバーを表示するかしないか。
しないほうが良いに決まってる。
src フレームに読み込みたいファイルを指定。
ココでカウンターのスクリプトを指定するのがキモだ!!

先生 でだな、これは最近調べてみて解ったんだが、最新版の[ Netscape 6 ]では、なんと今までサポートしていた<layer><ilayer>タグをサポートしなくなった。そのかわり、これまでIEの拡張タグだった「フローティングフレーム」をサポートするようになったのだ。
ミナ ええっ!? てコトはあ、同じネスケでもヴァージョンで見え方が変わるってコト?
先生 そうなんだよ。これには私も驚いた。つまり、現状を整理すると、

機能名(<タグ>) 対応ブラウザ
フローティングフレーム(<iframe>) IE4 / IE4.5 / IE5 (IE5.5未確認) / N6
レイヤー(<layer><ilayer>) NN4 / NC4.5 / NC4.7

となる。
したがって、基本的にはフローティングフレームでスクリプトを起動し、<iframe>を認識しないブラウザ(つまり表中下段のブラウザ)はレイヤーでスクリプトを起動する、というやりかたが一番良さそうだ。
ミナ そんなコト出来るんです? どうやるんですか?
先生 ふむ。じゃあ四の五の言う前にソースを見てもらおうか。

[ IE & NN(NC) Compatible ]

<iframe width="96" height="30" align="center" marginwidth="0" marginhright="0" scrolling="no" src="count.cgi">
  <layer id="Layer1" left="312" top="480" width="96" height="30" z-index="1" src="count.cgi">
  </layer>
</iframe>

ミナ ・・・これだけ? <iframe>の間に<layer>がまんま入ってるだけじゃないですか。
先生 うむその通り。だがこれでイイのだ。
こう記述すれば、まずは<iframe>を試し、それがダメだった場合<layer>を出力する、というふうにできる。
これで、IE/NN(NC)どちらにも対応するレイヤーカウンターが作れるってワケだ。
ところで、レイヤーがXY位置をピクセルレベルで指定できるという特性上、<body></body>タグの間のドコに記述してもいいことになってるのに対し、フローティングフレームは普通の画像やテーブルと同じように表示したい位置(ソース的な位置)にタグを記述することになる。
ミナ てコトは、フレームって言っても、ただ外部ファイルを読み込めるテーブル、ぐらいに考えたほうが良いんですかね?
先生 まあそんなところ。HTMLには強いのねミナくん。




  ●● [C] HD Counter ●●●●●
先生 では今回取り上げる最後の方法だ。ここでは「ヒアドキュメント」というしくみを使う。
ミナ ヒアドキュ? はじめて聞きます。HTML関連ですか?
先生 いや、これは純粋にPerlの技術だ。
今までいくつかのスクリプトを見てきたが、どれも最後の方でHTMLを「埋め込ん」で最終的にブラウザに出力したよな。
ミナ はいはい、なんか普通の記述よりやたらごちゃごちゃしてたアレですよね。¥とか¥nとかついてる。
先生 そうそう。PerlHTMLを埋め込むときはああいうふうにせざるを得ないと言ったが、逆に言えば、ああいうぐちゃぐちゃした書き方を努力で成し遂げられるなら、基本的に普通のHTMLを全部CGIから出力することだって不可能じゃない。
ミナ えええ〜〜〜。わたしにはそんな忍耐力はないですよう。
先生 そんなコトはハナから解っとる。極端な話をしただけだ。
でも、¥nとかPerl特有のややこしい決まりごとが無く、普通にHTMLを記述するようにPerl内でも書けるとすれば、ちょっとはラクかなって思うだろ?
ミナ それだったらHTMLエディタ使ってもいいですしねえ。
先生 ちょっと乗り気になってきたな。
それを実現するのが、この「ヒアドキュメント」というしくみだ。
実例を上げてみよう。
(文例)
print <<HTML;



HTML
という記述。
これは、[ <<HTML ]から文末の[ HTML ]に含まれる記述をまんま出力してください、というイミになる。
つまりこの間に普通のHTML文を貼り付ければ、CGIの処理の流れでHTMLを出力してくれるというわけ。
ミナ え? え? 良く解んない。
先生 ふむ、つまり「ヒアドキュメント」というのは、本来[ print ]文なんかを多用しなきゃいけない文章の出力やHTMLの出力と言った煩雑な記述を簡略化する技術で、[ <<****; ](****の部分は任意だが、大文字で書いたほうがよろしい)から[ **** ]までの部分を書いたまんまに出力してくれる技術。
・・・良し、さらに解りやすい例を出そう。
(文例)
print "<font color=¥"#FF6666¥">わたしはミナ・マインケです。¥n";
print "CGIの勉強中です。¥n";
print "応援してくださいね。あくまでそれなりに。</font>¥n";
という文字列を出力するCGIスクリプトがあるとする。
[ print ]3回もあるし、「エスケープ」するために¥記号が増えてしまって煩雑だよな。
ところがコレを、「ヒアドキュメント」を使って記述すれば、
(文例)
print <<MINNA;
<font color="#FF6666">
わたしはミナ・マインケです。
CGIの勉強中です。
応援してくださいね。あくまでそれなりに。 </font>
MINNA
というふうに書ける。随分すっきりするだろ?
「ヒアドキュメント」てのはこういうことだ。
ミナ へえなるほど。[ Print ]から最後の[ MINNA ]の間に入ってるのだけ見れば、確かにタダのHTML文ですね。
先生 な。イッキに書きやすくなったろ。[ print ]が続く場面では積極的に使いたい技術だ。
ミナ でも実際、今回のカウンターのケースではどういうふうにすればいいんです?
先生 ふむ。要するに、前回作った[ count.cgi ]の最後のHTML出力部分(19行目以降)に、何食わぬ顔して好きなようにHTML文を書いてやって、カウンターを設置したい場所の手前で「ヒアドキュメント」を閉じ、カウント画像を出力して、その後HTMLを閉じるのにまた「ヒアドキュメント」を使えばとてもクールだ。
口で言ってもしょうがないから、簡単なデザインのHTMLページを「ヒアドキュメント」で[ counthd.cgi ]に埋め込んだ場合のソースを見てみよう。

[ counthd.cgi ]

1-18行は[ count.cgi ]と同じ
   
19 #HTML表示
20 print "Content-type: text/html¥n¥n";
21 print <<HEAD_AND_BODY;
22 <html><head><title>ミナのホームページ</title></head>
23 <body><center><font size=5 color=ff3333>
24 ようこそミナのホームページへ!</font><br><br>
25 <font size=2 color=ff0000>
26 あなたは
27 HEAD_AND_BODY
   
28 #カウンター出力
29 foreach $key ( @counter ){
30 print "<img src=¥"images/$key.gif¥">";}
   
31 #残りのHTML出力
32 print <<END_OF_HTML;
33 人目のお客様です。</font></center></body></html>
34 END_OF_HTML

※行番号は便宜上表記しているだけです。 実際のスクリプトには行番号はつきません。

ミナ なるほどお、解ってきましたよ。21行目から27行目がカウンターの前の部分のHTMLですね?
先生 そうそう。27行目でいったんヒアドキュメントを閉じて、28-30行でカウンターを動かし、31行からでHTMLを閉じる、というしくみだ。
ミナ これなら、HTML文の最初と最後に宣言(という言い方するのかどうか解らないけど)するだけで良いんですから、相当凝ったページでもCGIから出力できちゃいますね!
先生 うむ。まあ、理論的にはな。
ミナ え? なんですその引っ掛かるような言い方?
先生 良く考えてみてくれミナくん。基本的にサーバってのは複数の人間で共有してるだろ? 自分のところでWebサーバを運営していない限りは。
そうすると、CGIを動作させるということはそれだけでサーバにある程度の負荷をかけるわけだから、他の人の迷惑を考えるとなるべく「小さい」スクリプトの方がいいよな。
けど、調子に乗ってヒアドキュメントを使いまくって、凝りに凝りまくったHTMLを埋め込んだCGIを作ると、実行にすごく(と言ってもコンマ何秒のレベル)時間がかかる。
したがって、ココまで期待させといてホント申し訳ないが、正直言ってこのヒアドキュメントを使って普通にHTMLを(ページ丸ごとぐらいのレベルで)表示させようというのは、ハッキリ言って好ましくない。
ミナ えええ。そうなんですかあ?
先生 だから、可能な限り最初に説明した「フレームカウンター」か「レイヤーカウンター」を使うようにしてくれ。
「ヒアドキュメント」は「こういうやり方もあるよ」ぐらいに考えてもらいたい。もともと長いテキストをprint文で出力する手間を省くための技術だしな。
ミナ は〜い。でもこれで、[ SSI ]のない人もアクセスカウンタを使うことが出来ますね!
先生 そうだな。ホントは<img>タグを使うなどもっと違うやり方もあるが、スクリプトを大幅に変更しなくてはならなくなるので、非常に厄介。「小手先のテクニックでゴマかす」という趣旨に反するからな。
ミナ さてさて、次はどんなゴマかしが見れるのかな〜〜〜。
先生 ナニを期待しとるかっ。


< Back to Index
[ Sample ]