вопрос по Blitz Template

Pablito

Новичок
вопрос по Blitz Template

наконец нашел хостера, котрый установил мне Blitz Template

протестировал, заработало! :)))

шаблон вида
{{ BEGIN root }}
{{ BEGIN news }}
{{ BEGIN row }}

{{ END }}
{{ END }}
{{ END }}

$T->iterate('/root/news/row');
echo $T -> parse();

выдает все как задумывалось

но как только я попытался вынести часть шаблона в отдельный файл:
{{ BEGIN root }}
{{ include('templates/news.tpl') }}
{{ END }}

index_news.tpl:
{{ BEGIN news }}
{{ BEGIN row }}

{{ END }}
{{ END }}

то что в include не отображается

если в подключаемом шаблоне отсавить только HTML без {{ }}
то он отбражается корректно. Подскажите плиз, что я делаю не так
 

fisher

накатила суть
include не может "продолжать" дерево корневого шаблона. более того, include не умеет пока делать контексты, вообще. то есть никаких BEGIN END в подключаемом шаблоне быть не должно. это ограничение возможно будет исправлено в будущем, но я затрудняюсь сказать когда. причина очень простая - include и контексты это два независимых идеологически метода разделения шаблона на куски. хотя реквестов объединить много - и я этим займусь.
 

Pablito

Новичок
Автор оригинала: fisher
include не может "продолжать" дерево корневого шаблона. более того, include не умеет пока делать контексты, вообще. то есть никаких BEGIN END в подключаемом шаблоне быть не должно.
т.е. весь шаблон с разветвленной сиситемой контекстов, в случае сложного шаблона, должен находться в одном файле??? Получается, я не могу повторно использовать вложенные контексты в других шаблонах :(

помоему, в случае сложного шаблона, был бы намного удобнее разбросать его части по разным файлам

а в каких случаях идеологически правильно использовать include?

спасибо!
 

Develar

Новичок
Использовать blitz без всякой своей обертки для задач шаблонизации представления можно только для ну очень простых задач. Ну а реализовывать в самом blitz подобное сомнительно по выигрышу в скорости. Захочет ли автор blitz превращать его в подобие каркаса, а не просто основы для построения своего решения и нужно ли кому нибудь будет это универсальное решение...

http://raa.livejournal.com/94771.html?thread=401971#t401971
http://raa.livejournal.com/98391.html#cutid1
 

fisher

накатила суть
>>т.е. весь шаблон с разветвленной сиситемой контекстов, в случае
>>сложного шаблона, должен находться в одном файле???
нет.
Вы можете внутри методов шаблона сделать что-то вроде $subTemplate = new Blitz(blabla) и работать с подшаблоном всё так же с контекстами. Но это уже будет без include. Чтобы такой подход не тормозил - можете сделать что-то вроде фабрики синглтонов.
 

Develar

Новичок
fisher
Видите ли вы необходимость реализации подобного на уровне blitz (опуская вопрос кто будет реализовывать :))? То есть чтобы на нативном уровне поддерживалось макетирование, подключение просто шаблона?
 

Pablito

Новичок
Автор оригинала: fisher
Чтобы такой подход не тормозил - можете сделать что-то вроде фабрики синглтонов.
боюсь, что это что-то сложное, хотя сам с этим не сталкивался

