# HG changeset patch # User cin # Date 1333633911 -14400 # Node ID 78a18a2b62668a2d7de83db833b35c4faedb004e # Parent cd1ff7029a638d2385e67ea38d1dfed0f9031429 IMPL::Web::View improvements (unstable) diff -r cd1ff7029a63 -r 78a18a2b6266 Lib/IMPL/Web/View/TTControl.pm --- a/Lib/IMPL/Web/View/TTControl.pm Wed Apr 04 17:51:27 2012 +0400 +++ b/Lib/IMPL/Web/View/TTControl.pm Thu Apr 05 17:51:51 2012 +0400 @@ -5,6 +5,7 @@ use IMPL::lang qw(:declare :constants); use Template::Context(); +use Scalar::Util qw(weaken); use parent qw( IMPL::DOM::Node @@ -34,12 +35,12 @@ $this->template( $template ) or die new IMPL::ArgumentException("A template is required"); $this->context( $context ) or die new IMPL::ArgumentException("A context is required"); - if ( my $ctor = $template->blocks->{CTOR} ) { - $context->process($ctor, { this => $this } ); - $context->stash->set('this',undef); - } + $this->id($name . "-" . _GetNextId()) unless $this->id; - $this->id($name . "-" . _GetNextId()) unless $this->id; + weaken($this); # prevent cyclic references produces by the code below + + $context->stash->set('append', sub { $this->appendChild(@_); undef; } ); + $context->stash->set('select', sub { $this->selectNodes(@_) } ); } @@ -50,8 +51,19 @@ } ); +sub InitInstance { + my ($this,$args) = @_; + + $args ||= {}; + + if ( my $ctor = $this->template->blocks->{CTOR} ) { + $this->context->process($ctor, { %$args, this => $this } ); + $this->context->stash->set('this',undef); + } +} + sub renderBlock { - $_[0]->template->blocks->{RENDER}; + $_[0]->template->blocks->{RENDER} || $_[0]->template; } sub Render { diff -r cd1ff7029a63 -r 78a18a2b6266 Lib/IMPL/Web/View/TTDocument.pm --- a/Lib/IMPL/Web/View/TTDocument.pm Wed Apr 04 17:51:27 2012 +0400 +++ b/Lib/IMPL/Web/View/TTDocument.pm Thu Apr 05 17:51:51 2012 +0400 @@ -46,6 +46,7 @@ }); $this->templateVars('document', sub { $self } ); + $this->InitInstance(); } our %CTOR = ( @@ -80,8 +81,8 @@ my $path = $control; if ( my $template = $this->loader->template($path) ) { - my $opts = { %{$this->opts} }; - $opts->{STASH} = $this->stash->clone(); + my $opts = { %{$this->loader->options} }; + $opts->{STASH} = $this->loader->context->stash->clone(); my $ctx = new Template::Context($opts); @@ -115,7 +116,7 @@ if ($this->layout) { $output = $this->context->include( - $this->layout, + $this->loader->template($this->layout), { content => sub { $output ||= $this->RenderContent($args); } } diff -r cd1ff7029a63 -r 78a18a2b6266 Lib/IMPL/Web/View/TTFactory.pm --- a/Lib/IMPL/Web/View/TTFactory.pm Wed Apr 04 17:51:27 2012 +0400 +++ b/Lib/IMPL/Web/View/TTFactory.pm Thu Apr 05 17:51:51 2012 +0400 @@ -31,9 +31,6 @@ $this->opts($options || {}); $this->nodeProperties($nodeProps || {}); $this->instances(0); - - # init factory context - $this->context->process($this->template); } our %CTOR = ( @@ -65,10 +62,14 @@ } } + my $instance = $this->SUPER::CreateObject(@_); + + $instance->InitInstance(); + $count++; $this->instances($count); - return $this->SUPER::CreateObject(@_); + return $instance; } sub save { @@ -172,7 +173,7 @@ Создает экземпляр элемента управления стандартным образом. Учитывает количество экземпляров и если это первый, то производит дополнительную инициализацию контекста выполнив блок шаблона C. -=item C +=item C<[inherited]new($name,$nodeProps)> Создает элемент управления с указанным именем и набором свойств. diff -r cd1ff7029a63 -r 78a18a2b6266 _test/Resources/TTView.Output/Panel.txt --- a/_test/Resources/TTView.Output/Panel.txt Wed Apr 04 17:51:27 2012 +0400 +++ b/_test/Resources/TTView.Output/Panel.txt Thu Apr 05 17:51:51 2012 +0400 @@ -5,4 +5,4 @@
hello world

