Mercurial > pub > Impl
annotate Lib/IMPL/Web/Handler/TTView.pm @ 205:891c04080658
IMPL::Web::View fixed template selection, release candidate
| author | sergey |
|---|---|
| date | Thu, 03 May 2012 01:00:02 +0400 |
| parents | d63f9a92d6d4 |
| children | c8fe3f84feba |
| rev | line source |
|---|---|
|
199
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
1 package IMPL::Web::Handler::TTView; |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
2 use strict; |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
3 |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
4 use List::Util qw(first); |
|
199
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
5 use IMPL::lang qw(:declare :constants); |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
6 use IMPL::declare { |
|
205
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
7 require => { |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
8 Factory => 'IMPL::Object::Factory' |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
9 }, |
|
199
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
10 base => { |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
11 'IMPL::Object' => undef, |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
12 'IMPL::Object::Autofill' => '@_', |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
13 'IMPL::Object::Serializable' => undef |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
14 } |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
15 }; |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
16 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
17 BEGIN { |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
18 public property contentType => PROP_GET | PROP_OWNERSET; |
| 203 | 19 public property loader => PROP_GET | PROP_OWNERSET; |
| 20 public property selectors => PROP_GET | PROP_LIST | PROP_OWNERSET; | |
| 21 public property defaultDocument => PROP_ALL; | |
| 22 public property indexResource => PROP_ALL; | |
| 23 private property _selectorsCache => PROP_ALL; | |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
24 private property _classTemplates => PROP_ALL; |
| 203 | 25 } |
| 26 | |
| 27 sub CTOR { | |
| 28 my ($this) = @_; | |
| 29 | |
| 30 $this->indexResource('index') unless $this->indexResource; | |
|
199
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
31 } |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
32 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
33 sub Invoke { |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
34 my ($this,$action,$next) = @_; |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
35 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
36 my $result = $next ? $next->($action) : undef; |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
37 |
|
205
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
38 my $vars = { |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
39 data => $result, |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
40 action => $action, |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
41 app => $action->application, |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
42 LoadFactory => sub { |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
43 my $class = shift; |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
44 |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
45 my $module = $class; |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
46 |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
47 $module =~ s/::/\//g; |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
48 $module .= ".pm"; |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
49 |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
50 require $module; |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
51 return Factory->new($class); |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
52 } |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
53 }; |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
54 |
| 203 | 55 my $doc = $this->loader->document( |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
56 $this->SelectView($action,ref $result), |
|
205
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
57 $vars |
|
199
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
58 ); |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
59 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
60 my $hout = $action->response->streamBody; |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
61 |
|
205
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
62 print $hout $doc->Render($vars); |
|
199
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
63 } |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
64 |
| 203 | 65 sub SelectView { |
| 66 my ($this,$action,$class) = @_; | |
| 67 | |
| 68 my @path = split /\//, $action->query->path_info(), -1; | |
| 69 | |
|
205
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
70 shift @path; # remove always empty leading segment |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
71 |
| 203 | 72 my $last = pop @path; |
| 73 $last =~ s/\.\w+$//; | |
|
205
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
74 $last ||= $this->indexResource; |
| 203 | 75 push @path,$last; |
| 76 | |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
77 $this->BuildCache unless $this->_selectorsCache; |
| 203 | 78 my $cache = $this->_selectorsCache; |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
79 |
|
205
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
80 @path = reverse @path; |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
81 |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
82 foreach my $subclass ( $class ? (_GetHierarchy($class), '-default') : '-plain') { |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
83 my @results; |
|
205
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
84 push @results, { result => $this->_classTemplates->{$subclass}, level => 0 } if $this->_classTemplates->{$subclass}; |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
85 if ($cache->{$subclass}) { |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
86 my $alternatives = [ { selector => $cache->{$subclass}, immediate => 1 } ]; |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
87 $alternatives = $this->MatchAlternatives($_,$alternatives,\@results) foreach @path; |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
88 } |
| 203 | 89 |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
90 if (@results) { |
|
205
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
91 @results = sort { $b->{level} <=> $a->{level} } @results; |
|
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
92 return (shift @results)->{result}; |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
93 } |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
94 } |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
95 |
|
205
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
96 return $this->defaultDocument; |
| 203 | 97 } |
| 98 | |
| 99 sub _GetHierarchy { | |
| 100 my ($class) = @_; | |
| 101 return unless $class; | |
| 102 | |
| 103 no strict 'refs'; | |
| 104 | |
| 105 return $class, map { _GetHierarchy($_) } @{"${class}::ISA"}; | |
| 106 } | |
| 107 | |
| 108 sub BuildCache { | |
| 109 my ($this) = @_; | |
| 110 | |
| 111 my @selectors; | |
| 112 | |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
113 my $cache = $this->_selectorsCache({}); |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
114 $this->_classTemplates({}); |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
115 |
| 203 | 116 foreach my $selector ($this->selectors) { |
| 117 if (not ref $selector) { | |
| 118 | |
| 119 my ($path,$data) = split(/\s*=>\s*/, $selector); | |
| 120 | |
| 121 my @path = split(/\s+/,$path); | |
| 122 | |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
123 my $class; |
| 203 | 124 |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
125 # if this selector has a class part |
|
205
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
126 if ($path[$#path] =~ m/^\@(.*)/) { |
| 203 | 127 $class = $1; |
|
205
891c04080658
IMPL::Web::View fixed template selection, release candidate
sergey
parents:
204
diff
changeset
|
128 pop @path; |
| 203 | 129 } else { |
| 130 $class = '-default'; | |
| 131 } | |
| 132 | |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
133 #if this selector has a path |
| 203 | 134 if (@path) { |
| 135 @path = reverse @path; | |
| 136 my $last = pop @path; | |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
137 my $t = ( $cache->{$class} ||= {} ); |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
138 my $level = 1; |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
139 foreach my $prim (@path ) { |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
140 $t = ($t->{$prim}->{next} ||= {}); |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
141 $level ++; |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
142 } |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
143 $t->{$last}->{level} = $level; |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
144 $t->{$last}->{data} = $data; |
| 203 | 145 |
| 146 } else { | |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
147 # we dont have a selector, only class |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
148 |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
149 $this->_classTemplates->{$class} = $data; |
| 203 | 150 } |
| 151 | |
| 152 } | |
| 153 } | |
| 154 } | |
| 155 | |
| 156 sub MatchAlternatives { | |
| 157 my ($this,$segment,$alternatives,$results) = @_; | |
| 158 | |
| 159 my @next; | |
| 160 | |
| 161 foreach my $alt (@$alternatives) { | |
| 162 while (my ($selector,$match) = each %{$alt->{selector}} ) { | |
| 163 | |
| 164 | |
| 165 my $context = { | |
| 166 vars => \%{ $alt->{vars} || {} }, | |
| 167 selector => $match->{next} | |
| 168 }; | |
| 169 | |
| 170 if ($selector =~ s/^>//) { | |
| 171 $context->{immediate} = 1; | |
| 172 } | |
| 173 | |
| 174 if (my ($name,$rx) = ($selector =~ m/^\{(?:(\w+)\:)?(.*)\}$/) ) { | |
| 175 #this is a regexp | |
| 176 | |
| 177 if ( my @captures = ($segment =~ m/($rx)/) ) { | |
| 178 $context->{success} = 1; | |
| 179 | |
| 180 if ($name) { | |
| 181 $context->{vars}->{$name} = \@captures; | |
| 182 } | |
| 183 } | |
| 184 } else { | |
| 185 #this is a segment name | |
| 186 if ($segment eq $selector) { | |
| 187 $context->{success} = 1; | |
| 188 } | |
| 189 } | |
| 190 | |
| 191 # test if there were a match | |
| 192 if (delete $context->{success}) { | |
| 193 if (my $data = $match->{data}) { | |
| 194 # interpolate data | |
| 195 $data =~ s/{(\w+)(?:\:(\d+))?}/ | |
| 196 my ($name,$index) = ($1,$2 || 0); | |
| 197 | |
| 198 if ($context->{vars}{$name}) { | |
| 199 $context->{vars}{$name}[$index]; | |
| 200 } else { | |
| 201 ""; | |
| 202 } | |
| 203 /gex; | |
| 204 | |
| 205 push @$results, { level => $match->{level}, result => $data }; | |
| 206 } | |
| 207 push @next, $context if $context->{selector}; | |
| 208 } else { | |
| 209 #repeat current alternative if it's not required to be immediate | |
| 210 push @next, { | |
| 211 selector => { $selector, $match }, | |
| 212 vars => $alt->{vars} | |
| 213 } unless $alt->{immediate}; | |
| 214 } | |
| 215 } | |
| 216 } | |
| 217 | |
| 218 return \@next; | |
| 219 } | |
| 220 | |
|
199
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
221 1; |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
222 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
223 __END__ |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
224 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
225 =pod |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
226 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
227 =head1 NAME |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
228 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
229 C<IMPL::Web::Handler::TTView> - использует шаблоны для построения представления. |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
230 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
231 =head1 SYNOPSIS |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
232 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
233 =begin code xml |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
234 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
235 <view type="HASH"> |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
236 <item extname="@My::Data::Product">product/info</item> |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
237 <catalog> |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
238 <catalog> |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
239 </view> |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
240 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
241 =end code xml |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
242 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
243 =head1 DESCRIPTION |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
244 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
245 Подбирает шаблон для представления результата, полученного при выполнении следующего обработчика. При |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
246 выборе используется принцип похожий на селекторы C<CSS>, основывающийся на именах ресурсов и их типах |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
247 данных. |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
248 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
249 =head1 SELECTORS |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
250 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
251 =begin text |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
252 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
253 [url-template] [class] => template |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
254 |
| 200 | 255 shoes * => product/list |
|
199
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
256 {action:*.} @My::Data::Product => product/{action} |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
257 |
|
204
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
258 stuff list => product/list |
|
d63f9a92d6d4
+IMPL::Config::Include - simple way to include external config
sergey
parents:
203
diff
changeset
|
259 details => product/details |
| 203 | 260 |
|
199
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
261 =end text |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
262 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
263 |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
264 =cut |
|
e743a8481327
Added REST support for forms (with only get and post methods)
sergey
parents:
diff
changeset
|
265 |