первое что подкупило в Blitz, скорость и простота.
теперь оказывается, что все не так просто :(
 

fisher

накатила суть
абисняю. допустим нужно сделать "инклюд" шаблона i.tpl, внутри которого есть контексты. вы делаете такую штуку. в корневом шаблоне делаете вызов метода - {{ test }}. в классе контроллера метод тест выглядит так, всё пишу не проверяя, считайте что это псевдокод:

function test () {
$sT = new Blitz('i,tpl'); // sT - subTemplste для краткости
$sT->iterate(..); //.. - всё что вам там нужно проитерировать, засетить и так далее
return $sT->parse();
}

в 99% случаев вам этого будет достаточно. но представим что вы пишете ОООЧЕНЬ нагруженный сайт. представим себе что test вызывается в цикле. каждый раз когда будет вызван конструктор будет делаться куча операций, которая вам не нужна. делаете класс, который реализует интерфейс к синглотону

function test () {
$sT = &TemplateRepository::getTemplate('i.tpl');
$sT->clean(); // если там осталось что-то - очистим
$sT->iterate(..); //.. - всё что вам там нужно проитерировать, засетить и так далее
return $sT->parse();
}

а внутри TemplateRepository просто делаете статический хэш название шаблона - объект шаблона, если объекта нет - вызывается конструктор, если есть - возвращаете объект.

НО - метод clean эспериментальный, лучше использовать пока fetch
в i.tpl пихаете всякие блоки а потом фетчите их оттуда:

function test () {
$sT = &TemplateRepository::getTemplate('i.tpl');
// всё что вам там нужно проитерировать, засетить и так далее
return $sT->fetch(...);
}

-~{}~ 28.03.07 19:31:

>>Видите ли вы необходимость реализации подобного на уровне blitz
я затрудняюсь сказать. давайте формализуем требования. итак, у меня есть некоторый шаблон, который инклюдится. внешний шаблон имеет дерево итераций. внутренний шаблон должен исполниться так, как будто бы мы его проитерировали - то есть взяв данные по итерациям из внешнего шаблона. если внутри одного инклюда есть другой инклюд - все должно прозрачно "унаследоваться" из внешних шаблонов. при этом никаких независимых параметров и итераций в подключаемые шаблоны ставить нельзя (разве что сделать свои глобальные переменные, правда тут есть идеологический конфликт но фиг бы ним) - короче, все итерации наследуются от родителя. я правильно понимаю?
 

Develar

Новичок
>> короче, все итерации наследуются от родителя. я правильно понимаю
нет. Внешний шаблон знает лишь имя подключаемого шаблона. Подключаемый независим. Точнее, мы подключаем не шаблон, а совокупность контроллер + шаблон = вид (эту совокупность в целом я называю видом - view)

<div id="content">
{view('h1')}
{content}
</div>

ведь наша цель - "весь шаблон с разветвленной сиситемой контекстов, в случае сложного шаблона, должен находться в одном файле" - разбить один огромный представляющий итоговую страницу на "где-то есть разумная середина, основанная на вероятности использования кусков кода из большого файла, в который вошли все случаи жизни". Нас не колышет как работает вид h1 - пусть выдаст heading для страницы и все.

В методе view мы инстанцируем Blitz - шаблон и подключаем контроллер для этого шаблона.


То есть, по сути, тот метод include что реализован в blitz, надо просто удалить за ненадобностью - "это два независимых идеологически метода разделения шаблона на куски", и если мы применяем его, нас надо лечить и тыкать носом в документацию. Нет внешнего и внутреннего, шаблон самодостаточен и един, метод возращает единственное значение - результат своего исполнения, include строго говоря языковая конструкция, которая даром не нужна на фоне контекстов.
А новички этого не понимают. Не до конца понимая что такое blitz они include воспринимают как средство разбиения видов (контроллер + шаблон) на разные файлы для повторного использования, а на самом деле это атавизм от 0.3.
 

fisher

накатила суть
то, что Вы пишете - понятно. но имхо не надо совсем уж навязывать какие-то идеологические моменты, не хочу удалять инклюд, народ пользуется и ему удобно. иначе получится что всё надо строить на методах - да, в этом и стостоит гибкость blitz, и наследование и всё такое - но это далеко не всегда удобно. а народ-то просит include расширить контекстами - у меня и до этого были такие реквесты. вы Вы говорите - да ну этот инклюд, удалить его и дело с концом :)
 

Develar

Новичок
В данном случае товарищ хочет разделения для повторного использования. Или... у него получится один большой контроллер и куча шаблонов. Он добьется разделения большого шаблона на маленькие. А контроллер то у него останется! Когда ему потребуется вон тот кусочек с row использовать в ином месте, в совершенно ином контроллере, кусок php кода управляющий этим row надо будет тоже выделять... То есть здесь include не катит, правильно?

Ну а для чего он тогда нужен? Пример из документации - "Метод list_news возвращает результат исполнения шаблона news_list_item.tpl" вполне ложится на то что я написал.


>> всё надо строить на методах - да, в этом и стостоит гибкость blitz
нет. Этот метод - метод обертки над blitz, а сам шаблон в отдельном файле, равно как и контроллер к нему.

>> удалить его и дело с концом
Не, почему с концом, а как же с разбивкой? Или мы просто не понимаем друг друга и на разных полюсах - вы имеете возможность задать для всей страницы один шаблон и это решает ваши задачи, а у меня вся эта муть с макетированием и раскруткой стека.
 

