Mercurial > pub > Impl
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/IMPL/Web/TT/Document.pm Fri Apr 02 20:18:46 2010 +0400 @@ -0,0 +1,218 @@ +package IMPL::Web::TT::Document; +use strict; +use warnings; + +use base qw(IMPL::DOM::Document IMPL::Object::Disposable); +use Template::Context; +use Template::Provider; +use IMPL::Class::Property; +use File::Spec; +use Scalar::Util qw(blessed); + +BEGIN { + private property _provider => prop_all; + private property _context => prop_all; + public property template => prop_get | owner_set; + public property presenter => prop_all, { validate => \&_validatePresenter }; +} + +our %CTOR = ( + 'IMPL::DOM::Document' => sub { nodeName => 'document' } +); + +sub provider { + my ($this,%args) = @_; + + if (my $provider = $this->_provider) { + return $provider; + } else { + return $this->_provider(new Template::Provider( + \%args + )); + } +} + +sub context { + my ($this) = @_; + + if (my $ctx = $this->_context) { + return $ctx; + } else { + return $this->_context ( + new Template::Context( + VARIABLES => { + document => $this, + this => $this, + render => sub { + $this->_process(@_); + } + }, + TRIM => 1, + RECURSION => 1, + LOAD_TEMPLATES => [$this->provider] + ) + ) + } +} + +sub _validatePresenter { + my ($this,$value) = @_; + + die new IMPL::InvalidArgumentException("A view object is required") unless blessed($value) and $value->isa('Template::View'); +} + +sub LoadFile { + my ($this,$filePath,$encoding) = @_; + + die new IMPL::InvalidArgumentException("A filePath parameter is required") unless $filePath; + + $encoding ||= 'utf8'; + + $this->_context(undef); + $this->_provider(undef); + + my ($vol,$dir,$fileName) = File::Spec->splitpath($filePath); + + my $inc = File::Spec->catpath($vol,$dir,''); + + $this->provider( + ENCODING => $encoding, + INTERPOLATE => 1, + PRE_CHOMP => 1, + POST_CHOMP => 1, + INCLUDE_PATH => $inc + ); + + $this->template($this->context->template($fileName)); +} + +sub title { + $_[0]->template->title; +} + +sub Render { + my ($this) = @_; + + return $this->template->process($this->context); +} + +# Формирует представление для произвольных объектов +sub _process { + my ($this,@items) = @_; + + my @result; + + foreach my $item (@items) { + if (blessed($item) and $item->isa('IMPL::Web::TT::Control')) { + push @result, $item->Render(); + } elsif(blessed($item)) { + if ($this->presenter) { + push @result, $this->presenter->print($item); + } else { + push @result, $this->toString; + } + } else { + push @result, $item; + } + } + + return join '',@items; +} + +sub Dispose { + my ($this) = @_; + + $this->template(undef); + $this->_context(undef); + $this->_provider(undef); + + $this->SUPER::Dispose(); +} + +1; +__END__ +=pod + +=head1 NAME + +C<IMPL::Web::TT::Document> - Документ, позволяющий строить представление по шаблону + +=head1 SYNOPSIS + +=begin code + +// create new document +my $doc = new IMPL::Web::TT::Document; + +// load template +$doc->loadFile('Templates/index.tt'); + +// render file +print $doc->Render(); + +=end code + +=head1 DESCRIPTION + +C<use base qw(IMPL::DOM::Document)> + +Документ, основанный на шаблоне Template::Toolkit. Позволяет загрузить шаблон, +и сформировать окончательный документ. Является наследником C<IMPL::DOM::Node>, +т.о. может быть использован для реализации DOM модели. + +Внутри шаблона переменная C<document> ссылается на объект документа. По этой +причине образуется циклическая ссылка между объектами шаблона и документом, что +требует вызова метода C<Dispose> для освобождения документа. + +=head1 METHODS + +=over + +=item C<CTOR()> + +Создает новый экземпляр документа, свойство C<nodeName> устанавливается в 'C<document>' + +=item C<$doc->LoadFile($fileName,$encoding)> + +Загружает шаблон из файла C<$fileName>, используя кодировку C<$encoding>. Если +кодировка не указана, использует utf-8. + +=item C<$doc->Render()> + +Возвращает данные построенные на основе загруженного шаблона. + +=item C<$doc->Dispose()> + +Освобождает ресурсы и помечает объект как освобожденный. + +=back + +=head1 DOM + +=begin code html + +[% table = document.Create('env','table') %] + +[% FOEACH item in document.result %] + [% table.rows.Add( item.get('name','value') ) %] +[% END %] + +[% form = document.Create('login','form') %] + + +[% form.template = 'LOGIN_FORM'%] + +[% FOREACH item IN document.childNodes %] + [%render(item)%] +[% END %] + +[% BLOCK LOGIN_FORM %] +<form method="POST" action='/login.pl'> + user: [% render(this.item('name')) %] password: [% render(this.item('password')) %] <input type="submit"/> +</form> +[% END %] + +=end code html + + +=cut