Современная, быстрая и удобная система управления сайтом

Шаблонизатор или форматированый PHP+HTML вывод в MaxSite CMS

Архив записейКомментарии: 0Просмотров: 3255

Шаблонизатор как правило применяется там, где требуется разделить работу программиста и верстальщика. Программист подготавливает данные для вывода, а верстальщик делает разметку в привычном HTML, без оглядки на программый код. Раньше, когда сайты были не такими интерактивными и «умными», подход неплохо работал. Со временем логика вывода усложнялась и это приводило к усложению самого шаблонизатора и добавлению новых команд. В итоге некоторые шаблонизаторы имеют настолько сложный и запутанный синтаксис, что проще выполнить логику на чистом PHP.

На текущий момент при создании PHP+HTML кода используется три основных подхода.

  • PHP - сам по себе неплохой шаблонизатор. Поэтому за базу берется HTML-код с PHP-вставками в виде echo или короткого синтаксиса.
  • Всё есть PHP. HTML выводится в виде строк череp echo. Как вариант - вывод через специальные php-функции.
  • Отдельный шаблонизор - подготавливаются данные, а сам вывод делается в отдельном tpl-файле.

Есть ещё подход, где нет никакой системы, а вариант вывода определяется по ситуации. Мы его рассматривать не будем, хотя он, насколько я понимаю, и преобладает в вебстроительстве.

Возьмем для рассмотрения простой пример вывода div-блока с текстом.

HTML с PHP-вкраплениями.

<div class="text"><?= $text ?></div>

Код читается достаточно легко и нет большой сложности поменять html-вёрстку. Если же внутри div-блока будет располагаться объёмный и более сложный php-код, то обычно делают так:

<div class="text"><?php 
 
... тут какой-то php-код ...
 
?></div>

Читабельность несколько ниже по той причине, что объем PHP превышает HTML. Логичней поступить наоборот - за основу взять PHP:

<?php
 
	echo '<div class="text">'; 
  
	... тут какой-то php-код ...
  
	echo '</div>';
 
?>

Читабельность не идеальная, но явно лучше предыдущего варианта. Хотя бы уже потому что код написан в одном php-стиле и не требуется искать html-вкрапления.

Если же php-код в блоке оказывается очень большим, то визуально можно «потерять» парные div'ы в коде. Думаю, что это вообще основная проблема написания кода в этом варианте. Лично у меня вообше привычка вначале делать код для div-блока, а php уже между ними вставлять. Но всё-равно вероятность ошибки возрастает многократно, особенно, если требуется вывести вложенные html-блоки.

В этом случае наступает очередь шаблонизатора. Шаблонизатор может быть основан на HTML или PHP-синтаксисе.

В HTML-варианте вначале потребуется подготовить данные и подставить их в специальный шаблон вывода. В prelatest 0.755 MaxSite CMS уже реализован такой шаблонизатор-парсер и я покажу как его использовать.

За основу берется stock-файл page-out.php. Он находится в default-шаблоне, поэтому нужно его скопировать в свой шаблон и подключить в custom/my_functions.php

require_once(getinfo('template_dir') . 'stock/page-out/page-out.php');

Или, если вы не хотите копировать файл, то подключить сразу из default-шаблона:

require_once(getinfo('templates_dir') . 'default/stock/page-out/page-out.php');

Теперь Page_out будет доступен в любой части сайта. Использование парсера будет основано на двух файлах. Первый - основной, например top.php


<?php
 
// новый объект Page_out
$p = new Page_out;
 
// данные для шаблона заносятся в массив
$data = array(
	'name_site' => getinfo('name_site');
	'description_site' => getinfo('description_site'),
);
 
// сам шаблон вывода в файле top.tpl
$p->parse_f('top.tpl', $data);

То есть здесь готовим массив $data с данными для шаблона вывода. Сам же html находится в файле top.tpl

<div class="top"><div class="wrap">
	<div class="name_site">{name_site}</div>
	<div class="description_site">{description_site}</div>
</div></div>

Здесь «переменные» заключены в фигурные скобки.

Данный шаблонизатор основан на стандартном парсере CodeIgniter и одним из его достоинств является высокое быстродействие. Правда и функциональность у него достаточно низкая.

Технически мы можем не разбивать вывод на два файла, а воспользоваться т.н. heredoc-синтаксисом PHP. В этом случае html-шаблон «загоняем» в отдельную строковую переменную.

<?php
 
// новый объект Page_out
$p = new Page_out;
 
// данные для шаблона заносятся в массив
$data = array(
	'name_site' => getinfo('name_site');
	'description_site' => getinfo('description_site'),
);
 
