Шаблонизаторы
Шаблонизатор - это механизм (техника), позволяющая отделить html от php, использовать один и тот же html многократно. Или, то же самое, но кому больше нравятся умные слова, шаблонизатор позволяет отделить логику представления от бизнес-логики (контроллера и тем более модели).
PHP - сам себе шаблонизатор
В php можно легко обходиться без шаблонизатора. Слышал, это токе программирование называют «линейным» (хотя на самом деле «линейное программирование» - это математический термин). Пусть есть какой-то php-код. Тогда в любом месте кода мы можем выполнить:
include "other.php"; // указываем какой-то существующий файл
тогда результат выполнения этого кода будет выведен на экран. Это уже позволяет вынести html код из php-файлов. Внутри файла удобно использовать php-переменные:
<html><head><title>php - сам себе шаблонизатор</title></head>
<body><?=$content?></body></html>
Вместо $content будет подставлено содержимое. И если сайт очень и очень простой (функции выполняются «линейно»), то этого способа в качестве «шаблонизатора» уже будет достаточно. Но что делать, если содержимое html-шаблона должно подставляться в другой, ещё больший шаблон? Такое нужно постоянно, а include не умеет возвращать своё содержимое в переменную, тогда я придумал такой способ, который выдам сразу:
function tpl($path, $vars=array()){
if ($vars) extract($vars);
ob_start();
include $path;
$code = ob_get_contents();
ob_end_clean();
return $code;
}
$html = tpl("templates/index.html", array("content"=>$this->content));
Надеюсь, вы смогли заценить фишку. Кроме того, что я считваю шаблон внутрь переменной, я ещё сразу и подставляю значения плейсхолдеров. При этом, при подстановке не засоряется пространство имён и не пахабятся шаблоны. Т.е. внутри шаблона нам не надо писать <? echo $this->content; ?>, а так же и остаётся <?=$content?>, как и было раньше.
Честно говоря, я понятия не имею, что плохого есть (а может и нет ничего) в использовании буфферов, так что можете использовать эту функцию на свой страх и риск.
Аналогичная функция, без использования буфера:
function htmlTpl($path, $vars=array()){
$res = file_get_contents($path);
$lambda = create_function('$x', 'return "<?=\${$x}?>";');
return str_replace( array_map($lambda, array_keys($vars)), array_values($vars), $res );
}
Минус(?) у этой функции будет такой, что внутри шаблона не может находиться php. В качестве плюса, то что шаблон htmlTpl подойдёт для функции tpl.
Smarty
Smarty - это движок для работы с шаблонами. Но и раньше я тоже пользовался шаблонами. Выглядело это примерно так:
$myTpl = file_get_contents( 'templates/necessary.tpl'); // может, для кого-то и эта фукнция будет открытием
в шаблоне писал html-код, в котором встречались плэйсхолдеры, типа:
<div><# BLOCK_CONTENT #></div>
а потом, через str_replace соответствующие блоки я заменял на соответствующий сгенерированный контент. Думаю, техника понятна.
Впрочем, Smarty так же не сатнет открытием. В-общем, я сам толком пока не ощутил его прелестей. Но когда уходишь с одной техники на другую, то, как минимум, она должна уметь всё то же самое, что могла старая.
Итак, Smarty. Для работы должы быть созданы каталоги и smarty должен быть инициализирован соответствующим образом. Об этом можно прочитать где-нибудь в интернете. Я успешно подключил шаблон и отобразил его на экран. В шаблоне я могу заменить плэйсхолдеры на соответствующие значения.
Но: в старой технике я мог сколько угодно раз вызывать функцию file_get_contents и вкладывать друг в друга сложные структуры, не боясь получить сложный html. До меня не сразу дошло, как реализовать то же самое средствами Smarty, потому сейчас и пишу.
Если в старой технике я заменял внутреннюю часть
<div><# INNER_HTML #></div>
на код, прочитанный в другом шаблоне, который я читал через file_get_contents, то в Smarty вместо <# INNER_HTML #> я ставлю
{include file=$filename}
а саму переменную $filename определяю в дочерней функции.
Подробнее: например, для вывода страницы я создаю функцию main. Функция main вызывает и отображает главный шаблон. В зависимости от параметра, вызывается одна из функций модуля example.php. Так вот уже внутри этой функции определяется smarty-переменная $filename. По-моему, клёво, - так же просто реализуется многократая вложенность, как и при работе с обычными файлами шаблонов.
Но есть приятные мелочи. Шаблон Smarty сначала преобразуется в php, поэтому в нём могут быть активные сущности. Если раньше для раскраски таблицы построчно (класс x/класс y), мне надо было следить за этим в php, то сейчас я делаю это средством шаблона.
По-сути, я только начал использовать Smarty, но в нём уже видны всякие вкусности. Типа защиты опубликованных email. Ещё я видел, что там можно делать всплывающие окна, но пока не разбирал. Немного посмотрел отзывы по Smarty, говорят, что работает очень быстро, что не может не радовать. А кроме, Smarty кэширует данные. В-общем, мне Smarty уже нравится.