- + \ No newline at end of file diff -r cd1ff7029a63 -r 78a18a2b6266 _test/Resources/TTView.Output/complex.default.txt diff -r cd1ff7029a63 -r 78a18a2b6266 _test/Resources/TTView/Layout/default.tt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/_test/Resources/TTView/Layout/default.tt Thu Apr 05 17:51:51 2012 +0400 @@ -0,0 +1,16 @@ + + + $site.name - $title + [% IF dojo.require.size; + modules = []; + modules.push('"' _ item _ '"') FOREACH item IN dojo.require.unique(); + %] + + [% END %] + + + [% content %] + + \ No newline at end of file diff -r cd1ff7029a63 -r 78a18a2b6266 _test/Resources/TTView/Layout/print.tt diff -r cd1ff7029a63 -r 78a18a2b6266 _test/Resources/TTView/My/Org/Panel.tt --- a/_test/Resources/TTView/My/Org/Panel.tt Wed Apr 04 17:51:27 2012 +0400 +++ b/_test/Resources/TTView/My/Org/Panel.tt Thu Apr 05 17:51:51 2012 +0400 @@ -8,16 +8,14 @@ BLOCK CTOR; dojoClass = dojoDefaultClass; visualClass = this.visualClass || 'classic'; - FOREACH text IN data; - CALL this.appendChild(TPreview.new('preview', nodeValue = text )); + FOREACH text IN this.data; + append(TPreview.new('preview', nodeValue = text )); END; END; %] -[% BLOCK RENDER %]
- [% FOREACH node IN this.selectNodes('preview') %] + [% FOREACH node IN select('preview') %] [% node.Render() %]
[% END %] -
-[% END %] \ No newline at end of file + \ No newline at end of file diff -r cd1ff7029a63 -r 78a18a2b6266 _test/Resources/TTView/complex.tt --- a/_test/Resources/TTView/complex.tt Wed Apr 04 17:51:27 2012 +0400 +++ b/_test/Resources/TTView/complex.tt Thu Apr 05 17:51:51 2012 +0400 @@ -1,9 +1,12 @@ [% - META version = 1, title = "my document 2"; + META version = 1, title = "my document 2", layout= "Layout/default"; - TPanel = document.require('My/Org/Panel'); - - this.appendChild(TPanel.new('information')); - - this.selectSingleNode('information').Render(); -%] \ No newline at end of file + BLOCK CTOR; + TPanel = require('My/Org/Panel'); + append( TPanel.new('information', data = this.data ) ); + END; + +%] +[% FOREACH node IN this.childNodes() %] +
[% node.Render() %]
+[% END %] \ No newline at end of file diff -r cd1ff7029a63 -r 78a18a2b6266 _test/Test/Web/View.pm --- a/_test/Test/Web/View.pm Wed Apr 04 17:51:27 2012 +0400 +++ b/_test/Test/Web/View.pm Thu Apr 05 17:51:51 2012 +0400 @@ -108,7 +108,6 @@ my $loader = $this->CreateLoader(); my $doc = $loader->document('simple'); - $doc->templateVars(data => ['one','two','hello world']); assert(defined $doc); @@ -121,7 +120,7 @@ assert($factory == $doc->require('My/Org/Panel'), "Control should be loaded only once"); - my $ctl = $factory->new('information', { visualClass => 'simple' } ); + my $ctl = $factory->new('information', { visualClass => 'simple', data => ['one','two','hello world'] } ); assert(defined $ctl); @@ -133,13 +132,34 @@ $doc->appendChild($ctl); - + assert($doc->templateVars('dojo.require')); + assert(ref $doc->templateVars('dojo.require') eq 'ARRAY'); + assert($doc->templateVars('dojo.require')->[0] eq 'dijit.form.Input' ); my $text = $ctl->Render(); - my $expected = read_file($this->GetResourceFile('Resources', 'TTView.Output', 'Panel.txt'), binmode => ':utf8'); + my $expected = read_file($this->GetResourceFile('Resources', 'TTView.Output', 'Panel.txt'), binmode => ':utf8'); assert($text eq $expected, '$ctl->Render(): Bad output', "Got: $text", "Expected: $expected"); + + +}; + +test TestDocumentLayout => sub { + my ($this) = @_; + + my $loader = $this->CreateLoader(); + + my $doc = $loader->document('complex'); + assert($doc->layout eq 'Layout/default'); + + my $expected = read_file($this->GetResourceFile('Resources', 'TTView.Output', 'complex.default.txt'), binmode => ':utf8' ); + + assert($doc->templateVars('dojo.require')->[0]); + + my $text = $doc->Render({ data => [qw(one two three)] }); + + assert($text eq $expected, '$doc->Render(): Bad output', "Got: $text", "Expected: $expected"); }; test TestMemoryLeaks => sub { @@ -157,6 +177,7 @@ $doc->Render( { self => $doc } ); }); + $loader->template('Layout/default'); $loader->template('My/Org/Panel'); $loader->template('My/Org/TextPreview'); AssertMemoryLeak(sub {