Perl で、CGI::Application を使う

CGI::Application は HTML::Template を統合している。以下は HTML::Template のドキュメントで書かれている例が含まれている。

使用するモジュール


use CGI::Application;

# 要 HTML::Template
# IPC::SharedCache (こちらは任意)

まずは以下のようなディレクトリとファイル構成にする。


./cgi-bin/lib/App.pm
./cgi-bin/templates/test.templ
./cgi-bin/index.cgi

index.cgi の内容:
基本的に App クラスを new して app->run() としているだけである。
BEGIN ブロックのそれはライブラリへのパスを探している。

#!/usr/bin/perl -w use strict; my $LIB_DIR; BEGIN {
if ($0 =~ m!(.*[/¥¥])!) {
    $LIB_DIR = $1;
} else {
    $LIB_DIR = './';
}
unshift @INC, $LIB_DIR . 'lib';
} use App; my $app = App->new(); $app->run(); 1;

App.pm の内容。

  1. このモジュールでは、このモジュールから return で返した文字列が出力されるようになっている。よって例では、結果的に $template->output が返す文字列を App オブジェクトから返している。後は自動的に出力される。
  2. $self->mode_param('rm') とあるのはフォームやURL中のクエリ文字列で rm='次に実行すべきメソッド' を指定しろ、ということ。例えば <input type=hidden name=rm value=do_next> みたいな感じである。'rm' がキーワード、メソッド名が値となっている。
  3. $self->start_mode('start') は、見ての通り、このアプリケーションがスタートしたときに実行されるメソッドを指定する。
  4. teardown (=destory と同義) は終了時に呼ばれるメソッド。
  5. このモジュールは CGI、HTML::Template と統合されていて、HTTP ヘッダなども $self->header_props と、CGI と同じように呼び出せる。
  6. HTML::Template については、$self->load_tmpl で HTML::Template オブジェクト (実体はハッシュリファレンス) が取り出せるようになっている。このとき指定できるキャッシュパラメータで、cache、double_cache は Linux など OS の実行プラットフォームに IPC::SharedCache モジュールがインストールされてないと使えない。
#!/usr/bin/perl -w package App; use strict; use base 'CGI::Application'; sub setup {
my $self = shift;
$self->mode_param('rm');
$self->start_mode('start');
$self->run_modes(
        'start' => ¥&start,
        'end'   => ¥&end
    );
    $self->header_props(-type=>'text/html', -charset=>'utf-8');
} sub teardown {
my $self = shift;
# Post-response shutdown functions
# ここにはデータベースの切断を書くとよい。
} sub start {
my $self = shift;
my $template = $self->load_tmpl('test.tmpl',  die_on_bad_params => 0,
    path => ['......./cgi-bin/templates'],
# cache => 1, # double_cache => 1, # file_cache => 1, # file_cache_dir => '/tmp', # double_file_cache => 1
);
return &template($template);
} sub end { } sub template {
my $template = shift;

# the fruit data - the keys are the fruit names and the values are
# pairs of color and shape contained in anonymous arrays
my %fruit_data = (
                Apple  => ['Red, Green or Yellow', 'Round'      ],
                Orange => ['Orange'              , 'Round'      ],
                Pear   => ['Green or Red'        , 'Pear-Shaped'],
                Banana => ['Yellow'              , 'Curved'     ],
               );

my @loop;  # the loop data will be put in here

# fill in the loop, sorted by fruit name
foreach my $name (sort keys %fruit_data) {
    # get the color and shape from the data hash
    my ($color, $shape) = @{$fruit_data{$name}};

    # make a new row for this fruit - the keys are <TMPL_VAR> names
    # and the values are the values to fill in the template.
    my %row = ( 
           name  => $name,
           color => $color,
           shape => $shape
          );

    # put this row into the loop by reference             
    push(@loop, \%row);
}

# call param to fill in the loop with the loop data by reference.
$template->param(fruit_loop => \@loop);

# print the template
return $template->output;
} 1;

test.tmpl の内容:

<HEAD>
    <TITLE>Fruity Data</TITLE>
</HEAD>
<BODY>
    <H1>Fruity Data</H1>

    <TABLE BORDER=1>

        <TR>
            <TD><B>Fruit Name</B></TD>
            <TD><B>Color</B></TD>
            <TD><B>Shape</B></TD>
        </TR>

    <TMPL_LOOP NAME="fruit_loop">
        <TR>
            <TD><TMPL_VAR NAME="name"></TD>
            <TD><TMPL_VAR NAME="color"></TD>
            <TD><TMPL_VAR NAME="shape"></TD>
        </TR>
    </TMPL_LOOP>

    </TABLE>

</BODY>