SSIを使ったメニュー

2002年11月のiswebサービス改定に対応

今回2191空挺団のホストとしてiswebを選んだのは、このサーバーがSSIを開放しているからです。SSIはServer Side Includeの略で、サーバー側がHTML文書のしかるべきところにしかるべき文書を挿入する機能です。

こういう仕掛けが欲しかったのは、全部のページにナビゲーション用のメニューをつけてみたかったからです。もちろん各ページにナビゲーションメニューをペーストしていけば済むことですが、このやりかたでは一ページ増やすごとに全ページ書き換えになります。当然、こんなことはしたくありません。

こういう手間を省く仕掛けとしてフレームが有ります。フレームはコンテンツとナビゲーションを別のHTML文書とし、表示するときに別々の枠に表示することで見た目を一枚の文書にします。

しかし、この方法は余りよくないことも有ります。例えば直リンクを張られると、こちらが期待した通りの見栄えになりません。そのページを基点とした自由なナビゲーションを出来ないわけです。

そこでSSIを使ってみようと考えました。SSIは対応するサーバーが少ないですが、サーバーさえ対応すればきれいな解決方法です(そのつもりでした)。

SSIの仕組み

私はファイルの挿入(インクルード)以外に興味が無いのでその点だけ説明します。SSIを使う場合は次のような命令をHTML文書に入れておけば、サーバーが勝手に指定するファイルをその部分に挿入してくれます。

<!--#include file="navigator.ssi" -->
<!--#include virtual="/root/foo/navigator.ssi" -->

この命令はHTMLからみるとコメントなのでHTMLエディタを混乱させることはありません。ここでnavigator.ssiは挿入されるファイルです。<!--から始まって-->までがnavigator.ssiの中身に置き換えられます。したがって、navigator.ssiの中に共通メニューを書いておけばSSIを使ってファイルを挿入するすべてのHTML文書に同じメニューを表示することが出来ます。

挿入ファイルは誰が書く

最初に考えたのはこれでした。私が使っているホームページ・ビルダーにはHTMLファイルの集まりをサイトとして管理する機能が有ります。このおかげで、ファイルを違うフォルダーに移すと、そのファイルの中のローカルリンクとそのファイルへのリンクを自動的に修正してくれます。このおかげでどれだけ助かったかわかりません。また、ローカルリンクを張るときにもマウスでドラッグ&ドロップできます。

ですから挿入するメニューもホームページ・ビルダーで書くことができればそれに越したことはありません。ところが、問題は挿入ファイルは完全なHTMLであってはいけないということです。挿入するべきファイルはHTMLファイルの中に組み込まれますので、<HEAD>や<BODY>といったタグは余計です。しかし、ホームページ・ビルダーはそんなことはお構いナシです。

結局ホームページビルダーで作ったメニューから自分で必要な部分を抜き出してテキストエディタにコピーし、挿入ファイルを作ることにしました。こいつに.ssiという拡張子を付けています。ホームページ・ビルダーでこれを編集すると<DOCTYPE>を付けてしまいますが…勘弁して。

基点はどこだ

ssiのインクルード命令には二種類有ります。一つはfile形式、もう一つはvirtual形式です。前者はメニューをHTMLファイルと同じディレクトリからしか読み込めません。これは痛い欠点です。サイト全体で共有したいメニューがある場合、すべてのファイルを同じフォルダに集めるか、メニューをすべてのディレクトリに配布することになります。前者は問題外、後者は馬鹿馬鹿しいのでやめました。

後から考えるとこれは軽率でした。

もうひとつのvirtual形式ですが、これは仮想ルートからのパスで読み込むファイルを指定します。仮想ルートは一般にはサーバーソフトがwww.foo.com/~bar/やwww.foo.com/に設定します。「どっちだよ!」と思ったのですが、実験すればいいのですぐにどうでも良くなりました。

結論から言うと、iswebでは仮想ルートはサーバー(が公開しているツリー)のルートです。2191空挺団はURLがhttp://adsp2191.hp.infoseek.co.jp/ですから、仮想ルートはadsp2191.hp.infoseek.co.jp/ です。したがって、HTMLファイルの中の#includeコマンドに与えるパスは、すべてここを基点としたパスになります。例を挙げれば、

