Mercurial > pub > Impl
diff 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 diff
--- a/Lib/IMPL/Web/View/TTLoader.pm Mon Sep 23 00:09:26 2013 +0400 +++ b/Lib/IMPL/Web/View/TTLoader.pm Fri Sep 27 16:28:27 2013 +0400 @@ -5,6 +5,8 @@ use File::Spec(); use IMPL::Const qw(:prop); +use Scalar::Util qw(weaken); + use IMPL::declare { require => { Provider => 'Template::Provider', @@ -21,13 +23,9 @@ 'IMPL::Object::Serializable' => undef ], props => [ - options => PROP_RO, provider => PROP_RO, context => PROP_RO, - ext => PROP_RO, - layoutBase => PROP_RO, - isInitialized => PROP_RO, - initializer => PROP_RO, + registry => PROP_RO, _globals => PROP_RW ] }; @@ -58,17 +56,44 @@ $refOpts ||= {}; - $this->ext($args{ext}) if $args{ext}; - $this->initializer($args{initializer}) if $args{initializer}; + # 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} : {}); - $this->options($refOpts); - $this->layoutBase($args{layoutBase}) if $args{layoutBase}; + $ctx->tt_ext($args{ext} || '.tt'); + + $this->registry(TTRegitry->new($ctx)); - # to aviod cyclic references we need to do a copy of $refOpts - $refOpts->{LOAD_TEMPLATES} = $this->provider(Provider->new( { %$refOpts } )); + 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}} ); + } + }); - $this->context(Context->new($refOpts)); + } sub document { @@ -76,83 +101,9 @@ $vars ||= {}; - my $tt = $this->template($name); - - $this->_init(); - - my $opts = { %{ $this->options } }; - - my $ctx = $this->context->clone(); - - $ctx->stash->update($vars); - - my $registry = TTRegistry->new($this, $ctx); - - my $factory = TTFactory->new($tt->class || TTDocument, $tt, $ctx, $name, $registry); - - $vars->{registry} = $registry; - $vars->{layoutBase} = $this->layoutBase; - - return $factory->new( $vars ); -} - - -sub template { - my ($this,$name) = @_; - - $name =~ s/^\s+|\s+$//g; - - die ArgumentException->new("A valid template name is required") unless length $name; - - $name = $this->_appendExt($name); - - my ($tt,$error) = $this->provider->fetch($name); - - if (defined $error and $error == STATUS_DECLINED) { - die KeyNotFoundException->new($name); - } elsif (defined $error and $error == STATUS_ERROR) { - die Exception->new("Failed to load a template", $name, $tt); - } + my $factory = $this->registry->Require($name); - return $tt; -} - -sub ResolveFileName { - my ($this,$fname) = @_; - - $fname = $this->_appendExt($fname); - - my @files = grep -f , map File::Spec->catfile($_,$fname), @{$this->provider->paths()}; - return shift @files; -} - -sub _appendExt { - my ($this,$name) = @_; - - return $name unless $this->ext; - - if (length $this->ext and substr( $name, -length($this->ext) ) eq $this->ext) { - return $name; - } else { - return $name . $this->ext; - } -} - -sub _init { - my ($this) = @_; - - if (!$this->isInitialized) { - my $initializer = $this->initializer || sub {}; - - eval { - $this->context->process($initializer,$this->_globals); - }; - if (my $e = $@) { - die Exception->new("Failed to process an initializer", $this->initializer, $e); - } - - $this->isInitialized(1); - } + return $factory->new(hashMerge($vars, $this->_globals)); } 1; @@ -179,7 +130,9 @@ ] }, ext => '.tt', - initializer => 'shared/global' + globals => { + images => '//cdn.mysite.net/static/images' + } );