comparison Lib/IMPL/Web/View/TTContext.pm @ 351:cfd7570c2af2

working on TTView: created TTView class for rendering models
author cin
date Tue, 08 Oct 2013 17:40:35 +0400
parents 86b470004d47
children 675cd1829255
comparison
equal deleted inserted replaced
350:f356c4894d1b 351:cfd7570c2af2
29 tt_cache 29 tt_cache
30 parent 30 parent
31 prefix 31 prefix
32 cache 32 cache
33 includes 33 includes
34 modules
34 )) { 35 )) {
35 my $t = $prop; 36 my $t = $prop;
36 37
37 *{__PACKAGE__ . '::' . $prop} = sub { 38 *{__PACKAGE__ . '::' . $prop} = sub {
38 my $this = shift; 39 my $this = shift;
64 65
65 sub find_template { 66 sub find_template {
66 my ($this,$name) = @_; 67 my ($this,$name) = @_;
67 68
68 my $cache = $this->tt_cache; 69 my $cache = $this->tt_cache;
70
69 $this->tt_cache($cache = {}) unless $cache; 71 $this->tt_cache($cache = {}) unless $cache;
70 72
71 if(my $tpl = $cache->{$name}) { 73 if(my $tpl = $cache->{$name}) {
72 return $tpl; 74 return $tpl;
73 } 75 }
75 my @inc = ($this->base, @{$this->includes || []}); 77 my @inc = ($this->base, @{$this->includes || []});
76 78
77 my $ext = $this->tt_ext || ""; 79 my $ext = $this->tt_ext || "";
78 80
79 my $file; 81 my $file;
80 82
81 foreach my $dir (@inc) { 83 foreach my $dir (@inc) {
82 $file = $dir ? "$dir/$name" : $name; 84 $file = $dir ? "$dir/$name" : $name;
83 85
84 my $base = join('/',splice([split(/\/+/,$file)],0,-1)); 86 my $base = join('/',splice([split(/\/+/,$file)],0,-1));
85 87
86 $file = $ext ? "$file.$ext" : $file; 88 $file = $ext ? "$file.$ext" : $file;
87 89
88 warn "lookup: $file"; 90 if (exists($this->modules->{$file})) {
89 91 my $info = $this->modules->{$file};
90 my $tt = eval { $this->template($file) }; 92 return $cache->{$name} = $info
91 93 if $info;
92 return $cache->{$name} = { 94 } else {
93 base => $base, 95 if( my $tt = eval { $this->template($file) } ) {
94 labels => $this->load_labels($file), 96 my $info = {
95 template => $tt, 97 base => $base,
96 } if $tt; 98 labels => $this->load_labels($file),
99 template => $tt,
100 initialized => 0
101 };
102 $this->modules->{$file} = $info;
103 return $cache->{$name} = $info;
104 } else {
105 $this->modules->{$file} = undef;
106 }
107 }
97 } 108 }
98 109
99 $this->throw(Template::Constants::ERROR_FILE, "$name: not found"); 110 $this->throw(Template::Constants::ERROR_FILE, "$name: not found");
100 } 111 }
101 112
111 $args = shift; 122 $args = shift;
112 } 123 }
113 124
114 my $prefix = $this->prefix; 125 my $prefix = $this->prefix;
115 126
116 warn "no resolve" if $args and $args->{_no_resolve}; 127 if (not(($args and delete $args->{_no_resolve}) or ref $model)) {
117
118 if (not(($args and delete $args->{_no_resolve}) or ref $model)) {
119 $prefix = $prefix ? "${prefix}.${model}" : $model; 128 $prefix = $prefix ? "${prefix}.${model}" : $model;
120 $model = $this->resolve_model($model); 129 $model = $this->resolve_model($model);
121 } else { 130 } else {
122 $prefix = ""; 131 $prefix = "";
123 } 132 }
134 $args 143 $args
135 ) 144 )
136 ); 145 );
137 } 146 }
138 147
148 sub display_model {
149 my $this = shift;
150 my $model = shift;
151 my ($template, $args);
152
153 if (ref $_[0] eq 'HASH') {
154 $args = shift;
155 } else {
156 $template = shift;
157 $args = shift;
158 }
159
160 $args ||= {};
161
162 my $prefix = delete $args->{prefix} || $this->prefix;
163
164 if (my $rel = delete $args->{rel}) {
165 $prefix = $prefix ? "${prefix}.${rel}" : $rel;
166 }
167
168 $template = $template ? $this->find_template($template) : $this->find_template_for($model);
169
170 return $this->render(
171 $template,
172 hashApply(
173 {
174 prefix => $prefix,
175 model => $model,
176 },
177 $args
178 )
179 );
180 }
181
139 sub invoke_environment { 182 sub invoke_environment {
140 my ($this,$code,$env) = @_; 183 my ($this,$code,$env) = @_;
141 184
142 $env ||= {}; 185 $env ||= {};
143 186
144 my $out = eval { 187 my $out = eval {
145 $this->localise( 188 $this->localise(
146 hashApply( 189 hashApply(
147 { 190 {
148 root => $this->root || $this, 191 root => $this->root || $this,
192 modules => $this->modules || {},
149 cache => TypeKeyedCollection->new(), 193 cache => TypeKeyedCollection->new(),
150 display => sub { 194 display => sub {
151 $this->display(@_); 195 $this->display(@_);
152 }, 196 },
153 render => sub { 197 render => sub {
154 $this->render(@_); 198 $this->render(@_);
155 } 199 },
200 display_model => sub {
201 $this->display_model(@_);
202 },
203 tt_cache => {}
156 }, 204 },
157 $env 205 $env
158 ) 206 )
159 ); 207 );
160 208
172 sub render { 220 sub render {
173 my ($this,$template,$args) = @_; 221 my ($this,$template,$args) = @_;
174 222
175 $args ||= {}; 223 $args ||= {};
176 224
177 #TODO handle classes 225 my $info = ref $template ? $template : $this->find_template($template);
178 226
179 my ($base,$labels); 227 if (ref($info) ne 'HASH') {
180 228 carp "got an invalid template object: $info (" . ref($info) . ")";
181 $template = $this->find_template($template) unless ref $template; 229 $info = {
182 230 template => $info,
183 if (ref $template eq 'HASH') { 231 base => $this->base,
184 $base = $template->{base}; 232 initialized => 1
185 $labels = $template->{labels}; 233 };
186 $template = $template->{template};
187 } else {
188 carp "got an invalid template object: $template";
189 $base = $this->base;
190 } 234 }
191 235
192 return $this->invoke_environment( 236 return $this->invoke_environment(
193 sub { 237 sub {
194 return shift->include($template,$args); 238 my $ctx = shift;
239
240 unless($info->{initialized}) {
241 if(my $init = $info->{template}->blocks->{INIT}) {
242 $info->{initialized} = 1;
243 eval {
244 $ctx->visit($info->{template}->blocks);
245 $ctx->include($init);
246 };
247 $ctx->leave();
248 }
249 }
250
251 return $ctx->include($info->{template},$args);
195 }, 252 },
196 hashMerge( 253 hashMerge(
197 $labels || {}, 254 $info->{labels} || {},
198 { 255 {
199 base => $base, 256 base => $info->{base},
200 parent => $this 257 parent => $this
201 } 258 }
202 ) 259 )
203 ) 260 )
204 } 261 }