Mercurial > pub > Impl
view Lib/IMPL/Web/Handler/ViewSelector.pm @ 222:84a6382b49c8
resources schema in progress
author | sergey |
---|---|
date | Mon, 27 Aug 2012 17:28:32 +0400 |
parents | d6e2ea24af08 |
children | 47f77e6409f7 |
line wrap: on
line source
package IMPL::Web::Handler::ViewSelector; use strict; use IMPL::lang qw(:declare :constants); use IMPL::declare { require => { NotAcceptable => 'IMPL::Web::NotAcceptableException', ViewResult => 'IMPL::Web::Application::ViewResult' }, base => { 'IMPL::Object' => undef, 'IMPL::Object::Autofill' => '@_', 'IMPL::Object::Serializable' => undef } }; BEGIN { public property views => PROP_ALL | PROP_LIST; public property fallback => PROP_ALL; public property types => PROP_ALL; } sub Invoke { my ($this,$action,$next) = @_; my $result = $next ? $next->($action) : undef; my $model; if( eval { $result->isa(ViewResult) } ) { my $handler; my $path = $action->query->path_info; 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 }); } else { return $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