Mercurial > pub > Impl
diff Lib/IMPL/Web/View/TTContext.pm @ 359:833e663796c4
TTView: added view variable to pass rendering context between controls
TTView: display function renamed to display_for
WebResource: resources now marked with roles for searching a desired resource by a role in the resource chain
author | sergey |
---|---|
date | Mon, 25 Nov 2013 02:19:31 +0400 |
parents | 97131d500f16 |
children | cbf4febf0930 |
line wrap: on
line diff
--- a/Lib/IMPL/Web/View/TTContext.pm Mon Nov 18 01:25:35 2013 +0400 +++ b/Lib/IMPL/Web/View/TTContext.pm Mon Nov 25 02:19:31 2013 +0400 @@ -23,6 +23,9 @@ BEGIN { no strict 'refs'; + # modules is a global (for the whole document) templates cache + # tt_cache is a local (for the current context only) templtes cache + # view is a special variable, which will be cloned and passed to the nested context foreach my $prop (qw( root base @@ -35,6 +38,7 @@ modules aliases id + view )) { my $t = $prop; @@ -75,7 +79,7 @@ } sub find_template { - my ($this,$name) = @_; + my ($this,$name, $nothrow) = @_; my $cache = $this->tt_cache; @@ -129,10 +133,12 @@ } } - $this->throw(Template::Constants::ERROR_FILE, "$name: not found"); + $this->throw(Template::Constants::ERROR_FILE, "$name: not found") + unless $nothrow; + return; } -sub display { +sub display_for { my $this = shift; my $model = shift; my ($template, $args); @@ -203,23 +209,41 @@ ); } +# обеспечивает необходимый уровень изоляции между контекстами +# $code - код, который нужно выполнить в новом контексте +# $env - хеш с переменными, которые будут переданы в новый контекст +# в процессе будет создан клон корневого контекста, со всеми его свойствами +# затем новый контекст будет локализован и в него будут добавлены новые переменные из $env +# созданный контекст будет передан параметром в $code sub invoke_environment { my ($this,$code,$env) = @_; $env ||= {}; my $ctx = ($this->root || $this)->clone(); - + + my @includes = @{$this->includes || []}; + + if ($this->base) { + unshift @includes, $this->base; + } + + my $view = $this->view; + $view = ref $view eq 'HASH' ? { %{$view} } : {}; + + hashApply($view, delete $env->{view}); + my $out = eval { $ctx->localise( hashApply( { + includes => \@includes, aliases => $this->aliases || {}, root => $this->root || $ctx, modules => $this->modules || {}, cache => TypeKeyedCollection->new(), - display => sub { - $ctx->display(@_); + display_for => sub { + $ctx->display_for(@_); }, render => sub { $ctx->render(@_); @@ -227,7 +251,8 @@ display_model => sub { $ctx->display_model(@_); }, - tt_cache => {} + tt_cache => {}, + view => $view }, $env ) @@ -244,6 +269,16 @@ return $out; } +# использует указанный шаблон для создания фрагмента документа +# шаблон может быть как именем, так и хешем, содержащим информацию +# о шаблоне. +# отдельно следует отметить, что данный метод создает новый контекст +# для выполнения шаблона в котором задает переменные base, parent, id +# а также создает переменные для строковых констант из labels +# хеш с переменными $args будет передан самому шаблону в момент выполнения +# если у шаблона указан класс элемента управления, то при выполнении шаблона +# будет создан экземпляр этого класса и процесс выполнения шаблона будет +# делегирован методу Render этого экземпляра. sub render { my ($this,$template,$args) = @_; @@ -276,7 +311,7 @@ } if (my $class = $info->{class}) { - $class->new($ctx,$info->{template},$args)->Render($args); + $class->new($ctx,$info->{template},$args)->Render({}); } else { return $ctx->include($info->{template},$args); } @@ -313,7 +348,7 @@ } sub find_template_for { - my ($this,$model) = @_; + my ($this,$model, $nothrow) = @_; my $type = typeof($model); @@ -331,8 +366,9 @@ my $sclass = shift @isa; (my $name = $sclass) =~ s/:+/_/g; + my ($shortName) = ($sclass =~ m/(\w+)$/); - $template = $this->find_template("templates/$name"); + $template = $this->find_template("templates/$name",1) || $this->find_template("templates/$shortName",1); if ($template) { $this->cache->Set($sclass,$template); @@ -343,7 +379,9 @@ } } - + $this->throw(Template::Constants::ERROR_FILE, "can't find a template for the model " . typeof($model)) + unless $nothrow; + return; }