- 名前 (NAME)
- 概要 (SYNOPSIS)
- 説明 (DESCRIPTION)
- ハンドラのチェーン化 (CHAINING HANDLERS)
- 警告 (CAVEATS)
- 行うこと (TO DO)
- 参考資料 (SEE ALSO)
- 作者 (AUTHOR)
- 著作権 (COPYRIGHT)
- 翻訳者
名前 (NAME)¶
Apache::SSI - Perl での Server Side Includes の実行
概要 (SYNOPSIS)¶
httpd.conf 内:
<Files *.phtml> # または何らか
SetHandler perl-script
PerlHandler Apache::SSI
</Files>
あなたは Apache::SSI サブクラスで独自拡張ができます。もしそうするなら PERL_METHOD_HANDLERS=1 とあわせて mod_perl をコンパイルしてください (そうすれば オブジェクト指向継承が利用可能です)。そしてモジュールをこのように作って下さい:
package MySSI;
use Apache::SSI ();
@ISA = qw(Apache::SSI);
#埋め込みシンタックス:
#<!--#something param=value -->
sub ssi_something {
my($self, $attr) = @_;
my $cmd = $attr->{param};
...
return $a_string;
}
そして httpd.conf 内は:
<Files *.phtml>
SetHandler perl-script
PerlHandler MySSI
</Files>
説明 (DESCRIPTION)¶
Apache::SSI は、HTML サーバ解析処理のための mod_include の機能を実行します。 これは Apache の mod_perl 下で動作します。
私の考えでは、このモジュールが有用であるかも知れない、主な理由が二つあります: 独自カスタム SSI 命令を実行するためのサブクラスが使えます。そして/または、 他の mod_perl ハンドラの出力を解析出来、また、SSI 出力を他のハンドラへ 送ることができます (その場合 Apache::Filter を利用して下さい)。
各 SSI 命令は Apache::SSI の、接頭辞 "ssi_" のメソッドによって処理されます。 例えば、<!--#printenv--> は ssi_printenv メソッドによって処理されます。 SSI タグ内の属性=値のペアは、解析され、ハッシュリファレンスで メソッドに渡されます。
'Echo' 命令は、ssi_echo メソッドによって処理され、その委任されたメソッドが、 接頭辞 "echo_" のメソッドを調べます。例えば、<!--#echo var=DOCUMENT_NAME--> は echo_DOCUMENT_NAME メソッドに処理されます。
Apache::SSI から継承し 'ssi_*' や 'echo_*' メソッドをオーバーライドするか、 新規のメソッドを書くことにより、挙動をカスタマイズできます。
SSI 命令 (SSI Directives)¶
このモジュールは mod_include と同じ命令をサポートします。少なくとも、 それが目標です。=) 以下に一覧されながら、文書化されていないメソッドについては、 http://www.apache.org/ で mod_include のオンラインドキュメントをご覧下さい。
config
echo
exec
fsize
flastmod
include
printenv
set
perl
Perl 関数を呼び出す方法は二つあり、そして引数を与える方法が二つあります。 関数は無名サブルーチンリファレンスによる指定、 あるいは他で定義済みの関数名での指定のどちらかでできます。
<!--#perl sub="sub { localtime() }"--> <!--#perl sub="time::now"-->
もし sub 引数が、正規表現 /^\s*sub[^\w:]/ にマッチすると、 サブルーチンリファレンスとみなされます。マッチしなければ、関数名とみなされます。 後者の場合で、関数名に "::" が含まれていない場合に、"main::" 文字列が 関数名の先頭に付加されます (これは関数が main パッケージか、あなたの指定する パッケージ内にあることを強制します)。これは、あなたのコードを main パッケージに置くための非常に悪い考えなので、私は気乗りせず この特徴を是認しているだけである事に注意してください。
大抵、無名サブルーチンを使うと、より遅くなります。なぜなら、それぞれは eval() されなければならず、キャッシュされないためです。 最善策をとるなら、親プロセス内に必要なコードをプリロードしておき、 そして関数名でそれを呼び出してください。
もし "&Package::SubPack::handler" のようなサブルーチンを呼び出す場合は "handler" の部分は省略可能で、このようにできます:
<!--#perl sub="Package::Subpack"-->
もしあなたが関数に引数のリストを与えたいなら、"arg" か "args" の どちらかのパラメータを使います:
<!--#perl sub="sub {$_[0] * 7}" arg=7--> <!--#perl sub=holy::matrimony arg=Hi arg=Lois--> <!--#perl sub=holy::matrimony args=Hi,Lois-->
"args" パラメータは簡単なカンマ分割をします。今のところ "args" パラメータを介した場合、引数内にカンマを埋め込む方法が存在しないことを 意味します。その場合は "arg" パラメータを使って下さい。
もしキーと値のペアを与えたくて、キーが 'sub', 'arg', 'args', または 'pass_request' (以下参照) でなければ、あなたのルーチンへはキーと値の 両者 が渡されます。これはあなたの関数へ、キーと値のペアになった ハッシュを渡させます:
<!--#perl sub=holy::matrimony groom=Hi bride=Lois--> これは &holy::matrimony('groom', 'Hi', 'bride', 'Lois'); を呼びます。
バージョン 1.95 の時点で、私達は現在の Apache リクエストオブジェクト ($r) を 第一引数として関数に渡します。これを抑制するには、'pass_request=no' という、 キーと値のペアを渡すか、あなたのサーバ設定ファイル内に 'PerlSetVar SSIPerlPass_Request no' を設定してください。
Perl SSI 呼び出しに関する詳細情報は
http://perl.apache.org/src/mod_perl.html
をご参照下さい。if
elif
else
endif
これらの四つの命令は
mod_include
と同じように使われます。一点の 重要な違い: ブール式は、Perl の eval() を使用して評価されます。これは、 等価比較で=
に代わり==
かeq
を使用する事、また、条件式に プリロードされた Perl サブルーチンを使用することが出来る事も意味します:<!--#if expr="&Movies::is_by_Coen_Brothers($MOVIE)"--> This movie is by the Coen Brothers. <!--#else--> This movie is not by the Coen Brothers. <!--#endif-->
もっとも、とても複雑な Perl の処理はできません。なぜならそれは手作業で (
mod_include
のように $var または ${var} 形式の) 変数を探し、 $object->method または $hash{'key'} のような表記には間違えさせられるからです。 Apache の変数に記入している間に、Perl 独自の表記を許可する方法について どんな提案でも歓迎します。
ハンドラのチェーン化 (CHAINING HANDLERS)¶
スタックされたハンドラのチェーン内にこのモジュールを存在させるため、 とても簡単な方法が二つあります。第一に Apache::Filter
を使い、そして あなたの httpd.conf はこのような感じでしょう:
PerlModule Apache::Filter
PerlModule Apache::SSI
PerlModule My::BeforeSSI
PerlModule My::AfterSSI
<Files ~ "\.ssi$">
SetHandler perl-script
PerlSetVar Filter On
PerlHandler My::BeforeSSI Apache::SSI My::AfterSSI
</Files>
"PerlSetVar Filter On"
ディレクティブは三つのスタックされたハンドラに それらをフィルタリングモードにすべきだと命じます。これは必須です。
第二に Apache::OutputChain
を使い、そしてあなたの httpd.conf は このような感じでしょう:
PerlModule Apache::OutputChain
PerlModule Apache::SSIChain
PerlModule My::BeforeSSI
PerlModule My::AfterSSI
<Files ~ "\.ssi$">
SetHandler perl-script
PerlHandler Apache::OutputChain My::AfterSSI Apache::SSIChain My::BeforeSSI
</Files>
このハンドラの順番は、二つの異なるメソッドで逆順にされる事に注意してください。 一つの理由は、私が書いた Apache::Filter
は、順番をより直感的にさせます。 もう一つの理由は、Apache::SSI
は、これ自体が Apache::Filter
を使う スタックハンドラで使われる事が出来る事です。それゆえに、Apache::OutputChain
と一緒に使われるには、Apache::SSIChain
にラップされている必要があります。
より明確な情報は Apache::OutputChain
と Apache::Filter
のドキュメントを ご覧下さい。そして、警告 (CAVEATS) の中の注記も見てください。
警告 (CAVEATS)¶
* Apache::Filter を介してハンドラをチェーン化した時に、もし <!--#include ...--> または <!--#exec cgi=...--> を使う場合、Apache::SSI はチェーン内の最後のフィルタ でなければなりません。これは Apache::SSI がファイルのインクルードのために、 $r->lookup_uri(...)->run を使い、これは Perl の STDOUT ではなく、 むしろ C の stdout へ出力を送るからです。従い Apache::Filter には 出力の捕捉やフィルタが出来ません。
もし Apache::SSI がチェーン内の最後のフィルタであるか、あなたが <!--#fsize-->, <!--#flastmod--> 等の簡単な SSI 命令を貼り付けるのなら問題ないでしょう。
* 現在の、<!--#echo var=whatever--> が変数を探す方法は、最初に $r->subprocess_env を試み、次に %ENV を試み、そして五つの追加環境変数は mod_include が提供します。この順序は正しいでしょうか?
行うこと (TO DO)¶
http://www.apache.org/docs/mod/mod_include.html を再訪し、私が出来ることが 他に何かないかを見ること。
ファイルをインクルードする時に十分に発達したサブリクエストを実行するか、 または、ただファイルを開いて出力するか、このどちらかを選択させる "PerlSetVar ASSI_Subrequests 0|1" オプションを持つことは素敵でしょう。
real.t テストのために Apache::test の使い方を知りたい。
参考資料 (SEE ALSO)¶
mod_include, mod_perl(3), Apache(3), HTML::Embperl(3), Apache::ePerl(3), Apache::OutputChain(3)
作者 (AUTHOR)¶
Ken Williams [email protected]
基本概念は Doug MacEachern [email protected] によるオリジナルバージョン。 実装は異なる。
著作権 (COPYRIGHT)¶
Copyright 1998 Swarthmore College. All rights reserved.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
翻訳者¶
谷口公一 <[email protected]>