view Lib/IMPL/Web/View/TTDocument.pm @ 187:927653d01f4f

TTControl::AUTOLOAD now accesses nodeProperties Added TTControl::renderBlock property to access RENDER block of the template
author sergey
date Tue, 03 Apr 2012 07:54:25 +0400
parents 6c0fee769b0c
children 029c9610528c
line wrap: on
line source

package IMPL::Web::View::TTDocument;
use strict;

use IMPL::lang qw(:declare :constants);
use IMPL::DOM::Property qw(_dom);
use IMPL::Web::View::TTFactory();
use IMPL::Web::View::TTControl();


use parent qw(
	IMPL::DOM::Document
	IMPL::Web::View::TTControl
);

BEGIN {
	public _dom property layout => PROP_ALL;
	public property opts => PROP_GET | PROP_OWNERSET;
	public property loader => PROP_GET | PROP_OWNERSET;
	public property controls => PROP_GET | PROP_OWNERSET;
}

sub CTOR {
	my ($this,$template,$refOpts,%args) = @_;
	
	$this->controls({});
	$this->loader($args{loader}) if $args{loader};
	
	$this->layout( $template->layout ) unless $this->layout;
	
	$this->opts($refOpts);
}

our %CTOR = (
	'IMPL::Web::View::TTControl' => sub {
		'document',
		$_[0], # template
		new Template::Context($_[1])  # context
	},
	'IMPL::DOM::Document' => sub {
		nodeName => 'document'
	}
);

sub require {
	my ($this, $control) = @_;
	
	if (my $factory = $this->controls->{$control}) {
		return $factory;
	} else {
		
		my $path = $control;
		if ( my $template = $this->loader->template($path) ) {
			my $opts = { %{$this->opts} };
			$opts->{STASH} = $this->context->stash->clone();
			
			my $ctx = new Template::Context($opts);
			
			$factory = new IMPL::Web::View::TTFactory(
				typeof IMPL::Web::View::TTControl,
				$template,
				$ctx,
				$opts
			);
			
			my @parts = split(/\/+/,$control);
			
			$this->controls->{$control} = $factory;
			$this->context->stash->set([map { $_, 0 } @parts], $factory);
						
			return $factory;
		} else {
			die new IMPL::KeyNotFoundException($control);
		}
		
	}
}

sub renderBlock {
	$_[0]->template;	
}

sub Render {
	my ($this,$args) = @_;
	
	my $output = $this->IMPL::Web::TTControl::Render( { document => $this } );
	
	if ($this->layout) {
		$output = $this->context->include($this->layout, { content => $output } );
	}
	
	return $output;
}


1;

__END__

=pod

=head1 NAME

C<IMPL::Web::View::TTDocument> - документ для построения HTML страницы на основе шаблонов TT.

=head1 SYNOPSIS

=begin code

use IMPL::Web::View::TTDocument();

my $doc = new IMPL::Wbe::View::TTDocument($template,$ttOptions);

return $doc->Render();

=end code

Однако, более предпочтительный способ использовать C<IMPL::Web::View::TTLoader>.

=head1 DESCRIPTION

Документ для представления данных. Документы представляют собой иерархически организованные данные,
элементами данного документа являются данные для отображения, такие как

=over

=item * Объекты из БД

=item * Навигационные цепочки

=item * Меню и т.п. 

=back

Скприт шаблона формирует структуру документа, затем сформированная структура форматируется в готовый документ.
Процесс преобразования объектной модели в готовый документ может быть выполнена как вручную, так и при помощи
вспомогательного шаблона - обертки. Если у шаблона документа указан C<wrapper> в метаданных, то он будет
использован как шаблон для форматирования объектной модели, вывод самого шаблона будет проигнорирован. Если
обертка не задана, то результатом будет вывод самого скрипта шаблона.

Каждый документ имеет свое собственное пространство имен, которое может быть вложенным в некоторое внешнее,
указанное при создании документа.
=head2 Порядок обработки документа

=over

=item 1 Создается документ при помощи метода C<TTLoader::document()>

=item 1 При создании документа (в конструкторе), происходит выполнение блока C<CTOR>

=item 1 При вызове метода C<TTDocument::Render()> устанавливаются переменные C<this>, C<document>
и шаблон обрабатывается при помощи метода C<process()> контекста документа.

=back

=head2 Загрузка элемента управления

=over

=item 1 C<document.require('my/org/input')>

=item 1 Загружает шаблон C<my/org/input.tt>

=item 1 Создает фабрику элементов управления с собственным контекстом, вложенным в контекст документа.

=item 1 Выполняет шаблон в пространстве имен фабрики 

=item 1 Регистритует фабрику в контексте документа по пути C<my.org.input>

=back

=head2 Создание элемента управления

=over

=item 1 C<< my.org.input.new('login') >>

=item 1 Если это первый элемент управления, то выполняетя статический конструктор в контексте фабрики

=item 1 Создается новый дочерний контекст к контексту фабрики

=item 1 Создается экземпляр элемента управления

=item 1 Выполняется блок конструктора в контексте элемента управления, параметр C<this> имеет значение
нового экземпляра элемента управления  

=back

=head1 MEMBERS

=over

=item C<CTOR($template, %options)>

Создает экземпляр документа с указанным шаблоном и параметрами, параметры 

=back

=cut