簡易CGI Webフレームワーク
2007/02/05
友達に、ちょっとしたサイトを作る話を貰ったとき(仕事じゃなく)、perlでやることにしました。CGIとHTML::Templateは、使うけど黒魔術じゃないというframeworkはできないものかと思いながら、作ってみました。
結果頼まれたサイトはなかなか完成せず、なんちゃってframework作りに興味が向いている自分に気が付いてしまいました。そのときの、簡単な使い方と中枢部のソースです。名前はMizincoとしています。機能も少ないから身のたけに合った名前ではないでしょうかね。
- 簡単な使い方
- CGIファイル
#!c:/perl/bin/perl use strict; use warnings; use Mizinco; my $controller = new Mizinco(); $controller->proc(); exit; #===================================================================== # Action #===================================================================== package Action; use CGI::Carp qw(fatalsToBrowser); sub default { return {redirect_to => "hello"}; } sub hello { my ($q, $session, $infos) = @_; my $response_data = {message => "hello, dynamic world. <" . localtime . ">"}; return { forward_to => "hello.html", response_data => $response_data }; }
- テンプレートファイル
<html> <body> <h1>hello, world.</h1> <p><tmpl_var name='message' escape='html'></p> </body> </html>
- frameworkの中枢部のソース
package Mizinco; use 5.008002; use strict; use warnings; our $VERSION = '0.01'; use Carp; use CGI; use CGI::Session; use HTML::Template; use HTML::FillInForm; use Mizinco::Utils; sub new { my ($class, %args) = @_; my $q = new CGI or die "failed to create CGI instance: $! $@\n"; my $session = new CGI::Session("driver:File", $q, {Directory => './session'}) or die "failed to create CGI::Session instance: $! $@\n"; my $self = { query => $q, session => $session, args => \%args, entry_cgi => $q->url(-absolute, 1), app_name => Mizinco::Utils::get_app_name($q) }; return bless $self, $class; } sub proc { my $self = shift; my $q = $self->{query}; my $session = $self->{session}; #get command from PATH_INFO. my (undef, $command, @info) = split('/', $ENV{'PATH_INFO'}); $command ||= "default"; #default action name. #execute action. my $action_results = do { no strict "refs"; &{"Action::${command}"}($q, $session, \@info); }; #validate error. if ($action_results->{validate_errors}) { $action_results = Mizinco::Utils::restore_action_results($action_results, $q, $session) ; } #redirect, if you appointed it. and return. if ($action_results->{redirect_to}) { print $q->redirect("$self->{entry_cgi}/$action_results->{redirect_to}"); return; } #prepare view. my $template = new HTML::Template(filename => "html/" . $action_results->{forward_to}, associate => $q, die_on_bad_params => 0, loop_context_vars => 1) or die "failed to create HTML::Template instance: $! $@\n"; my $response_data = $action_results->{response_data}; map {$template->param($_ => $response_data->{$_});} (keys %$response_data); $session->param("_action_results", $action_results); print $session->header(-type => 'text/html', -charset => 'Windows-31J'); my $output_buf = $template->output; #replace mizinco tags. $output_buf =~ s/\<mizinco_action_url\>/$self->{entry_cgi}/ig; $output_buf =~ s/\<mizinco_app_url\>/$self->{app_name}/ig; #fill in form and output html document. print new HTML::FillInForm()->fill(scalarref => \$output_buf, fobject => $q); } sub DESTROY { my $self = shift; $self->{session}->save_param($self->{query}); } 1;
まぁ、これだけでは動かないんですが。(あと2,3ファイル必要)
いつの日か、まとめて出せる状態になればいいなとは思ってるけど。。。