Mercurial > pub > Impl
comparison Lib/IMPL/Web/View/TTDocument.pm @ 288:3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
author | sergey |
---|---|
date | Tue, 19 Feb 2013 19:58:27 +0400 |
parents | 2d253e6e4a88 |
children | 85572f512abc |
comparison
equal
deleted
inserted
replaced
287:2d253e6e4a88 | 288:3a9cfea098dd |
---|---|
1 package IMPL::Web::View::TTDocument; | 1 package IMPL::Web::View::TTDocument; |
2 use strict; | 2 use strict; |
3 | 3 |
4 use Scalar::Util qw(weaken); | 4 use Scalar::Util qw(weaken); |
5 use IMPL::Const qw(:prop); | 5 use IMPL::Const qw(:prop); |
6 use IMPL::lang qw(:hash); | 6 use IMPL::lang qw(:hash is); |
7 use Carp qw(carp); | |
8 use mro; | |
7 | 9 |
8 use IMPL::declare { | 10 use IMPL::declare { |
9 require => { | 11 require => { |
10 TTFactory => 'IMPL::Web::View::TTFactory', | 12 TTFactory => 'IMPL::Web::View::TTFactory', |
11 TTControl => 'IMPL::Web::View::TTControl', | 13 TTControl => 'IMPL::Web::View::TTControl', |
12 Loader => 'IMPL::Code::Loader' | 14 Loader => 'IMPL::Code::Loader' |
13 }, | 15 }, |
14 base => [ | 16 base => [ |
15 'IMPL::Web::View::TTControl' => sub { | 17 'IMPL::Web::View::TTControl' => sub { |
16 my ($template,$ctx) = @_; | 18 my ($template,$ctx) = @_; |
17 'document', | 19 $ctx ||= Template::Context->new(); |
18 $template, # template | 20 return 'document', $template, $ctx; # context |
19 $ctx || Template::Context->new() # context | |
20 } | 21 } |
21 ], | 22 ], |
22 props => [ | 23 props => [ |
23 layout => PROP_RW, | 24 layout => PROP_RW, |
24 loader => PROP_RW, | 25 loader => PROP_RW, |
25 controls => PROP_RO, | 26 controls => PROP_RO, |
26 creationArgs => PROP_RO, | |
27 | |
28 # store the stash separately to make require() method to work correctly | |
29 # even when a stash of the context is modified during the processing | |
30 stash => PROP_RO | |
31 ] | 27 ] |
32 }; | 28 }; |
33 | 29 |
34 BEGIN { | |
35 | |
36 } | |
37 | |
38 sub CTOR { | 30 sub CTOR { |
39 my ($this,$template,$ctx,$loader,$vars) = @_; | 31 my ($this,$template,$ctx,$loader,$vars) = @_; |
40 | 32 |
41 $this->controls({}); | 33 $this->controls({}); |
42 $this->loader($loader) if $loader; | 34 $this->loader($loader) if $loader; |
43 | 35 |
44 $this->layout( $template->layout ) unless $this->layout; | 36 $this->layout( $template->layout ) unless $this->layout; |
45 | 37 |
46 $this->stash($this->context->stash); | 38 $this->context->stash->update($vars) |
47 $this->creationArgs($vars); | 39 if ref $vars eq 'HASH'; |
48 | 40 |
49 my $self = $this; | 41 $this->InitInstance(); |
50 weaken($self); | |
51 | |
52 $this->templateVars(require => sub { | |
53 my $doc = $self; | |
54 die new IMPL::Exception("A document is destroyed or invalid") unless $doc; | |
55 $doc->RequireControl(@_); | |
56 }); | |
57 | |
58 $this->templateVars(document => sub { $self } ); | |
59 $this->InitInstance($vars); | |
60 } | 42 } |
61 | 43 |
62 sub templateVars { | 44 sub templateVars { |
63 my $this = shift; | 45 my $this = shift; |
64 my $name = shift; | 46 my $name = shift; |
65 | |
66 if (@_) { | 47 if (@_) { |
67 return $this->stash->set($name, shift); | 48 return $this->context->stash->set($name, shift); |
68 } else { | 49 } else { |
69 return $this->stash->get($name); | 50 return $this->context->stash->get($name); |
70 } | 51 } |
71 } | 52 } |
72 | 53 |
73 sub RequireControl { | 54 sub RequireControl { |
74 my ($this, $control) = @_; | 55 my ($this, $control, $ctx) = @_; |
56 | |
57 $ctx ||= $this->context; | |
75 | 58 |
76 if (my $factory = $this->controls->{$control}) { | 59 if (my $factory = $this->controls->{$control}) { |
77 return $factory; | 60 return $factory; |
78 } else { | 61 } else { |
79 | |
80 my $path = $control; | 62 my $path = $control; |
81 | 63 |
82 if ( my $template = $this->loader->template($path) ) { | 64 if ( my $template = $this->loader->template($path) ) { |
83 | 65 |
84 # factory will create a clone of the stash | |
85 # $opts->{STASH} = $this->stash->clone(); | |
86 | |
87 my $ctx = Template::Context->new({%{$this->context}, STASH => $this->stash });#new Template::Context($opts); | |
88 | |
89 $factory = new IMPL::Web::View::TTFactory( | 66 $factory = new IMPL::Web::View::TTFactory( |
90 $template->class || TTControl, | 67 $template->class || TTControl, |
91 $template, | 68 $template, |
92 $ctx, | 69 $ctx, |
93 join( '/', splice( @{[split(/\//,$path)]}, 0, -1 ) ) | 70 join( '/', splice( @{[split(/\//,$path)]}, 0, -1 ) ) |
107 } | 84 } |
108 } | 85 } |
109 | 86 |
110 sub Render { | 87 sub Render { |
111 my ($this,$args) = @_; | 88 my ($this,$args) = @_; |
112 | 89 |
113 $args ||= {}; | 90 $args ||= {}; |
114 | 91 |
115 my $newArgs = hashMerge($this->creationArgs, $args); | 92 $this->context->localise(); |
116 | 93 |
117 if ($this->layout) { | 94 my $documentContext; |
118 my $text = eval { | 95 my %controls; |
119 #$this->context->localise(); | 96 my $require; |
97 $require = sub { | |
98 my $control = shift; | |
99 if (my $factory = $controls{$control}) { | |
100 return $factory; | |
101 } else { | |
102 my $path = $control; | |
103 | |
104 if ( my $template = $this->loader->template($path) ) { | |
105 | |
106 $factory = new IMPL::Web::View::TTFactory( | |
107 $template->class || TTControl, | |
108 $template, | |
109 $documentContext, | |
110 join( '/', splice( @{[split(/\//,$path)]}, 0, -1 ) ), | |
111 $require | |
112 ); | |
113 | |
114 if ($template->class) { | |
115 Loader->safe->Require($template->class); | |
116 } | |
117 | |
118 $controls{$control} = $factory; | |
119 | |
120 return $factory; | |
121 | |
122 } else { | |
123 die new IMPL::KeyNotFoundException($control); | |
124 } | |
125 } | |
126 }; | |
127 | |
128 $this->context->stash->set(require => $require); | |
129 $this->context->stash->set(document => $this); | |
130 $documentContext = Template::Context->new( { %{$this->context} } ); | |
131 | |
132 my $text = eval { | |
133 | |
134 if ($this->layout) { | |
120 my $tlayout = $this->loader->layout($this->layout); | 135 my $tlayout = $this->loader->layout($this->layout); |
121 if(my $init = $tlayout->blocks->{INIT}) { | 136 if(my $init = $tlayout->blocks->{INIT}) { |
122 $this->context->process( | 137 $this->context->process( |
123 $init, | 138 $init, |
124 hashMerge( | 139 hashMerge( |
125 $newArgs, | 140 $args, |
126 { | 141 { |
127 template => $this->template | 142 template => $this->template |
128 } | 143 } |
129 ) | 144 ) |
130 ); | 145 ); |
131 } | 146 } |
147 my $content = $this->next::method($args); | |
132 return $this->context->include( | 148 return $this->context->include( |
133 $tlayout, | 149 $tlayout, |
134 { | 150 { |
135 %{$newArgs}, | 151 %{$args}, |
136 content => $this->RenderContent($newArgs), | 152 content => $content, |
137 this => $this, | 153 this => $this, |
138 template => $this->template | 154 template => $this->template |
139 } | 155 } |
140 ); | 156 ); |
141 }; | 157 } else { |
142 my $e = $@; | 158 return $this->next::method($args); |
143 | 159 } |
144 #$this->context->delocalise(); | 160 }; |
145 | 161 |
146 if ($e) { | 162 $this->context->delocalise(); |
147 die $e; | 163 |
148 } else { | 164 my $e = $@; |
149 return $text; | 165 if ($e) { |
150 } | 166 die $e; |
151 | |
152 } else { | 167 } else { |
153 return $this->RenderContent($newArgs); | 168 return $text; |
154 } | 169 } |
155 } | 170 |
156 | 171 |
157 sub RenderContent { | |
158 my $this = shift; | |
159 return $this->SUPER::Render(@_); | |
160 } | 172 } |
161 | 173 |
162 1; | 174 1; |
163 | 175 |
164 __END__ | 176 __END__ |