Mercurial > pub > Impl
view Lib/IMPL/Web/Handler/ViewSelector.pm @ 263:0f59b2de72af
*fixed IMPL::DOM::Schema circular module references
*modified IMPL::Object::Singleton, added auto-activation
*code cleanups, docs
author | sergey |
---|---|
date | Wed, 09 Jan 2013 05:17:44 +0400 |
parents | 3cebcf6fdb9b |
children |
line wrap: on
line source
package IMPL::Web::Handler::ViewSelector; use strict; use IMPL::Const qw(:prop); use IMPL::declare { require => { NotAcceptable => 'IMPL::Web::NotAcceptableException', HttpResponse => 'IMPL::Web::HttpResponse' }, base => [ 'IMPL::Object' => undef, 'IMPL::Object::Autofill' => '@_', 'IMPL::Object::Serializable' => undef ], props => [ views => PROP_RW | PROP_LIST, fallback => PROP_RW, types => PROP_RW ] }; sub Invoke { my ( $this, $action, $next ) = @_; my $result = $next ? $next->($action) : undef; my $model; return $result if eval { $result->isa(HttpResponse) }; my $handler; my $path = $action->pathInfo; if ( $this->types and $path =~ m/\.(\w+)$/ ) { my $forced; if ( $forced = $this->types->{$1} and $action->query->Accept($forced) ) { ($handler) = grep eval { $_->can('contentType') } && $_->contentType eq $forced, $this->views; } } if ( not $handler ) { my @handlers = sort { $b->{preference} <=> $a->{preference} } map { { handler => $_, preference => eval { $_->can('contentType') } ? $action->query->Accept( $_->contentType ) : 0 } } $this->views; my $info = shift @handlers; $handler = $info ? $info->{handler} : undef; } die NotAcceptable->new( map { eval { $_->can('contentType') } ? $_->contentType : () } $this->views ) unless $handler; return $handler->Invoke( $action, sub { $result } ); } 1; __END__ =pod =head1 NAME C<IMPL::Web::Handler::ViewSelector> - Выбор нужного представления на основе заголовка C<Accept> =head1 DESCRIPTION Использует заголовок запроса C<Accept> для выбора подходящего представления, если задано свойство C<types>, пытается в первую очередь по расширению определить, какое представление подходит. В случаях, когда не требуется строить представление для данных (например, при перенаправлении к другому ресурсу или если нет данных), нужно, чтобы данному обработчику был возвращен L<IMPL::Web::Application::ActionResult>, который будет просто передан далее. =head1 MEMBERS =head2 C<[get,set,list]views> Список представлений, которые могут быть возвращены. =head2 C<[get,set]types> Хеш с соотвествием между расширением и типом содержимого, для подсказки при выборе представления. =cut