"/ssi/navigator.ssi" 

のようにします。

基点はどこだ2

共通メニューの中のURLを考えてみましょう。メニューの中に完全なURLを書くことはまずありません。なぜならローカル・ファイルへのパスだからです。しかし、共通メニューが置かれるディレクトリとそれが読み込まれるHTMLのディレクトリは違います。と、いうことは共通メニューの中のパスは、あらゆるローカル・ディレクトリから使うことを想定しなければなりません。

この結果、共通メニューの中では相対パスは使えず、絶対パスを使うことになります。他のサーバーはどうか知りませんが、iswebでは絶対パスのルートは上述の仮想ルートと同じでした。したがって、テキストエディタで共通メニューの中のパスを書き換えるときは、先ほど同様の指定になります。例としてトップ・ページを指し示すときには、

"/index.shtml"

としておきます。

広告が出ない

通常のサーバーならこの作業できちんとした文書が表示されるようになります。ただし、SSIを施すための設定はサーバーによって違います。iswebの場合拡張子が.shtmlでなければなりません。いずれにせよ、これで共通メニュー化はおわります。

ところが、iswebの場合.shtmlで#includeを使うと広告が消えます。これでは追い出されてしまいます。そこで、サポートセンターのFTP, CGIの設定についてにあるタグを手書きで挿入して解決しました。

なお、私のサイトは他のサイトのようなきれいな広告が出ません。サポートセンターからは「正常表示されている」とそっけない返事が来ましたのでこれでよしとしています。

使い心地は?

自画自賛で恐縮ですが閲覧しごこちは上々だと思っています。どのページに直リンクして飛んできても完全なメニューが表示されるようにしています。また、スクロールするとメニューが消えるので画面を有効に使えます。

メイン・メニューを頭にだけ付けたのでページ下部から他のページに移るときにスクロールして戻らなければなりません。そこで各ページに「ページトップに戻る」ボタンをCSSを使って配置しています。実はこれもSSIで読み込んでいます。ですからボタンデザインを変えたい場合もファイルを2,3いじるだけでサイト内の全ボタンを変えることが出来ます。当然、ボタンではなくメニューにすることも出来ます。

SSIを使う場合、各ページには定型のレイアウトやSSIのタグを配置しなければなりません。これは雛型を使ったり、既存のページをコピーするなどで解決します。

問題点

大問題が一つ有ります。HTMLファイルに共通メニューファイルへの仮想パスを直書きしたために、ホームページ・ビルダーからは管理できなくなりました。これはサイトのトップフォルダより上に仮想ルートがあるためで、ホームページ・ビルダーはこの手のリンクを触らずにそっとしておきます。その結果、共通メニューファイルを移動させることが困難になりました。また、ssiメニューへのリンクが切れるので、これを自動でFTPを使ってロードすることができません。

もちろん、これ自身は大問題ではありません。共通メニューファイルは一箇所にまとめたほうが便利ですし、動かす必要もありません。問題はiswebから引っ越す場合です。直書きした仮想パスは引越し先では使用できません。そのため、大量のHTMLファイルを手作業で修正するか、ツールを使って書きなおうすしかありません。

これは共通メニューを各ディレクトリに配布しておけば避けられた問題です。各ディレクトリへの更新したメニューの配布が面倒ですが、ちょっとしたバッチファイルを作ればすぐ済みます。FTPに関してもSSIだけは独立したFTPプログラムで一括転送すれば問題ありません。こうしておけば引越しは楽です。

SSIは必要ない?

引越しのときにわざわざツールを使うならば、初めからSSIフィルターでも作ったほうがいいのではないでしょうか。そうしてフィルターを掛けたHTMLファイルをアップロードするのです。利点は

などがあります。もちろん、大きなサイトになるとHTMLファイルと共通メニューファイルの依存関係を抽出して、必要なファイルだけアップロードするようにしたいところです。しかし小さなサイトで回線がADSLなら毎回全部送ってもたかが知れています。

