1 package MojoX
::Dispatcher
::FilterChain
;
8 use MojoX
::FilterChain
::Constants
;
10 our $VERSION = '0.03';
12 use constant DEBUG
=> $ENV{MOJOX_DISPATCHER_FILTERCHAIN_DEBUG
} || 0;
14 __PACKAGE__
->attr('filters', default => sub { [] });
20 my $name = ref $filter;
21 warn "Adding filter '$name'" if DEBUG
;
23 push @
{$self->filters}, $filter;
29 foreach my $filter (@
{$self->filters}) {
30 my $name = ref $filter;
32 warn "Running '$name' filter" if DEBUG
;
34 my $proceed = $filter->run(@_);
36 warn "Stop filter chain after '$name' filter"
37 if DEBUG
and $proceed == LAST
;
39 last if $proceed == LAST
;
48 MojoX::Dispatcher::FilterChain - Intercepting filter manager
52 use MojoX::Dispatcher::FilterChain;
54 my $chain = MojoX::Dispatcher::FilterChain->new();
55 $chain->add(LanguageDetect->new);
56 $chain->add(Authorization->new);
57 $chain->add(RenderView->new);
65 L<MojoX::Dispatcher::FilterChain> is a intercepting filter manager pattern
68 Standart dispatch process can look like this:
73 # Try to find a static file
74 $self->static->dispatch($c);
76 # Use routes if we don't have a response code yet
77 $self->routes->dispatch($c) unless $c->res->code;
79 # Nothing found, serve static file "public/404.html"
80 unless ($c->res->code) {
81 #$self->static->serve($c, '/404.html');
86 Problem is that we have repetitive code that is checking whether to go to the
87 next dispatcher or stop.
89 What we want to have is a list of independent filters that are called in
90 specific order and one of them can intercept the chain.
92 Now we can rewrite our dispatch example.
94 __PACKAGE__->attr('chain',
95 default => sub { MojoX::Dispatcher::FilterChain->new } );
101 $self->chain->process($c);
107 my $chain = $self->chain;
109 $chain->add(MyApp::FilterChain::StaticDispatch->new($c));
110 $chain->add(MyApp::FilterChain::RoutesDispatch->new($c));
111 $chain->add(MyApp::FilterChain::RenderView->new($c));
114 Filter itself inherits L<MojoX::FilterChain::Base> and has method B<run> that
115 is called when chain is processed. L<MojoX::FilterChain::Constants>
116 module exports two self explaining constants B<NEXT> and B<LAST>. Depending on
117 which value is returned after running current filter, chain proceeds or stops.
119 Regular filter can look like this:
121 package MyApp::FilterChain::Routes;
126 use base 'MojoX::FilterChain::Base';
128 # export LAST and NEXT constants
129 use MojoX::FilterChain::Constants;
132 my ( $self, $c ) = @_;
134 $c->app->routes->dispatch($c);
136 return $c->res->code ? LAST : NEXT;
143 L<MojoX::Dispatcher::FilterChain> inherits all methods from L<Mojo::Base> and
144 implements the following the ones.
148 my $chain = MojoX::Dispatcher::FilterChain->new;
152 Add filter instance to filter chain.
154 my $chain->add(Filter->new);
158 Run filter chain. Parameters provided will be passed on to every filter.
163 =head1 COPYRIGHT & LICENSE
165 Copyright 2008 Viacheslav Tikhanovskii, all rights reserved.
167 This program is free software; you can redistribute it and/or modify it
168 under the same terms as Perl itself.