Mercurial > pub > Impl
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 } |