comparison Lib/IMPL/Web/View/TTDocument.pm @ 194:4d0e1962161c

Replaced tabs with spaces IMPL::Web::View - fixed document model, new features (control classes, document constructor parameters)
author cin
date Tue, 10 Apr 2012 20:08:29 +0400
parents 8e8401c0aea4
children 7a920771fd8e
comparison
equal deleted inserted replaced
193:8e8401c0aea4 194:4d0e1962161c
8 8
9 use Scalar::Util qw(weaken); 9 use Scalar::Util qw(weaken);
10 10
11 11
12 use parent qw( 12 use parent qw(
13 IMPL::DOM::Document 13 IMPL::DOM::Document
14 IMPL::Web::View::TTControl 14 IMPL::Web::View::TTControl
15 ); 15 );
16 16
17 BEGIN { 17 BEGIN {
18 public _dom property layout => PROP_ALL; 18 public _dom property layout => PROP_ALL;
19 public property opts => PROP_GET | PROP_OWNERSET; 19 public property opts => PROP_GET | PROP_OWNERSET;
20 public property loader => PROP_GET | PROP_OWNERSET; 20 public property loader => PROP_ALL;
21 public property controls => PROP_GET | PROP_OWNERSET; 21 public property controls => PROP_GET | PROP_OWNERSET;
22 22
23 # store the stash separately to make require() method to work correctly 23 # store the stash separately to make require() method to work correctly
24 # even when a stash of the context is modified during the processing 24 # even when a stash of the context is modified during the processing
25 public property stash => PROP_GET | PROP_OWNERSET; 25 public property stash => PROP_GET | PROP_OWNERSET;
26 } 26 }
27 27
28 sub CTOR { 28 sub CTOR {
29 my ($this,$template,$refOpts,%args) = @_; 29 my ($this,$template,$refOpts,$loader,$vars) = @_;
30 30
31 $this->controls({}); 31 $this->controls({});
32 $this->loader($args{loader}) if $args{loader}; 32 $this->loader($loader) if $loader;
33 33
34 $this->layout( $template->layout ) unless $this->layout; 34 $this->layout( $template->layout ) unless $this->layout;
35 35
36 $this->opts($refOpts); 36 $this->opts($refOpts);
37 $this->stash($this->context->stash); 37 $this->stash($this->context->stash);
38 38
39 my $self = $this; 39 my $self = $this;
40 weaken($self); 40 weaken($self);
41 41
42 $this->templateVars('require', sub { 42 $this->templateVars('require', sub {
43 my $doc = $self; 43 my $doc = $self;
44 die new IMPL::Exception("A document is destroyed or invalid") unless $doc; 44 die new IMPL::Exception("A document is destroyed or invalid") unless $doc;
45 $doc->require(@_); 45 $doc->require(@_);
46 }); 46 });
47 47
48 $this->templateVars('document', sub { $self } ); 48 $this->templateVars('document', sub { $self } );
49 $this->InitInstance(); 49 $this->InitInstance($vars);
50 } 50 }
51 51
52 our %CTOR = ( 52 our %CTOR = (
53 'IMPL::Web::View::TTControl' => sub { 53 'IMPL::Web::View::TTControl' => sub {
54 'document', 54 my ($template,$contextOpts) = @_;
55 $_[0], # template 55 'document',
56 new Template::Context($_[1]) # context 56 $_[0], # template
57 }, 57 new Template::Context($_[1]) # context
58 'IMPL::DOM::Document' => sub { 58 },
59 nodeName => 'document' 59 'IMPL::DOM::Document' => sub {
60 } 60 nodeName => 'document'
61 }
61 ); 62 );
62 63
63 sub templateVars { 64 sub templateVars {
64 my $this = shift; 65 my $this = shift;
65 my $name = shift; 66 my $name = shift;
66 67
67 if (@_) { 68 if (@_) {
68 return $this->stash->set($name, shift); 69 return $this->stash->set($name, shift);
69 } else { 70 } else {
70 return $this->stash->get($name); 71 return $this->stash->get($name);
71 } 72 }
72 } 73 }
73 74
74 sub require { 75 sub require {
75 my ($this, $control, $nodeProps) = @_; 76 my ($this, $control, $nodeProps) = @_;
76 77
77 $nodeProps ||= {}; 78 $nodeProps ||= {};
78 $nodeProps->{document} = $this; 79 $nodeProps->{document} = $this;
79 80
80 if (my $factory = $this->controls->{$control}) { 81 if (my $factory = $this->controls->{$control}) {
81 return $factory; 82 return $factory;
82 } else { 83 } else {
83 84
84 my $path = $control; 85 my $path = $control;
85 if ( my $template = $this->loader->template($path) ) { 86 if ( my $template = $this->loader->template($path) ) {
86 87 my $opts = { %{$this->opts} };
87 my $opts = { %{$this->opts} }; 88
88 $opts->{STASH} = $this->context->stash->clone(); 89 # avoid propagation of local variables
90 $opts->{STASH} = $this->stash->clone();
89 91
90 my $ctx = new Template::Context($opts); 92 my $ctx = new Template::Context($opts);
91 93
92 $factory = new IMPL::Web::View::TTFactory( 94 $factory = new IMPL::Web::View::TTFactory(
93 typeof IMPL::Web::View::TTControl, 95 $template->class || typeof IMPL::Web::View::TTControl,
94 $template, 96 $template,
95 $ctx, 97 $ctx,
96 $opts, 98 $opts
97 { document => $this } 99 );
98 ); 100
99 101 my @parts = split(/\/+/,$control);
100 my @parts = split(/\/+/,$control); 102
101 103 $this->controls->{$control} = $factory;
102 $this->controls->{$control} = $factory; 104
103 105 return $factory;
104 return $factory; 106
105 107 } else {
106 } else { 108 die new IMPL::KeyNotFoundException($control);
107 die new IMPL::KeyNotFoundException($control); 109 }
108 } 110 }
109 }
110 } 111 }
111 112
112 sub Render { 113 sub Render {
113 my ($this,$args) = @_; 114 my ($this,$args) = @_;
114 115
115 my $output; 116 my $output;
116 117
117 if ($this->layout) { 118 if ($this->layout) {
118 $output = $this->context->include( 119 $output = $this->context->include(
119 $this->loader->template($this->layout), 120 $this->loader->template($this->layout),
120 { 121 {
121 content => sub { $output ||= $this->RenderContent($args); } 122 content => sub { $output ||= $this->RenderContent($args); },
122 } 123 this => $this,
123 ); 124 template => $this->template
124 } else { 125 }
125 return $this->RenderContent($args); 126 );
126 } 127 } else {
127 128 return $this->RenderContent($args);
128 return $output; 129 }
130
131 return $output;
129 } 132 }
130 133
131 sub RenderContent { 134 sub RenderContent {
132 my $this = shift; 135 my $this = shift;
133 return $this->SUPER::Render(@_); 136 return $this->SUPER::Render(@_);
134 } 137 }
135 138
136 139
137 1; 140 1;
138 141
213 216
214 =head2 Загрузка элемента управления 217 =head2 Загрузка элемента управления
215 218
216 =over 219 =over
217 220
218 =item 1 C<require('my/org/input')> 221 =item 1 C<TInput = require('my/org/input')>
219 222
220 =item 1 Загружает шаблон C<my/org/input.tt> 223 =item 1 Загружает шаблон C<my/org/input.tt>
221 224
222 =item 1 Создает фабрику элементов управления с собственным контекстом, унаследованным от контекст документа. 225 =item 1 Создает фабрику элементов управления с собственным контекстом, унаследованным от контекст документа.
223 226
227 230
228 =head2 Создание элемента управления 231 =head2 Создание элемента управления
229 232
230 =over 233 =over
231 234
232 =item 1 C<< my.org.input.new('login') >> 235 =item 1 C<< TInput.new('login') >>
233 236
234 =item 1 Если это первый элемент управления, то выполняетя статический конструктор в контексте фабрики 237 =item 1 Если это первый элемент управления, то выполняетя статический конструктор в контексте фабрики
235 238
236 =item 1 Создается новый дочерний контекст к контексту фабрики 239 =item 1 Создается новый дочерний контекст к контексту фабрики
237 240