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__