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