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; ... });
をうまく使えば簡単にできる気がした。