Mercurial > pub > Impl
annotate Lib/IMPL/Web/View/TTContext.pm @ 373:3ca44e23fd1f
implemented new web resource
author | cin |
---|---|
date | Wed, 25 Dec 2013 17:29:38 +0400 |
parents | d5c8b955bf8d |
children | 1eca08048ba9 |
rev | line source |
---|---|
343 | 1 package IMPL::Web::View::TTContext; |
2 use strict; | |
3 use Template::Base; | |
348 | 4 use Carp qw(carp); |
349 | 5 use File::Spec(); |
6 use IMPL::Resources::Format qw(FormatMessage); | |
7 use IMPL::Resources::Strings(); | |
343 | 8 |
348 | 9 use IMPL::Exception(); |
349 | 10 use IMPL::lang qw(is typeof hashApply hashMerge); |
343 | 11 use IMPL::declare { |
348 | 12 require => { |
13 Document => '-Template::Document', | |
14 TypeKeyedCollection => 'IMPL::TypeKeyedCollection', | |
349 | 15 ArgException => '-IMPL::InvalidArgumentException', |
352 | 16 Resources => 'IMPL::Resources', |
371 | 17 Loader => 'IMPL::Code::Loader', |
18 MetadataBase => '-IMPL::Web::View::Metadata::BaseMeta', | |
19 Metadata => 'IMPL::Web::View::Metadata::ObjectMeta' | |
348 | 20 }, |
21 base => [ | |
343 | 22 'Template::Context' => '@_' |
348 | 23 ] |
343 | 24 }; |
25 | |
347 | 26 BEGIN { |
348 | 27 no strict 'refs'; |
359
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
28 # modules is a global (for the whole document) templates cache |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
29 # tt_cache is a local (for the current context only) templtes cache |
347 | 30 foreach my $prop (qw( |
348 | 31 root |
347 | 32 base |
33 tt_ext | |
348 | 34 tt_cache |
347 | 35 parent |
36 prefix | |
348 | 37 cache |
38 includes | |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
39 modules |
352 | 40 aliases |
370
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
41 |
356 | 42 id |
370
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
43 metadata |
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
44 model |
347 | 45 )) { |
46 my $t = $prop; | |
47 | |
348 | 48 *{__PACKAGE__ . '::' . $prop} = sub { |
347 | 49 my $this = shift; |
50 return @_ ? $this->stash->set($t, @_) : $this->stash->get($t); | |
51 } | |
52 } | |
53 } | |
54 | |
343 | 55 sub clone { |
56 my $this = shift; | |
347 | 57 my $params = shift; |
343 | 58 |
59 $this->localise(); | |
60 | |
61 my $args = { %{$this} }; | |
62 | |
63 $this->delocalise(); | |
64 | |
348 | 65 my $class = ref($this); |
343 | 66 |
67 delete $args->{CONFIG}; | |
68 | |
347 | 69 my $clone = $class->new($args); |
70 | |
71 $clone->stash->update($params) if $params; | |
72 | |
73 return $clone; | |
345 | 74 } |
75 | |
356 | 76 sub get_next_id { |
77 my ($this) = @_; | |
78 | |
79 my $id = $this->stash->get('document.nextId') || 0; | |
80 $this->stash->set('document.nextId', $id + 1); | |
81 return "w-$id"; | |
82 } | |
83 | |
345 | 84 sub find_template { |
359
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
85 my ($this,$name, $nothrow) = @_; |
348 | 86 |
87 my $cache = $this->tt_cache; | |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
88 |
348 | 89 $this->tt_cache($cache = {}) unless $cache; |
345 | 90 |
348 | 91 if(my $tpl = $cache->{$name}) { |
92 return $tpl; | |
93 } | |
94 | |
95 my @inc = ($this->base, @{$this->includes || []}); | |
96 | |
345 | 97 my $ext = $this->tt_ext || ""; |
348 | 98 |
99 my $file; | |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
100 |
345 | 101 foreach my $dir (@inc) { |
348 | 102 $file = $dir ? "$dir/$name" : $name; |
103 | |
104 my $base = join('/',splice([split(/\/+/,$file)],0,-1)); | |
105 | |
106 $file = $ext ? "$file.$ext" : $file; | |
107 | |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
108 if (exists($this->modules->{$file})) { |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
109 my $info = $this->modules->{$file}; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
110 return $cache->{$name} = $info |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
111 if $info; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
112 } else { |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
113 if( my $tt = eval { $this->template($file) } ) { |
352 | 114 my $class; |
115 if ($class = $tt->class) { | |
116 $class = $this->aliases->{$class} || $class; | |
117 Loader->safe->Require($class); | |
118 } | |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
119 my $info = { |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
120 base => $base, |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
121 labels => $this->load_labels($file), |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
122 template => $tt, |
352 | 123 initialized => 0, |
124 class => $class | |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
125 }; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
126 $this->modules->{$file} = $info; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
127 return $cache->{$name} = $info; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
128 } else { |
353 | 129 my $err = $@; |
130 | |
131 for(my $t = $err; is($t,'Template::Exception'); $t = $t->info ) { | |
132 die $err unless $t->type eq Template::Constants::ERROR_FILE; | |
133 } | |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
134 $this->modules->{$file} = undef; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
135 } |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
136 } |
345 | 137 } |
138 | |
359
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
139 $this->throw(Template::Constants::ERROR_FILE, "$name: not found") |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
140 unless $nothrow; |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
141 return; |
345 | 142 } |
143 | |
359
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
144 sub display_for { |
347 | 145 my $this = shift; |
370
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
146 my $path = shift; |
348 | 147 my ($template, $args); |
347 | 148 |
149 if (ref $_[0] eq 'HASH') { | |
150 $args = shift; | |
151 } else { | |
152 $template = shift; | |
153 $args = shift; | |
154 } | |
155 | |
348 | 156 my $prefix = $this->prefix; |
157 | |
354 | 158 my $info; |
371 | 159 my $meta = $this->resolve_model($path,$args) |
160 or return "[not found '$path']"; | |
354 | 161 |
371 | 162 $info->{prefix} = join('.', grep($_, $prefix, $path)); |
370
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
163 $info->{model} = $meta->model; |
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
164 $info->{metadata} = $meta; |
348 | 165 |
355
8dfb9df07d02
added support for the custom resolvers for the TTView
sergey
parents:
354
diff
changeset
|
166 $template ||= $info->{template}; |
371 | 167 $template = $template ? $this->find_template($template) : $this->find_template_for($info->{metadata}); |
348 | 168 |
169 return $this->render( | |
170 $template, | |
171 hashApply( | |
354 | 172 $info, |
348 | 173 $args |
174 ) | |
175 ); | |
176 } | |
177 | |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
178 sub display_model { |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
179 my $this = shift; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
180 my $model = shift; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
181 my ($template, $args); |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
182 |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
183 if (ref $_[0] eq 'HASH') { |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
184 $args = shift; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
185 } else { |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
186 $template = shift; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
187 $args = shift; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
188 } |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
189 |
371 | 190 #copy |
191 $args = { %{$args || {}} }; | |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
192 |
371 | 193 $args->{prefix} = join('.',grep($_,$this->prefix,$args->{path})) |
194 unless defined $args->{prefix}; | |
195 | |
196 if (is($model,MetadataBase)) { | |
197 $args->{model} = $model->model; | |
198 $args->{metadata} = $model; | |
199 } else { | |
200 $args->{model} = $model; | |
201 $args->{metadata} = Metadata->GetMetadataForModel($model); | |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
202 } |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
203 |
371 | 204 $template = $template ? $this->find_template($template) : $this->find_template_for($args->{metadata}); |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
205 |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
206 return $this->render( |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
207 $template, |
371 | 208 $args |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
209 ); |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
210 } |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
211 |
359
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
212 # обеспечивает необходимый уровень изоляции между контекстами |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
213 # $code - код, который нужно выполнить в новом контексте |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
214 # $env - хеш с переменными, которые будут переданы в новый контекст |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
215 # в процессе будет создан клон корневого контекста, со всеми его свойствами |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
216 # затем новый контекст будет локализован и в него будут добавлены новые переменные из $env |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
217 # созданный контекст будет передан параметром в $code |
348 | 218 sub invoke_environment { |
219 my ($this,$code,$env) = @_; | |
220 | |
221 $env ||= {}; | |
222 | |
354 | 223 my $ctx = ($this->root || $this)->clone(); |
359
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
224 |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
225 my @includes = @{$this->includes || []}; |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
226 |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
227 if ($this->base) { |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
228 unshift @includes, $this->base; |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
229 } |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
230 |
348 | 231 my $out = eval { |
354 | 232 $ctx->localise( |
348 | 233 hashApply( |
234 { | |
359
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
235 includes => \@includes, |
352 | 236 aliases => $this->aliases || {}, |
354 | 237 root => $this->root || $ctx, |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
238 modules => $this->modules || {}, |
348 | 239 cache => TypeKeyedCollection->new(), |
359
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
240 display_for => sub { |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
241 $ctx->display_for(@_); |
348 | 242 }, |
243 render => sub { | |
354 | 244 $ctx->render(@_); |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
245 }, |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
246 display_model => sub { |
354 | 247 $ctx->display_model(@_); |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
248 }, |
370
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
249 tt_cache => {} |
348 | 250 }, |
251 $env | |
252 ) | |
253 ); | |
254 | |
354 | 255 &$code($ctx); |
348 | 256 }; |
257 | |
258 my $e = $@; | |
354 | 259 $ctx->delocalise(); |
348 | 260 |
261 die $e if $e; | |
262 | |
263 return $out; | |
264 } | |
265 | |
359
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
266 # использует указанный шаблон для создания фрагмента документа |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
267 # шаблон может быть как именем, так и хешем, содержащим информацию |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
268 # о шаблоне. |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
269 # отдельно следует отметить, что данный метод создает новый контекст |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
270 # для выполнения шаблона в котором задает переменные base, parent, id |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
271 # а также создает переменные для строковых констант из labels |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
272 # хеш с переменными $args будет передан самому шаблону в момент выполнения |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
273 # если у шаблона указан класс элемента управления, то при выполнении шаблона |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
274 # будет создан экземпляр этого класса и процесс выполнения шаблона будет |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
275 # делегирован методу Render этого экземпляра. |
348 | 276 sub render { |
277 my ($this,$template,$args) = @_; | |
278 | |
279 $args ||= {}; | |
280 | |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
281 my $info = ref $template ? $template : $this->find_template($template); |
348 | 282 |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
283 if (ref($info) ne 'HASH') { |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
284 carp "got an invalid template object: $info (" . ref($info) . ")"; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
285 $info = { |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
286 template => $info, |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
287 base => $this->base, |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
288 initialized => 1 |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
289 }; |
348 | 290 } |
291 | |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
292 return $this->invoke_environment( |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
293 sub { |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
294 my $ctx = shift; |
352 | 295 |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
296 unless($info->{initialized}) { |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
297 if(my $init = $info->{template}->blocks->{INIT}) { |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
298 $info->{initialized} = 1; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
299 eval { |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
300 $ctx->visit($info->{template}->blocks); |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
301 $ctx->include($init); |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
302 }; |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
303 $ctx->leave(); |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
304 } |
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
305 } |
352 | 306 |
307 if (my $class = $info->{class}) { | |
359
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
308 $class->new($ctx,$info->{template},$args)->Render({}); |
352 | 309 } else { |
310 return $ctx->include($info->{template},$args); | |
311 } | |
348 | 312 }, |
349 | 313 hashMerge( |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
314 $info->{labels} || {}, |
349 | 315 { |
351
cfd7570c2af2
working on TTView: created TTView class for rendering models
cin
parents:
349
diff
changeset
|
316 base => $info->{base}, |
356 | 317 parent => $this, |
318 id => $this->get_next_id | |
349 | 319 } |
320 ) | |
348 | 321 ) |
322 } | |
323 | |
324 sub resolve_model { | |
370
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
325 my ($this,$prefix) = @_; |
348 | 326 |
327 die ArgException->new(prefix => "the prefix must be specified") | |
328 unless defined $prefix; | |
329 | |
370
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
330 my $meta = $this->metadata; |
371 | 331 unless($meta) { |
332 $meta = Metadata->GetMetadataForModel($this->model); | |
333 $this->metadata($meta); | |
334 } | |
335 | |
370
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
336 foreach my $part (grep length($_), split(/\.|\[(\d+)\]/, $prefix)) { |
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
337 last unless $meta; |
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
338 if ($part =~ /^\d+$/) { |
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
339 $meta = $meta->GetItem($part); |
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
340 } else { |
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
341 $meta = $meta->GetProperty($part); |
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
342 } |
354 | 343 } |
344 | |
370
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
345 return $meta; |
348 | 346 } |
347 | |
348 sub find_template_for { | |
370
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
349 my ($this,$meta, $nothrow) = @_; |
347 | 350 |
371 | 351 die ArgException->new(meta => 'An invalid metadata is supplied') |
352 unless is($meta,MetadataBase); | |
353 | |
370
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
354 return $this->find_template($meta->template) |
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
355 if ($meta->template); |
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
356 |
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
357 my $type = $meta->modelType; |
347 | 358 |
348 | 359 return $this->find_template('templates/plain') unless $type; |
360 | |
361 if (my $template = $this->cache->Get($type)) { | |
362 return $template; | |
363 } else { | |
364 | |
365 no strict 'refs'; | |
366 | |
367 my @isa = $type; | |
368 | |
369 while (@isa) { | |
370 my $sclass = shift @isa; | |
371 | |
372 (my $name = $sclass) =~ s/:+/_/g; | |
359
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
373 my ($shortName) = ($sclass =~ m/(\w+)$/); |
348 | 374 |
359
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
375 $template = $this->find_template("templates/$name",1) || $this->find_template("templates/$shortName",1); |
348 | 376 |
377 if ($template) { | |
378 $this->cache->Set($sclass,$template); | |
379 return $template; | |
380 } | |
370
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
381 |
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
382 #todo $meta->GetISA |
348 | 383 push @isa, @{"${sclass}::ISA"}; |
384 } | |
385 | |
386 } | |
370
cbf4febf0930
ObjectMeta, Tests, migrating to the new metadata model.
sergey
parents:
359
diff
changeset
|
387 $this->throw(Template::Constants::ERROR_FILE, "can't find a template for the model $type") |
359
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
388 unless $nothrow; |
833e663796c4
TTView: added view variable to pass rendering context between controls
sergey
parents:
356
diff
changeset
|
389 |
348 | 390 return; |
347 | 391 } |
392 | |
349 | 393 sub get_real_file { |
394 my ($this,$fname) = @_; | |
395 | |
396 my @path = split(/\/+/,$fname); | |
397 | |
398 foreach my $provider (@{$this->load_templates || []}) { | |
399 foreach my $dir (@{$provider->paths || []}) { | |
400 my $realName = File::Spec->catfile($dir,@path); | |
401 return $realName if -f $realName; | |
402 } | |
403 } | |
404 } | |
405 | |
406 sub load_labels { | |
407 my ($this,$fname) = @_; | |
408 | |
409 $fname = $this->get_real_file($fname); | |
410 | |
411 my %vars; | |
412 | |
413 my $flabels = "$fname.labels"; | |
414 | |
415 if (-f $flabels) { | |
416 | |
417 my %labels; | |
418 $labels{default} = IMPL::Resources::Strings::ParseStringsMap($flabels); | |
419 | |
420 while(my($label,$text) = each %{$labels{default}}) { | |
421 $vars{$label} = sub { | |
422 my ($params) = @_; | |
423 my $locale = Resources->currentLocale; | |
424 | |
425 unless ($labels{$locale}) { | |
426 $labels{$locale} = -f "$fname.$locale" ? | |
427 IMPL::Resources::Strings::ParseStringsMap("$fname.$locale") : | |
428 {}; | |
429 } | |
430 | |
431 return FormatMessage(($labels{$locale}{$label} || $text),$params); | |
432 } | |
433 } | |
434 } | |
435 | |
436 return \%vars; | |
437 } | |
438 | |
345 | 439 1; |
440 | |
441 __END__ | |
442 | |
443 =pod | |
444 | |
445 =head1 NAME | |
446 | |
447 C<IMPL::Web::View::TTContext> - доработанная версия контекста | |
448 | |
449 =head1 DESCRIPTION | |
450 | |
451 Расширяет функции C<Template::Context> | |
452 | |
453 =begin plantuml | |
454 | |
455 @startuml | |
456 | |
348 | 457 object RootContext { |
345 | 458 document |
346 | 459 globals |
345 | 460 } |
461 | |
462 object DocumentContext { | |
346 | 463 base |
464 extends | |
465 } | |
466 | |
467 object ControlContext { | |
468 base | |
469 extends | |
345 | 470 } |
471 | |
348 | 472 RootContext o-- DocumentContext |
473 RootContext o-- ControlContext | |
345 | 474 |
346 | 475 Document -- DocumentContext |
476 Control - ControlContext | |
345 | 477 |
348 | 478 Loader . RootContext: <<creates>> |
346 | 479 Loader . Document: <<creates>> |
480 Loader -up- Registry | |
345 | 481 |
482 @enduml | |
483 | |
484 =end plantuml | |
485 | |
486 =head1 MEMBERS | |
487 | |
488 =head2 C<[get,set]base> | |
489 | |
490 Префикс пути для поиска шаблонов | |
491 | |
492 =head2 C<template($name)> | |
493 | |
494 Сначала пытается загрузить шаблон используя префикс C<base>, затем без префикса. | |
495 | |
496 =head2 C<clone()> | |
497 | |
498 Создает копию контекста, при этом C<stash> локализуется, таким образом | |
499 клонированный контекст имеет собственное пространство имен, вложенное в | |
500 пространство родительского контекста. | |
501 | |
502 =cut |