Amon2でコントローラー(Dispatcher)が動く前に処理を入れたい。
2014年11月27日
元となるソース(というか、修正するファイル)は、以前作成した(Amon2で$c->render()を自動で呼ぶようにしてみた。)のMyApp::Web
気分的には、Catalystのautoに近い挙動を目指す。
package MyApp::Web;
# dispatcher
use MyApp::Web::Dispatcher;
sub dispatch {
my $c = shift;
my $res = undef;
my $env = $c->request->env;
my ($method) = MyApp::Web::Dispatcher->router->match( $env->{REQUEST_METHOD}, $env->{PATH_INFO} );
eval {
# autoを呼ぶ
$res = $method->{'class'}->auto($c);
};
# レスポンスを持っている(autoでリダイレクトとか)
return $res if ( ref $res eq 'Amon2::Web::Response');
# コントローラーを呼ぶ
$res = MyApp::Web::Dispatcher->dispatch($c);
# レスポンスを持っている
return $res if ( ref $res eq 'Amon2::Web::Response');
# jsonを返す場合(Amon2::Plugin::Web::JSON)
if ( exists $c->stash->{'json'} ) {
return $c->render_json( $c->stash->{'json'} );
}
# htmlを返す場合
my $template = '';
if ( $c->stash->{'template'} ) {
# templateを手動で指定
$template = $c->stash->{'template'};
}
else {
# templateを自動セット
my $path = $method->{class} .'/' . $method->{method};
$path =~ s/MyApp::Web::C:://;
$path =~ s/\:\:/\//g;
$path = lc $path;
$template = $path . '.tt';
}
return ( $c->render($template, $c->stash ) or die "response is not generated" );
}
1;
“Class”->auto($c);を追加
これで、コントローラーを呼ぶ前に同名のClassに書いたautoメソッドが呼ばれる。
コントローラーのサンプル
package MyApp::Web::C::User;
sub auto {
my ( $class, $c ) = @_;
# 事前処理(Authチェックとか)
}
sub index { }
sub edit { }
1;
追記
もしかして
__PACKAGE__->add_trigger(BEFORE_DISPATCH => sub { my $c = shift; ... });
をうまく使えば簡単にできる気がした。