今回iswebを選んだのは上記のような処理をするプログラムを作る余裕が無かったためですが、結論は笑い話になったようです。だれかこんなプログラム作ってみませんか?

結構受けると思うのですが。

結論はどうあれ、ssiの使い心地は気にいりましたのでしばらくここに腰を落ち着けようと思います。

ホームページビルダーによるSSI

読み返してみるとぐちゃぐちゃ書いている割に中身がありません。「で、お前はどうやっているんだ!」と怒られそうです。そこで、私が現在行っている作業方法を列挙してみます。

テンプレートを使う

ホームページビルダー(Ver6.5)にはテンプレートという便利な機能があります。これは統一的なデザインをページ間で維持したいときに使う機能で、要するにその名の通りページの雛型を登録する機能です。

これらの雛型に定型のレイアウトやSSIスクリプトをあらかじめ書き込んだものを登録しておけば、決まりきった作業の大半から開放されます。例えばこのページはISWEBが要求する広告インクルードSSI、横線、メインメニューインクルード用SSI、レイアウト用表組み、サブメニュー用SSI、ページトップ移動用SSIなどの定型情報をもっていますが、これらは雛型に書き込んであるために、新規ページを作ったときには既にそこにあります。

雛型は複数登録することができ、新しいページを作るときにそれらの雛型の一つを選ぶことができます。たとえばEZ-KIT LiteADSP-2191はサブメニューが異なります。そのため、別々の雛型から作り出しています。サブメニューを共有するページは、すべて同じ雛型から作ることができます。

もちろん、雛型を使わずに既存のファイルを改造して新しいファイルを作ってもいいでしょう。

メニューの維持

ホームページビルダーでSSIを使うときに、おそらくもっともきわどいことになるのがインクルードされるメニューです。その理由は次の通りです。

  1. メニューの中のリンクはトップディレクトリ相対になるため、リンク先ページとの間の一貫性をホームページビルダーが管理できなくなる。なぜなら、iswebのトップディレクトリは、レンタル領域のトップとはことなるから。
  2. SSIのインクルードはvirtual指定になるため、インクルード元とメニューの間の一貫性をホームページビルダーが管理できなくなる。
  3. 一貫性を管理できないと、相手を移動したときにリンク元の修正ができない。
  4. 一貫性を管理できないと、リンク先を更新したときにアップロード対象にならない。

3に関しては、対象ファイルを移動・改名したときにメニュー側を自動変更できないのが痛手です。また、メニューの移動はあきらめるしかありません(これはそれほど痛くない)。

4に関してはメニュー(.ssi)を変更したときに自動的にアップロード対象としてくれない点が痛手です。

そこで次のような対策を打ちました。

  1. メニューは.ssiと、それに対応する.htmファイルを作った。
  2. .ssiも、.htmもサイトの適当なファイルから一括リンクする。(現在はまずhtmlへリンクを張り、1のhtmlファイルから.ssiにリンクしています)

2の適当なファイルとは、これです。このページを作ったことで、メニューを持つ.ssiファイルを変更すると、ホームページビルダーが勝手にアップロード対象にしてくれます。また、.ssiに対応する.htmlを持っておくことで、リンク先ページが移動した場合、メニューの.html側をホームページビルダーが自動的に変更してくれます。したがって、変更後に.htmlからメニューだけ抜き出して.ssiにコピーすればきちんとサイトの更新をメニューに反映することができます。

.htmlから.ssiへの変更

.thml上に作ったメニューを.ssiにコピーした後、リンク先アドレスを変更する必要が有ります。これは、HTML表示状態で変更します。

例えば .htmlファイルでは

<A href="../misc/index.shtml">雑多なもの</A>

となっているリンクを

<A href="/misc/index.shtml">雑多なもの</A>

のように変更します。検索・置換メニューが便利ですが、手作業でやってもそれほど負担ではありません。

2191空挺団 | プログラム | EZ-KIT | こぼれ話 | アーキテクチャー | 命令 | レジスタ | DSP掲示板 | FAQ |