postmail.cgi を使ったメールフォームの入力・確認・完了・エラーページで、共通のHTML部品(ヘッダー・フッター等)を差し込み置換できるように改造する。SSIやPHPのinclude的な機能。
SSI include:
<!-- #include "xxxxx" -->
PHP include:
<?php include "xxxxx" ?>
書式を決める
SSI/PHPと似てるけど違う(SSI/PHPコードではない)ものにしておく。
独自実装するオリジナル書式:
<!-- &include "xxxxx" -->
とりあえずローカルファイルのみ、パスはドキュメントルート以降の絶対パスのみ対応する。例:
<!-- &include "/include/header.html" -->
<!-- &include "/include/footer.html" -->
入力・確認・完了・エラーページのテンプレートファイルで、この書式を使えるようにする。
差し込み置換処理ライブラリ新規作成
- ファイル
- lib/CGI/Include.pm
#
# 独自インクルード対応
#
# 書式:<!-- &include "xxxxx" -->
#
# ローカルファイルのみ、パスはドキュメントルート以降の絶対パスのみ対応
#
package CGI::Include;
use strict;
sub get_contents {
my ($target) = @_;
open(IN, "$ENV{DOCUMENT_ROOT}$target") or return '';
my $data = join('', <IN>);
close(IN);
return $data;
}
sub data {
my ($data) = @_;
$data =~ s/<!--\s*&include\s+"([^"]+)"\s*-->/&get_contents($1)/eg;
return $data;
}
1;
入力ページ用CGIファイル新規作成
- ファイル
- index.cgi
#!/usr/bin/perl -w
use strict;
use lib './lib';
use CGI::Include;
open(IN, "./index.html") or return;
my $data = CGI::Include::data(join('', <IN>));
close(IN);
print "Content-type: text/html; charset=utf-8\n\n";
print $data;
※1行目は環境にあわせて書き換える
Webサーバー設定
入力ページがCGI経由で表示されるよう、Webサーバー側で設定。
Apache なら .htaccess や httpd.conf で mod_rewrite を利用。
例えばフォームURLが /xxxxx/ で、ドキュメントルート直下 .htaccess に書く場合の例:
RewriteEngine on
RewriteRule ^/?xxxxx/?$ /xxxxx/index.cgi [L]
RewriteRule ^/?xxxxx/index\.html /xxxxx/index.cgi [L]
入力ページ以外も対応
postmail.cgi 本体を改造して、確認・完了・エラーページにも対応。
- ファイル
- postmail.cgi
13: use CGI::Minimal;
14: use CGI::Include;
15: use Jcode;
125: open(IN,"$cf{tmpldir}/conf.html") or error("open err: conf.html");
126: my $tmpl = CGI::Include::data(join('', <IN>));
127: close(IN);
391: open(IN,"$cf{tmpldir}/thanks.html") or error("open err: thanks.html");
392: my $tmpl = CGI::Include::data(join('', <IN>));
393: close(IN);
422: open(IN,"$cf{tmpldir}/error.html") or die;
423: my $tmpl = CGI::Include::data(join('', <IN>));
424: close(IN);
558: open(IN,"$cf{tmpldir}/error.html") or die;
559: my $tmpl = CGI::Include::data(join('', <IN>));
560: close(IN);