$tpl = <<<EOF
 
<div class="top"><div class="wrap">
	<div class="name_site">{name_site}</div>
	<div class="description_site">{description_site}</div>
</div></div>
 
EOF;
 
// вывод
$p->parse($tpl, $data);

Подход с парсером-шаблонизатором хорош там, где используется фиксированная html-структура, и более-менее стабильные «php-данные». На практике встречаются куда более сложные задачи, где нужно предусмотреть тесную связку HTML+PHP на уровне каждого подблока и различных html-тэгов.

Для решения таких задач больше подходит шаблонизатор в виде специальных php-функций, которые упрощают формирование html-кода.

В примере выше (3-й листинг) мы выводили html через echo и визуально html-код сильно «загрязняет» php. Чтобы от этого избавиться можно использовать чистый php, где формированием html будут заниматься отдельные функции.

О подобном подходе я уже рассказывал в статье Форматированный вывод записей в MaxSite CMS. В ней примеры основанные на выводе записей, но на самом деле возможности такие, что мы можем организовать вывод произвольных данных.

Все вышеприведенные примеры можно сделать так:

// новый объект Page_out
$p = new Page_out;
 
$p->div_start('top', 'wrap');
	$p->div(getinfo('name_site'), 'name_site');
	$p->div(getinfo('description_site'), 'description_site');
$p->div_end('top', 'wrap');

Здесь мы вообще не видим HTML-кода, хотя интуитивно он более чем понятен. Метод div_start открывет два div'а div.top и div.wrap. То есть в параметрах мы указываем css-классы. Метод div_end - закрывает div'ы.

Метод div выводит указанный текст (первый аргумент) в полном div-блоке с указанным во втором аргументе css-классом.

Теперь, если нужно поменять html-верстку, то меняем её через эти же php-функции. Если метод div «режет» глаз, то можно воспользоватья его аналогом - tag. Посмотрите на этот же вариант, только имя сайта и описание я загнал в H1 и H2.

// новый объект Page_out
$p = new Page_out;
 
$p->div_start('top', 'wrap');
	$p->tag(getinfo('name_site'), 'name_site', 'h1');
	$p->tag(getinfo('description_site'), 'description_site', 'h2');
$p->div_end('top', 'wrap');

Если стоит задача оформить блок в более сложном html-стиле, то можно воспользоваться методом block.

$p->block('<span style="color: red">', '</span>', $text);

В общем же случае, чтобы привести код к единому стилю с использованием $p без echo, для вывода произвольного html используется одноименный метод.

$p->html('<hr>');

Если требуется вывести div.clearfix, то можно сделать это так:

$p->clearfix();

Собственно, уже этих возможностей вполне достаточно, чтобы организовать практически любой HTML со сложной PHP-логикой. Кроме того, у функций Page_out есть дополнительный «интеллект». Например метод block выведет данные, только если они реально существуют. Если раньше приходилось делать так:

... откуда-то получили $text, которая может быть пустой ... 

if ($text)
{
	echo $text;
}

То теперь можно проще:

$p->block('<span>', '</span>', $text);

Span я поставил для примера. Метод block сам применит условие if ($text).

Ещё расскажу про метод link, который формирует произвольную html-ссылку. Например можно оформить ссылку в h1.name_site.

$p->tag( 
	$p->link('ссылка', 'Название'),
	'name_site',
	'h1'
);

Если делать «традиционно», то код мог бы быть таким:

<?php
 
$link = 'ссылка';
$name = 'Название';
 
echo '<h1 class="name_site"><a href="' . $link . '">' . $name . '</a></h1>';

Вполне очевидно, что с помощью Page_out код получается чище, компактней и более понятный. Единственный минус использования Page_out - потребуется потратить 10 минут, чтобы узнать за что отвечают его методы. Впрочем, относящихся только к форматированному html-выводу совсем ничего: html, tag, div, div_start, div_end, block и link.

ps Ещё один небольшой пример, основанный на «синтаксическом сахаре» PHP. Код хоть и небольшой, но интересный.

$p
	-> div_start('top', 'wrap')
	
		-> tag( 
				(
					!is_type('home') ? 
							$p->link(getinfo('siteurl'), getinfo('name_site')) 
						: 
							getinfo('name_site')
				),
				'name_site', 'h1')
	
		-> tag(getinfo('description_site'), 'description_site', 'h2')
	
	-> div_end('top', 'wrap')
;
Оставьте свой комментарий!

Комментарий будет опубликован после проверки

Вы можете войти под своим логином или зарегистрироваться на сайте.

(обязательно)