Сегодня я хочу рассказать об очень интересном и полезном приеме в веб-программировании под названиемшаблонизация. Как я уже говорил в одной из предыдущих статей, любая HTML-страница состоит из каркаса и данных. Данные — это текстовая, графическая и прочая информация: пункты меню, заголовки, тексты информационных блоков и т. д. Каркас определяет вид и положение данных. Это могут быть скрытые таблицы, слои, стили и т. д.
Первые работы начинающего веб-программиста выглядят, как правило, примерно так:
echo '<div class="post_entry">';
echo '<h2>' . $article['title'] . '</h2>';
echo '<div class="date">' . $article['date'] . ' • Категория: <a href="/' . $article['category_alias'] . '/' . $article['article_alias'] . '">' . $article['category'] . '</a></div>';
echo $article['text'];
echo '</div>';
Код выше выводит оформленный блок статьи на сайте, данные, по всей видимости, берутся из базы данных (массив article), каркас страницы "жестко" вписан в код в виде строковых констант. Выглядит это очень некрасиво, не правда ли? Все из-за того, что каркас страницы и ее данные перемешаны в PHP-коде. Такой код очень неудобен как в плане чтения, так и в плане редактирования.
Суть шаблонизации заключается в том, чтобы отделить каркас страницы от программного кода. Каркас страницы помещается в отдельный текстовый файл (шаблон), в местах, где необходимо вывести данные размещаются специальные псевдопеременные. Сценарий загружает нужный шаблон, заменяет в нем псевдопеременные на соответствующие данные и выводит.
Шаблон для примера выше может выглядеть следующим образом:
<div class="post_entry">
<h2>{TITLE}</h2>
<div class="date">{CREATED} • Категория: <a href="{CATEGORY_LINK}">{CATEGORY}</a></div>
{CONTENT}
</div>
В данном случае псевдопеременные представляют из себя латинские слова, заключенные в фигурные скобки. В принципе, как будут выглядеть эти псевдопеременные решает программист, лично я всегда использую именно такой их вид.
"Натянуть" данные на шаблон очень просто, достаточно воспользоваться функцией str_replace или preg_replace для замены псевдопеременных в шаблоне. Но грамотнее для этой цели написать собственный простой шаблонизатор.
Например, предлагаю следующую реализацию примитивного шаблонизатора, который, по сути, является предельно упрощенным вариантом шаблонизатора, используемого в движке сайта MyFirstSite.ru:
<?php
class QTemplate
{
private $content = NULL;
private $res_content = NULL;
function QTemplate($tpl_dir, $tpl_name)
{
if ( ! file_exists($tpl_dir . $tpl_name . '.tpl') ) return;
$this->content = file_get_contents($tpl_dir . $tpl_name . '.tpl');
}
function assign_vars($vars)
{
$this->res_content = $this->content;
foreach( $vars as $blockname => $value )
{
$this->res_content = preg_replace('/{' . $blockname . '}/i', $value, $this->res_content);
}
}
function render()
{
if ( $this->res_content == '' ) $this->res_content = $this->content;
return $this->res_content;
}
}
?>
Шаблонизатор представляет из себя PHP-класс QTemplate. При создании экземпляра класса предается путь к папке с шаблонами и имя шаблона. Метод assign_vars "натягивает" данные на шаблон, то есть заменяет псевдопеременные в шаблоне на соответствующие им данные. Соответствия передаются в аргументе vars, который должен представлять из себя массив со следующей структурой:
array(
'ИМЯ_ПСЕВДОПЕРЕМЕННОЙ' => 'ДАННЫЕ',
'ИМЯ_ПСЕВДОПЕРЕМЕННОЙ' => 'ДАННЫЕ',
'ИМЯ_ПСЕВДОПЕРЕМЕННОЙ' => 'ДАННЫЕ'
);
При замене псевдопеременных результат сохраняется во внутреннюю переменную res_content, при этом переменная content содержит исходный текст шаблона. Это позволяет много раз использовать один экземпляр шаблонизатора для генерирования HTML-кода.
Метод render возвращает готовый HTML-код. Вызывается, соответственно, после замены псевдопеременных методомassign_vars.
А теперь давайте рассмотрим пример использования шаблонизатора:
<?php
$tpl_dir = 'templates/default/'; //--Путь к папке с шаблонами
require 'qtemplate.php'; //--Подключаем шаблонизатор
//--Тут должен находиться код получения статей из базы данных в массив $articles
$main_tpl = new QTemplate($tpl_dir, 'main'); //--Загружаем шаблон main
$article_tpl = new QTemplate($tpl_dir, 'article'); //--Загружаем шаблон article
$content = '';
//--"Пробегаемся" по всем статьям
foreach ( $articles as $article )
{
//--"Натягиваем" данные на шаблон
$article_tpl->assign_vars( array(
'TITLE' => $article['title'],
'CREATED' => $article['date'],
'CATEGORY_LINK' => '/' . $article['category_alias'] . '/' . $article['article_alias'],
'CATEGORY' => $article['category'],
'CONTENT' => $article['text']
) );
//--Генерируем HTML-код статьи
$content .= $article_tpl->render();
}
//--"Натягиваем" контент на главный шаблон
$main_tpl->assign_vars( array(
'TITLE' => 'Новости',
'CONTENT' => $content
) );
//--Генерируем HTML-код всей страницы и выводим его
echo $main_tpl->render();
?>
PHP-скрипт загружает два шаблона: main, содержащий структуру HTML-страницы (DOCTYPE, метатеги и т. д.) иarticle, содержащий структуру статьи. Код прокомментирован и, я надеюсь, предельно понятен. В цикле данные каждой статьи "натягиваются" на шаблон article, далее готовый HTML-код накопительно добавляется в переменнуюcontent. Полученный контент помещается в шаблон main. Это очень важная возможность — возможность заменять псевдопеременную одного шаблона результатом обработки другого шаблона (или нескольких шаблонов). В результате генерируется страница-категория со списком статей. Для более детального рассмотрения предлагаюскачать архив проекта, где вы найдете код шаблонизатора, тестовой страницы, а также необходимые шаблоны.
Преимущества, дающие использование шаблонов при генерировании кода HTML-страниц:
Во-первых, чистота кода. Программный код не содержит HTML-кода, поэтому легко читается. В то же время, шаблон содержит только HTML-код, в котором видно где и какие данные вставляются (для этого давайте осмысленные имена псевдопеременным).
Во-вторых, разделение программного и HTML-кода дает возможность независимой разработки движка и дизайна. Чтобы что-то изменить во внешнем виде готового сайта достаточно внести изменения в соответствующий шаблон, при этом не нужно владеть навыками программирования.
Сайт может иметь несколько дизайнов. Чтобы полностью изменить дизайн сайта достаточно просто изменить путь к папке с шаблонами.
Плюсов, конечно, намного больше, это лишь наиболее выраженные. В общем, я советую использовать шаблоны всегда и везде. Удачного кодинга!