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