comparison Lib/IMPL/Web/TT/Document.pm @ 77:9d24db321029

Refactoring Web::TT docs
author wizard
date Fri, 02 Apr 2010 20:18:46 +0400
parents Lib/IMPL/Web/TDocument.pm@b1652a158b2b
children 964587c5183c
comparison
equal deleted inserted replaced
76:b1652a158b2b 77:9d24db321029
1 package IMPL::Web::TT::Document;
2 use strict;
3 use warnings;
4
5 use base qw(IMPL::DOM::Document IMPL::Object::Disposable);
6 use Template::Context;
7 use Template::Provider;
8 use IMPL::Class::Property;
9 use File::Spec;
10 use Scalar::Util qw(blessed);
11
12 BEGIN {
13 private property _provider => prop_all;
14 private property _context => prop_all;
15 public property template => prop_get | owner_set;
16 public property presenter => prop_all, { validate => \&_validatePresenter };
17 }
18
19 our %CTOR = (
20 'IMPL::DOM::Document' => sub { nodeName => 'document' }
21 );
22
23 sub provider {
24 my ($this,%args) = @_;
25
26 if (my $provider = $this->_provider) {
27 return $provider;
28 } else {
29 return $this->_provider(new Template::Provider(
30 \%args
31 ));
32 }
33 }
34
35 sub context {
36 my ($this) = @_;
37
38 if (my $ctx = $this->_context) {
39 return $ctx;
40 } else {
41 return $this->_context (
42 new Template::Context(
43 VARIABLES => {
44 document => $this,
45 this => $this,
46 render => sub {
47 $this->_process(@_);
48 }
49 },
50 TRIM => 1,
51 RECURSION => 1,
52 LOAD_TEMPLATES => [$this->provider]
53 )
54 )
55 }
56 }
57
58 sub _validatePresenter {
59 my ($this,$value) = @_;
60
61 die new IMPL::InvalidArgumentException("A view object is required") unless blessed($value) and $value->isa('Template::View');
62 }
63
64 sub LoadFile {
65 my ($this,$filePath,$encoding) = @_;
66
67 die new IMPL::InvalidArgumentException("A filePath parameter is required") unless $filePath;
68
69 $encoding ||= 'utf8';
70
71 $this->_context(undef);
72 $this->_provider(undef);
73
74 my ($vol,$dir,$fileName) = File::Spec->splitpath($filePath);
75
76 my $inc = File::Spec->catpath($vol,$dir,'');
77
78 $this->provider(
79 ENCODING => $encoding,
80 INTERPOLATE => 1,
81 PRE_CHOMP => 1,
82 POST_CHOMP => 1,
83 INCLUDE_PATH => $inc
84 );
85
86 $this->template($this->context->template($fileName));
87 }
88
89 sub title {
90 $_[0]->template->title;
91 }
92
93 sub Render {
94 my ($this) = @_;
95
96 return $this->template->process($this->context);
97 }
98
99 # Формирует представление для произвольных объектов
100 sub _process {
101 my ($this,@items) = @_;
102
103 my @result;
104
105 foreach my $item (@items) {
106 if (blessed($item) and $item->isa('IMPL::Web::TT::Control')) {
107 push @result, $item->Render();
108 } elsif(blessed($item)) {
109 if ($this->presenter) {
110 push @result, $this->presenter->print($item);
111 } else {
112 push @result, $this->toString;
113 }
114 } else {
115 push @result, $item;
116 }
117 }
118
119 return join '',@items;
120 }
121
122 sub Dispose {
123 my ($this) = @_;
124
125 $this->template(undef);
126 $this->_context(undef);
127 $this->_provider(undef);
128
129 $this->SUPER::Dispose();
130 }
131
132 1;
133 __END__
134 =pod
135
136 =head1 NAME
137
138 C<IMPL::Web::TT::Document> - Документ, позволяющий строить представление по шаблону
139
140 =head1 SYNOPSIS
141
142 =begin code
143
144 // create new document
145 my $doc = new IMPL::Web::TT::Document;
146
147 // load template
148 $doc->loadFile('Templates/index.tt');
149
150 // render file
151 print $doc->Render();
152
153 =end code
154
155 =head1 DESCRIPTION
156
157 C<use base qw(IMPL::DOM::Document)>
158
159 Документ, основанный на шаблоне Template::Toolkit. Позволяет загрузить шаблон,
160 и сформировать окончательный документ. Является наследником C<IMPL::DOM::Node>,
161 т.о. может быть использован для реализации DOM модели.
162
163 Внутри шаблона переменная C<document> ссылается на объект документа. По этой
164 причине образуется циклическая ссылка между объектами шаблона и документом, что
165 требует вызова метода C<Dispose> для освобождения документа.
166
167 =head1 METHODS
168
169 =over
170
171 =item C<CTOR()>
172
173 Создает новый экземпляр документа, свойство C<nodeName> устанавливается в 'C<document>'
174
175 =item C<$doc->LoadFile($fileName,$encoding)>
176
177 Загружает шаблон из файла C<$fileName>, используя кодировку C<$encoding>. Если
178 кодировка не указана, использует utf-8.
179
180 =item C<$doc->Render()>
181
182 Возвращает данные построенные на основе загруженного шаблона.
183
184 =item C<$doc->Dispose()>
185
186 Освобождает ресурсы и помечает объект как освобожденный.
187
188 =back
189
190 =head1 DOM
191
192 =begin code html
193
194 [% table = document.Create('env','table') %]
195
196 [% FOEACH item in document.result %]
197 [% table.rows.Add( item.get('name','value') ) %]
198 [% END %]
199
200 [% form = document.Create('login','form') %]
201
202
203 [% form.template = 'LOGIN_FORM'%]
204
205 [% FOREACH item IN document.childNodes %]
206 [%render(item)%]
207 [% END %]
208
209 [% BLOCK LOGIN_FORM %]
210 <form method="POST" action='/login.pl'>
211 user: [% render(this.item('name')) %] password: [% render(this.item('password')) %] <input type="submit"/>
212 </form>
213 [% END %]
214
215 =end code html
216
217
218 =cut