view Lib/IMPL/Web/TDocument.pm @ 59:0f3e369553bd

Rewritten property implementation (probably become slower but more flexible) Configuration infrastructure in progress (in the aspect of the lazy activation) Initial concept for the code generator
author wizard
date Tue, 09 Mar 2010 02:50:45 +0300
parents 16ada169ca75
children 915df8fcd16f
line wrap: on
line source

package IMPL::Web::TDocument;
use strict;
use warnings;

use base qw(IMPL::DOM::Node IMPL::Object::Disposable);
use Template::Context;
use Template::Provider;
use IMPL::Class::Property;
use File::Spec;

BEGIN {
    private property _Provider => prop_all;
    private property _Context => prop_all;
    public property Template => prop_get | owner_set;
}

our %CTOR = (
    'IMPL::DOM::Node' => 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
                },
                TRIM => 1,
                RECURSION => 1,
                LOAD_TEMPLATES => [$this->Provider]
            )
        )
    }
}

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 Dispose {
    my ($this) = @_;
    
    $this->Template(undef);
    $this->_Context(undef);
    $this->_Provider(undef);
    
    $this->SUPER::Dispose();
}

1;
__END__
=pod

=head1 SYNOPSIS

// create new document
my $doc = new IMPL::Web::TDocument;

// load template
$doc->loadFile('Templates/index.tt');

// render file
print $doc->Render();

=head1 DESCRIPTION

Документ, основанный на шаблоне Template::Toolkit. Позволяет загрузить шаблон,
и сформировать окончательный документ. Является наследником C<IMPL::DOM::Node>,
т.о. может быть использован для реализации DOM модели.

Внутри шаблона переменная C<document> ссылается на объект документа. По этой
причине образуется циклическая ссылка между объектами шаблона и документом, что
требует вызова метода C<Dispose> для освобождения документа.

=head1 METHODS

=level 4

=item C<new()>

Создает новый экземпляр документа

=item C<$doc->loadFile($fileName,$encoding)>

Загружает шаблон из файла C<$fileName>, используя кодировку C<$encoding>. Если
кодировка не указана, использует utf-8.

=item C<$doc->Render()>

Возвращает данные построенные на основе загруженного шаблона.

=item C<$doc->Dispose()>

Освобождает ресурсы и помечает объект как освобожденный.

=back

=cut