fisher

накатила суть
вероятно, Вы уже научились использовать blitz так, как я даже сам не предполагал. мне надо осмыслить вышесказанное :) впрочем, это уже палюбому оффтоп.
 

Pablito

Новичок
Автор оригинала: fisher
абисняю. допустим нужно сделать "инклюд" шаблона i.tpl, внутри которого есть контексты. вы делаете такую штуку. в корневом шаблоне делаете вызов метода - {{ test }}. в классе контроллера метод тест выглядит так, всё пишу не проверяя, считайте что это псевдокод:

function test () {
$sT = new Blitz('i,tpl'); // sT - subTemplste для краткости
$sT->iterate(..); //.. - всё что вам там нужно проитерировать, засетить и так далее
return $sT->parse();
}
Спасибо все получилось, работает, буду дальше экспериментировать! :)
 

syfisher

TDD infected!!
Develar

Если я правильно понял, вы создаете свой класс, наследник от Blitz, скажем MyView, где есть метод view($template_class, $template_name).

Внутри этого метода создается новый экзепляр $template_class (наследник от MyView), куда ему передается путь до шаблона.

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

Я правильно понял идею??
 

Develar

Новичок
Да.

PHP:
/**
	 * Подключение контроллера, для всех определяемых/принимаемых переменных используем префикс _, для предотвращения коллизии имен при extract() - извлечении параметров подключенного контроллера
	 * @param string $name
	 * @param bool $_cache = false Кешировать сверстанный вид
	 * @param int $_tree_level = null Уровень поиска
	 * @param bool $_from_framework Из каркаса
	 * @return string Результат работы
	 */
	public function view($_name, $_cache = false, $_tree_level = null, $_from_framework = false)
	{
		if ($_cache)
		{
			$_cache_name = $_name . $_tree_level;
			if (isset(self::$cache[$_cache_name]))
			{
				return self::$cache[$_cache_name];
			}
		}

		if (isset($this->controllerVars[$_name]))
		{
			extract(array_shift($this->controllerVars[$_name]), EXTR_REFS);
		}

		$Template = new Template_view_cms($_name);
		if ($_from_framework)
		{
			include(Kernel::$View->getPathFromFramework($_name . View_cms::CONTROLLER_FILE_EXTENSION));
		}
		else
		{
			include(Kernel::$View->getPath($_name . View_cms::CONTROLLER_FILE_EXTENSION, $_tree_level));
		}
		$content = $Template->parse();

		if ($_cache)
		{
			self::$cache[$_cache_name] = $content;
		}

		return $content;
	}
-~{}~ 29.03.07 13:21:

помимо view есть еще layout
PHP:
public function layout($name)
{
	$this->layout = $name;
}
который потом, при разборе макетируемого шаблона, и парсится.
PHP:
public function parse()
	{
		$content = parent::parse();
		if (isset($this->layout))
		{
			self::$content = $content;
			$Template = new Template_view_cms($this->layout . View_cms::LAYOUT_FILE_EXTENSION);
			include(Kernel::$View->getPath($this->layout . View_cms::LAYOUT_FILE_EXTENSION . View_cms::CONTROLLER_FILE_EXTENSION));
			$content = $Template->parse();
		}
		return $content;
	}
 

syfisher

TDD infected!!
Develar
Угу, ясно. Все же смотрю создается экземпляр класса Template_view_cms, а не его дочерний. По сути повторного использования логики по получению данных нет, так?
 

Develar

Новичок
>> повторного использования логики по получению данных нет
Логика по получению данных, точнее вызов API - (понятное дело, контроллер не сам добывает данные) который эти данные дает контроллеру, то есть логика отображения, находится в коде контроллера, а не какого то класса, скажем Template_view_cms. Мы запросили вид h1 - view('h1')

Template_view_cms инстанцировал шаблон (сам класс спросит у View_cms как h1 преобразовать в путь к файлу, чтобы дать родительскому конструктору blitz)
$Template = new Template_view_cms($_name);

подключили к нему контроллер
include(Kernel::$View->getPath($_name . View_cms::CONTROLLER_FILE_EXTENSION, $_tree_level));

и вернул в место вызова строку.
 
Сверху