Вложенный шаблон должен задать title
чаще всего встречал такую проблему: в середине страницы выводится блок, этот блок задает Title, но реально Title уже выведен в head как быть?
решение (Спасибо AlexHamp)
отказываемся от идеи футера и хедера, и переходим к идее вложенных блоков. Остается проблема прегенерации вложенных блоков, она решается так: сначала мы генерируем содержимое вложенных блоков и в них задаем title, а потом выводим в основном шаблоне страницы.
шаблон страницы:
{assign var="pageTitle" value="Мой сайт"} {if !empty($innerTemplate)} {include file=$innerTemplate assign="innerContent"} {else} {assign var="innerContent" value="нет вложеного шаблона"} {/if} <HTML> <HEAD> <TITLE>{$pageTitle}</TITLE> </HEAD> <BODY> {$innerContent} </BODY> </HTML>
теперь внутренний шаблон:
{assign var="pageTitle" value="Мой сайт: Новости"} <h1>Новости</h1> ...далее вывод новостей...
Если мы работаем с шаблонизатором типа Квики, с общим пространством имен, то этого вполне достаточно, если же мы работаем со смарти, то нужно сделать в скрипте следующие:
$pageTitle=''; $smarty->assign_by_ref('pageTitle', $pageTitle);
Теперь изменения во внутреннем шаблоне будут происходить с $pageTitle из скрипта, вывод будет осуществляться ее же.
Таким образом мы смогли перенести задачу генерации заголовков во внутренний шаблон.
Генерация данных в шаблоне?
Догадываюсь, что вы подумали: «щас нам покажут спагети код, и мы закидаем этого парня помидорами!». Но спешу вас остановить! речь пойдет о решении задачи связывания отображения и модели с примемлемым разделением оных. Часто нужно повсеместно внедрить на сайте какой-либо блок, возможно, информер, возьму для примера блок, который выводится рядом с ником пользователя (всеми сообщениями, коментами и всеми всеми!)и оторбажает немножко информации о нем (допустим просто время регистрации, и юзерпик). Конечно, некоторые гуру скажут: используй генерацию этих данных прямо в модели! в каждом месте, где ты генерируешь эти логины пользователей, генерируй и сопутствующую информацию! Я с вами соглашусь, а даже дополню, если вы не можете этого сделать — значит архитектура проекта начинает дурно пахнуть, но нам часто нужно работать в не идеальных условиях, и иногда нужно решение, которое не будет заставлять нас рыться, например, в чужом коде, или в «черном ящике». Как писать расширение? первое что приходи в голову — это написать функцию и зарегистрировать ее в смарти потом вызывать, на пример так: {getUserRegDate userlogin=$login} если нам нужно много сопуствующей информации, то решение будет громоздким.
я предлагаю сделать так:
объявить класс, который будет осуществлять доступ к информации, в него включить всю логику по тому как информация извлекается.
class UserInfo(){ public $regDate; public $iniciateStatus=false; public iniciate($login){ if (читаем данные для логина){ берем данные и записываем их в наш контейнер, $this->regDate=... $this->iniciateStatus=true; }else $this->iniciateStatus=false; } }
и подключить его
$smarty->assign(new UserInfo(), $userInfo);
теперь как этим пользоваться в шаблоне?
{if $userInfo->iniciate($login)} зарегистрирован {$userInfo->regDate|date_format} {/if}
теперь следует все это инкапсулировать в подшаблон-блок и вызывать так:
{include file=userInfoBlock login=$login}
В итоге мы получаем достаточно изящное решение проблемы запроса данных в шаблоне из модели, минимально смешивания их.
Это нужно, например, когда мы в процессе работы самого шаблона узнаем, что нам нужны какие-то еще данные от модели. И, как показала моя практика, не всегда это говорит о плохой архитектуре системы.
UPD
Если не нравится без контрольный доступ, то можно его ограничить:
в iniciate делаем assign данных а в шаблоне пишем проще уже:
{if $userInfo->iniciate($login)}
зарегистрирован {$userRegDate|date_format}
{/if}
правда так вы можете получить конфликт имен.