Mercurial > pub > Impl
view Lib/IMPL/Web/View/TTLoader.pm @ 345:72799d1211c5
sync
author | cin |
---|---|
date | Fri, 27 Sep 2013 16:28:27 +0400 |
parents | 9bdccdf1f50b |
children |
line wrap: on
line source
package IMPL::Web::View::TTLoader; use strict; use Template::Constants qw(:status); use File::Spec(); use IMPL::Const qw(:prop); use Scalar::Util qw(weaken); use IMPL::declare { require => { Provider => 'Template::Provider', Context => 'IMPL::Web::View::TTContext', TTRegistry => 'IMPL::Web::View::TTRegistry', TTFactory => 'IMPL::Web::View::TTFactory', TTDocument => '-IMPL::Web::View::TTDocument', Exception => 'IMPL::Exception', ArgumentException => '-IMPL::InvalidArgumentException', KeyNotFoundException => '-IMPL::KeyNotFoundException' }, base => [ 'IMPL::Object' => undef, 'IMPL::Object::Serializable' => undef ], props => [ provider => PROP_RO, context => PROP_RO, registry => PROP_RO, _globals => PROP_RW ] }; sub save { my ($this,$context) = @_; $context->AddVar($_, $this->$_()) for qw(options provider context ext layoutBase); } sub restore { my ($class,$data,$surrogate) = @_; my %params = @$data; my $refOpts = delete $params{options}; if ($surrogate){ $surrogate->callCTOR($refOpts,%params); } else { $surrogate = $class->new($refOpts,%params); } return $surrogate; } sub CTOR { my ($this,$refOpts,%args) = @_; $refOpts ||= {}; # to aviod cyclic references we need to do a copy of $refOpts $refOpts->{LOAD_TEMPLATES} = Provider->new( { %$refOpts } ); my $ctx = Context->new( { %$refOpts } ); $this->context($ctx); $this->_globals(ref $args{globals} eq 'HASH' ? $args{globals} : {}); $ctx->tt_ext($args{ext} || '.tt'); $this->registry(TTRegitry->new($ctx)); weaken($ctx); weaken($this); $ctx->stash->update({ require => sub { my ($modname) = @_; my @inc; push @inc, $ctx->base if $ctx->base; my $ti = $ctx->find_template($name,@inc); require $this->registry->Require($ti); }, inclue => sub { my ($name) = @_; my @inc; push @inc, $ctx->base if $ctx->base; my $ti = $ctx->find_template($name,@inc); return $ctx->include($ti->{template}, {base => $ti->{base}} ); } }); } sub document { my ($this,$name,$vars) = @_; $vars ||= {}; my $factory = $this->registry->Require($name); return $factory->new(hashMerge($vars, $this->_globals)); } 1; __END__ =pod =head1 NAME C<IMPL::Web::View::TTLoader> - предоставляет глобальный контекст для загрузки шаблонов =head1 SYNOPSIS =begin code use IMPL::Web::View::TTLoader(); my $loader = new IMPL::Web::View::TTLoader( { INCLUDE_PATH => [ '/my/app/tt', '/my/app/tt/lib' ] }, ext => '.tt', globals => { images => '//cdn.mysite.net/static/images' } ); my $doc = $loader->document('index'); my $html = $doc->Render(); =end code =head1 DESCRIPTION Провайдер для загрузки шаблонов и документов. Имеет собственное пространство имен, контекст выполнения шаблонов. Контект загрузчика инициализируется шаблоном, в котором определяются глобальные переменные, которые будут доступны в документах, однако их изменения будут локализованы. Инициализация контекста провайдера происходит при первой загрузке любого документа. =head1 MEMBERS =head2 C<CTOR($options,%args)> =over =item * C<$options> Параметры контекста загрузчика, контексты документов и элементов управления также унаследуют эти свойства. Напрямую передаются в конструктор C<Template::Context>. =item * C<%args> Именованные параметы загрузчика. =over =item * C<ext> Расширение, которое будет добавляться к именам шаблонов и документов (если оно не будет указано явно). =item * C<initializer> Имя шаблона, который будет использован для инициализации контекста. =item * C<globals> Глобальные переменнын, которые будут переданы в контекст. =item * C<layoutBase> Путь к шаблонам для оформления документов. Каждый документ может задавать свой C<layout> указанный в его C<META> блоке или конструкторе. См. C<IMPL::View::TTDocument>. =back =back =head2 C<document($docName)> Загружает документ с именем C<$docName>. При необходимости к нему будет добавлено расширение, указанное в свойстве C<ext>. Это единственно полезный метод провайдера. =cut