Mercurial > pub > Impl
annotate Lib/IMPL/Web/View/TTControl.pm @ 342:1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
author | cin |
---|---|
date | Wed, 03 Jul 2013 03:53:12 +0400 |
parents | 71221d79e6b4 |
children | 9bdccdf1f50b |
rev | line source |
---|---|
181 | 1 package IMPL::Web::View::TTControl; |
2 use strict; | |
3 | |
234 | 4 use IMPL::Const qw(:prop); |
334 | 5 use IMPL::lang qw(:hash :base); |
299 | 6 use Scalar::Util qw(blessed reftype); |
234 | 7 use IMPL::declare { |
8 require => { | |
296 | 9 TemplateDocument => 'Template::Document', |
234 | 10 TTContext => 'Template::Context', |
11 Exception => 'IMPL::Exception', | |
238 | 12 ArgumentException => '-IMPL::InvalidArgumentException', |
13 OperationException => '-IMPL::InvalidOperationException' | |
234 | 14 }, |
15 base => [ | |
241
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
16 'IMPL::Object' => undef |
234 | 17 ], |
18 props => [ | |
19 id => PROP_RO, | |
238 | 20 attributes => PROP_RW, |
234 | 21 context => PROP_RO, |
22 template => PROP_RO | |
23 ] | |
24 }; | |
25 | |
181 | 26 |
187 | 27 { |
194 | 28 my $nextId = 1; |
29 sub _GetNextId { | |
299 | 30 return '_' . $nextId++; |
194 | 31 } |
187 | 32 } |
181 | 33 |
300 | 34 our $AUTOLOAD_REGEX = qr/^[a-z]/; |
238 | 35 |
334 | 36 my %mapSkipAttributes = map { $_, 1 } qw(attributes context); |
37 | |
181 | 38 sub CTOR { |
299 | 39 my ($this,$template,$context,$attrs) = @_; |
194 | 40 |
299 | 41 |
194 | 42 $this->template( $template ) or die new IMPL::ArgumentException("A template is required"); |
334 | 43 |
44 die IMPL::ArgumentException->new(context => "A context is required, supplied: $context") | |
45 unless is($context,TTContext); | |
46 | |
47 $this->context( $context ); | |
194 | 48 |
238 | 49 $this->attributes({}); |
194 | 50 |
301 | 51 if(ref($attrs) eq 'HASH') { |
299 | 52 while (my($key,$value) = each %$attrs) { |
334 | 53 next if $mapSkipAttributes{$key}; |
299 | 54 $this->SetAttribute($key,$value); |
55 } | |
307 | 56 } |
241
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
57 |
299 | 58 $this->id(_GetNextId()) unless $this->id; |
191 | 59 } |
60 | |
238 | 61 sub GetAttribute { |
62 my ($this,$name) = (shift,shift); | |
63 | |
64 if (my $method = $this->can($name)) { | |
65 unshift @_,$this; | |
66 goto &$method; | |
67 } else { | |
68 return $this->attributes->{$name}; | |
69 } | |
70 } | |
71 | |
72 sub SetAttribute { | |
73 my $this = shift; | |
74 my $name = shift; | |
75 | |
76 if (my $method = $this->can($name)) { | |
77 unshift @_, $this; | |
78 goto &$method; | |
79 } else { | |
80 return $this->attributes->{$name} = shift; | |
81 } | |
82 } | |
83 | |
187 | 84 sub Render { |
194 | 85 my ($this,$args) = @_; |
86 | |
87 $args = {} unless ref $args eq 'HASH'; | |
88 | |
299 | 89 return $this->context->include( |
301 | 90 $this->template->block, |
299 | 91 { |
92 %$args, | |
93 this => $this, | |
94 template => $this->template | |
95 } | |
96 ); | |
267 | 97 } |
98 | |
302 | 99 sub GetTemplate { |
100 my ($this,$name) = @_; | |
101 | |
102 return eval { $this->context->template($name) }; | |
103 } | |
104 | |
105 sub Include { | |
106 my ($this,$template, $args) = @_; | |
107 | |
108 my $tpl = $this->GetTemplate($template) | |
109 or die OperationException->new("The specified template isn't found", $template); | |
110 | |
111 return $this->context->include( | |
112 $tpl, | |
113 $args | |
114 ); | |
115 } | |
116 | |
314 | 117 sub HasBlock { |
118 my ($this,$block) = @_; | |
119 | |
120 $this->GetTemplate ? 1 : 0; | |
121 } | |
122 | |
185 | 123 sub AUTOLOAD { |
194 | 124 our $AUTOLOAD; |
125 | |
126 my $method = ($AUTOLOAD =~ m/(\w+)$/)[0]; | |
127 | |
128 return if $method eq 'DESTROY'; | |
129 | |
300 | 130 if ($method =~ /$AUTOLOAD_REGEX/) { |
238 | 131 my $this = shift; |
241
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
132 |
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
133 die OperationException->new("can't invoke method '$method' on an unblessed reference") unless blessed $this; |
238 | 134 |
135 return @_ ? $this->SetAttribute($method,@_) : $this->GetAttribute($method); | |
136 } else { | |
137 die OperationException->new("The specified method '$method' doesn't exists"); | |
138 } | |
181 | 139 } |
140 | |
342
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
141 sub CloneContext { |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
142 my ($this) = @_; |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
143 |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
144 $this->context->localise(); |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
145 |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
146 my $args = { %{$this->context} }; |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
147 delete $args->{CONFIG}; |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
148 |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
149 $this->context->delocalise(); |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
150 |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
151 return TTContext->new($args); |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
152 } |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
153 |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
154 sub CreateControlFromTemplate { |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
155 my ($this,$template,$args) = @_; |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
156 |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
157 if (not ref($template)) { |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
158 return $this->context->stash->get([ |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
159 require => [ |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
160 $template |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
161 ] |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
162 ])->new($args); |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
163 } else { |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
164 return $this->new( |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
165 $template, |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
166 $this->CloneContext(), |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
167 $args |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
168 ); |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
169 } |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
170 } |
1090c1dd7429
TTControl: added a helper method 'CreateControlFromTemlpate'
cin
parents:
334
diff
changeset
|
171 |
181 | 172 1; |
173 | |
174 __END__ | |
175 | |
176 =pod | |
177 | |
178 =head1 NAME | |
179 | |
180 C<IMPL::Web::View::TTControl> | |
181 | |
182 =head1 SYNPOSIS | |
183 | |
265 | 184 =begin text |
185 | |
186 [% | |
187 META version = 1; | |
188 BLOCK INIT; | |
189 # this is a document scope | |
299 | 190 dojo.modules.push( 'dijit/form/Input' ); |
265 | 191 END; |
299 | 192 |
193 # local to this block | |
194 TPreview = require('My/Org/TextPreview'); | |
265 | 195 |
299 | 196 # init control props |
197 visualClass = this.visualClass || 'classic'; | |
198 %] | |
199 <div id="$id" class="$visualClass" data-dojo-type="dijit/form/Input"> | |
200 [% FOREACH item IN model %] | |
201 <div class="itemContainer"> | |
202 [% Display(item) %] | |
203 </div> | |
265 | 204 [% END %] |
205 </div> | |
206 | |
207 =end text | |
208 | |
181 | 209 =head1 DESCRIPTION |
210 | |
299 | 211 Легкая обертка вокруг шаблона, позволяет изолировать пространство имен шаблона, |
212 а также реализовать собственные методы по представлению данных (в случае если | |
213 это проще сделать в виде методов класса). | |
265 | 214 |
181 | 215 =head2 BLOCKS |
216 | |
265 | 217 =head3 META |
218 | |
219 Атрибуты C<META> C<layout>, C<title> будут перенесены в свойства элемента | |
220 управления. | |
221 | |
181 | 222 =head3 INIT |
223 | |
265 | 224 Данный блок шаблона управления выполняется один раз при создании первого |
225 экземпляра элемента управления, в пространстве имен документа. Может | |
226 использоваться для формирования заголовочной части документа, скрипта | |
227 подключающего C<js> модули и т.п. | |
228 | |
229 Выполнение данного блока производится фабрикой элементов управления. | |
181 | 230 |
187 | 231 =head2 TEMPLATE VARS |
232 | |
265 | 233 Каждый шаблон имеет собственное пространство имен, вложенное в пространство имен |
234 фабрики элементов (которая разделяет пространство имен документа). В шаблоне | |
235 могут определяться новые переменные, однако они останутся локальными для блоков. | |
236 | |
237 Чтобы передать данные между блоками следует использовать ссылку на элемент | |
238 управления C<this>. | |
239 | |
240 =begin text | |
241 | |
242 [% | |
243 BLOCK CTOR; | |
244 this.extraCssClass = 'active'; | |
245 text = "this text will gone"; | |
246 END; | |
247 %] | |
248 | |
249 <div class="$this.extraCssClass">some text $text</div> | |
250 | |
251 =end text | |
252 | |
253 В примере выше переменная C<$text> установленная в конструкторе шаблона, при | |
254 отображении элемента управления будет неопределена. | |
187 | 255 |
256 =over | |
257 | |
265 | 258 =item * C<this> |
259 | |
260 ссылка на объект элемента управления | |
261 | |
262 =item * C<component> | |
187 | 263 |
265 | 264 ссылка на текущий шаблон, устанавливается автоматически в методе |
265 C<Template::Context::process>. | |
187 | 266 |
265 | 267 =item * C<template> |
268 | |
269 ссылка на шаблон элемента управления, для совместимости с C<TT> | |
187 | 270 |
271 =back | |
272 | |
273 =head1 MEMBERS | |
274 | |
300 | 275 =head2 C<[get]context> |
187 | 276 |
300 | 277 Контекст элемента управления, хранит пременные шаблона. Фабрика элементов |
278 управления создает новый контекст пространство имен которого вложено в | |
279 пространство имен документа. | |
187 | 280 |
300 | 281 Контекст следует использовать только при рендеринге документа. |
282 | |
283 =head2 C<[get,set]template> | |
187 | 284 |
285 C<Template::Document> Шаблон элемента управления. | |
286 | |
300 | 287 =head2 C<AUTOLOAD> |
187 | 288 |
265 | 289 Для удобства работы с шаблоном, элементы управления предоставляю доступ к своим |
290 свойствам через метод C<AUTOLOAD>. Имена свойств должны начинаться со строчной | |
291 буквы. | |
187 | 292 |
181 | 293 =cut |