Mercurial > pub > Impl
view Lib/IMPL/Web/Handler/ViewSelector.pm @ 210:6adaeb86945d
added IMPL::Web::AutoLocator
author | sergey |
---|---|
date | Tue, 29 May 2012 20:07:22 +0400 |
parents | 3d433a977e3b |
children | d6e2ea24af08 |
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' }, 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 $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,$next); } 1; __END__ =pod =head1 NAME C<IMPL::Web::Handler::ViewSelector> - Выбор нужного представления на основе заголовка C<Accept> =head1 DESCRIPTION Использует заголовок запроса C<Accept> для выбора подходящего представления, если задано свойство C<types>, пытается в первую очередь по расширению определить, какое представление подходит. =head1 MEMBERS =head2 C<[get,set,list]views> Список представлений, которые могут быть возвращены. =head2 C<[get,set]types> Хеш с соотвествием между расширением и типом содержимого, для подсказки при выборе представления. =cut