Создание собственного шаблонизатора

Создание собственного шаблонизатора

От автора: Разрабатывая веб-приложения, очень хорошей практикой является отделение логики скрипта от его дизайна. В таком случае очень удобно выполнять всевозможные правки по дизайну, не затрагивая логики. И наоборот, изменяя логическую часть приложения – внешний вид остается нетронутым. Но при создании приложений по такой структуре возникает вопрос, как передать переменные в дизайнерскую часть? Поэтому в данном уроке мы с Вами научимся создавать собственный несложный шаблонизатор, при помощи которого можно передавать переменные из логической части скрипта в дизайнерскую.

скачать исходникискачать урок

Введение

Первым делом определимся с понятием шаблона. Шаблоны — это отдельные файлы которые занимаются выводом данных скрипта на экран. То есть они занимаются только выводом информации, при этом шаблон только получает данные для вывода и ни как их не формирует. Из этого следует, что шаблоны содержат практически чистый HTML с минимальными вставками PHP кода, который используется для отображения данных переменных, формирования условий (if — else) и описания циклов (foreach) для обхода по массивам. Шаблоны бывают самых различных видов, а вместе с тем и шаблонизаторы. Но различают два основных вида шаблонов по способу передачи данных. Первый предусматривает передачу значений обычных переменных, которые в последствии, будут выведены на экран обычным образом, к примеру, используя функцию echo:

echo $var;

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

{$var}

В данном уроке мы будем рассматривать первый тип шаблонов. Так как этот тип наиболее удачен и функционален. Смотрите, язык PHP по своей структуре уже является очень хорошим шаблонизатором, так как очень легко встраивается в разметку HTML. Если же мы используем в шаблонах специальные метки ({$var}) , то для вывода данных, нам потребуется писать специальную функцию, которая отыщет все метки и заменит их, на соответствующие данные. Но что получается, PHP и так очень хорошо встраивается в PHP, а мы пишем дополнительные функции для вывода переменных на экран. Хотя можем ограничиться обычной функцией echo:

<?php echo $var;?>

Создание шаблонов

Для сегодняшнего урока мы будем использовать следующий сайт:

Вот код файла index.php который, выводит главную страницу на экран:

<?php
	header("Content-Type:text/html;charset=UTF8");
	//подключаем файл конфигурации
	include 'config.php';
	include 'functions.php';
	$result = get_statti();
	$cat = get_cat();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
	<link rel="stylesheet" href="css/style.css"/>
	<link rel="stylesheet" href="css/jquery-ui.css"/>
	<link rel="stylesheet" href="css/jquery-ui.structure.css"/>
	<link rel="stylesheet" href="css/jquery-ui.theme.css"/>
	<script src="js/jquery-1.11.1.min.js"></script>
	<script src="js/jquery-ui.js"></script>
	<script src="js/script.js"></script>
</head>
<body>

<div class="wrap">
	<div class='header'></div>

	<div class="menu">
			<form>
			<fieldset>
				<label for="menu">Главное меню</label>
				<select name="menu" id="menu">
				<? foreach($cat as $item) {
				printf("<option value='%s'>%s</option>",$item['id_category'],$item['name_category']);
				}
				?>
				</select>
			</fieldset>
		</form>
	</div>

	<div class='content'>
		<form action="view_text.php" method="POST">
			<input type="text" name="search" value="">
			<input type="submit" value="OK">
		</form>
		<div class="main_text">
			<? foreach($result as $row) {
			printf("<table class='table' width='780' border='0' cellspacing='0' cellpadding='0'>
			<tr>
			<td class='td_top'>
			<h5><a title='%s' href='view_text.php?id=%s'>%s</a></h5>
			Дата добавления: %s
			</td>
			</tr>
			<tr>
			<td> 
			<img title='%s' align='left' src='%s'>
			<p>%s</p>
			</td>
			</tr>
			<tr>
			<td>
			<p>Просмотров: %s </p>
			</td>
			</tr>
			</table> ",$row['title'], $row['id'], $row['title'], $row['date'], $row['title'], $row['img_src'], $row['discription'], $row['view']); } ?>
		</div>
		
	</div> 
	
	<div class='footer'>
		<? echo "<p style='text-align:right;font_size:5px; color:white;margin:10px;'>".$site_name."</p>";?>
	</div>

</div>

</body>
</html>

Как Вы видите в этом файле логика скрипта тесно связана с его дизайном. Поэтому давайте это исправим и создадим шаблон для главной страницы тестового сайта. Вот код шаблона:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
	<link rel="stylesheet" href="css/style.css"/>
	<script src="js/script.js"></script>
</head>
<body>
 <div class="wrap">
  <div class='header'> </div>
   <div class="menu">
    <form>
     <fieldset>
      <label for="menu">Главное меню</label>
       <select name="menu" id="menu">
        <?php foreach($cat as $item) :? >
         <option value='<?php echo $item['id_category']; ?>'>
         	<?php echo $item['name_category']; ?>
         </option>
          <?php endforeach;?> ?> 
      </select>
       </fieldset>
        </form>
         </div>
          <div class='content'>
           <form action="view_text.php" method="POST">
            <input type="text" name="search" value=""> 
            <input type="submit" value="OK">
             </form>
              <div class="main_text">
               <? foreach($result as $row) :? >
                <table class='table' width='780' border='0' cellspacing='0' cellpadding='0'> <tr>
                 <td class='td_top'> <h5><a title='<?php echo $row['title']?>' href='view_text.php?id=<?php echo $row['id']?>'><?php echo $row['title']?></a></h5>
                  Дата добавления: <?php echo $row['date']?>
                   </td>
                    </tr>
                     <tr>
                      <td>
                       <img title='<?php echo $row['title'] ?>' align='left' src='<?php echo $row['img_src']?>'>
                       <p><?php echo $row['discription']?></p>
                   </td>
                    </tr> 
                    <tr>
                     <td>
                      <p>Просмотров: <?php echo $row['view'];?> </p>
                       </td> 
                   </tr>
                    </table> 
                <?php endforeach;?> ?>
                 </div> </div>
                  <div class='footer'> <? echo "<p style='text-align:right;font_size:5px; color:white;margin:10px;'>".$site_name."</p>";?> </div>
                   </div>
</body></html>

Как Вы видите в данный файл я вынес только дизайн главной страницы сайта. Для вывода данных сайта используются обычные переменные PHP. Цикл foreach описан при помощи альтернативного синтаксиса. Обратите внимание, что код данного файла достаточно прост и состоит практически из разметки HTML, что упрощает редактирование дизайна. Данный файл я сохраняю в папку templates под именем index.tpl.php.

В свою очередь файл index.php, файл который выводит главную страницу на экран, теперь содержит только логическую часть:

<?php
header("Content-Type:text/html;charset=UTF8");
//подключаем файл конфигурации
include 'config.php';
include 'functions.php';
$result = get_statti();
$cat = get_cat();
?>

Теперь, когда у нас есть шаблон, необходимо передать ему данные и вывести на экран.

Создание шаблонизатора

В качестве шаблонизатора в нашем случае будет выступать функция:

function render($tmp,$vars = array()) {
	if(file_exists('templates/'.$tmp.'.tpl.php')) {
		ob_start();
		extract($vars);
		require 'templates/'.$tmp.'.tpl.php';
		return ob_get_clean();
	}
}

Данная функция, принимает два параметра: $tmp – имя шаблона (только имя – без расширения и строки tpl), $vars = array() – необязательный параметр – массив переменных которые необходимо передать в шаблон.

В данной функции проверяем, существует ли в папке templates нужный шаблон. И если он существует — то первым делом включаем буферизированный вывод, используя функцию ob_start(). При этом весь вывод на экран будет попадать в буфер обмена. Далее нужно создать переменные, которые будут переданы в шаблон. Эти переменные мы передаем в виде массива $vars. Это обычный ассоциативный массив, ключи которого содержат имена переменных, а значения, соответственно – значения этих переменных. Используя функцию extract($vars), мы создаем в памяти переменные из массива $vars. Имена которых, соответствуют ключам данного массива.

После этого необходимо только лишь подключить нужный файл шаблона, что мы собственно и делаем. При этом на экран ничего выведено не будет, так как включен буферизированный вывод. Значит необходимо очистить буфер обмена. Для этого используем функцию ob_get_clean(), она очищает буфер обмена и возвращает его содержимое, которое мы вернем как результат работы функции в целом.

На этом шаблонизатор завешен.

Вывод шаблона на экран

Теперь давайте посмотрим как использовать данный шаблонизатор. В файле index.php, который выводит главную страницу на экран добавим следующий код:

echo render('index',array('cat'=>$cat,'result'=>$result));

То есть выводит на экран данные, которые вернет функция render. При этом передаем ей имя шаблона ‘index’ и массив переменных, которые нужно передать в шаблон. Массив составляем следующим образом. Ключ – содержит имя передаваемой переменной (переменной которая используется в шаблоне), а значение – соответственно значение этой переменной. В моем случае нужно передать две переменные: $cat и $result, что собственно я и делаю.

Если проверить работу шаблона в браузере – то мы увидим, что все отлично работает.

Вложенные шаблоны

Любой хороший шаблонизатор, должен поддерживать вложенность шаблонов – наш шаблонизатор не исключение и по своим возможностям полностью поддерживает вложенные шаблоны. Давайте посмотрим, как работать с вложенными шаблонами. Итак, давайте разделим шаблон index.tpl.php на три отдельных шаблона. Шаблон вывода списка категорий, который назовем menu.tpl.php:

<form> 
	<fieldset>
	 <label for="menu">Главное меню</label>
	  <select name="menu" id="menu">
	   <?php foreach($cat as $item) :? >
	    <option value='<?php echo $item['id_category']; ?>'>
	    	<?php echo $item['name_category']; ?>
	    </option>
	     <?php endforeach;?> ?>
	      </select> </fieldset>
</form>

Шаблон вывода списка статей – файл content.tpl.php:

<form action="view_text.php" method="POST">
 <input type="text" name="search" value="">
  <input type="submit" value="OK">
   </form>
    <div class="main_text">
     <? foreach($result as $row) :? >
      <table class='table' width='780' border='0' cellspacing='0' cellpadding='0'>
       <tr>
        <td class='td_top'> <h5><a title='<?php echo $row['title']?>' href='view_text.php?id=<?php echo $row['id']?>'><?php echo $row['title']?></a></h5>
         Дата добавления: <?php echo $row['date']?>
          </td>
           </tr> 
           <tr>
            <td>
             <img title='<?php echo $row['title'] ?>' align='left' src='<?php echo $row['img_src']?>'>
             <p><?php echo $row['discription']?></p>
         </td>
          </tr>
           <tr>
            <td>
             <p>Просмотров: <?php echo $row['view'];?> </p> 
         </td> 
     </tr> 
 </table>
  <?php endforeach;?> ?> 
</div>

И главный файл шаблона, в котором должны быть включены вложенные шаблоны. Вложенные шаблоны должны быть выведены как значения переменных $menu и $content. То есть значения этих переменных должны включать в себя файлы, которые мы описали выше.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
	<link rel="stylesheet" href="css/style.css"/>
	<script src="js/script.js"></script>
</head>
<body>
 <div class="wrap">
  <div class='header'> </div>
   <div class="menu"> <?php echo $menu;?> </div>
    <div class='content'>
     <?php echo $content;?> </div>
      <div class='footer'> <? echo "<p style='text-align:right;font_size:5px; color:white;margin:10px;'>".$site_name."</p>";?> </div>
       </div>
</body></html>

Теперь в файле index.php, используя шаблонизатор выведем данные на экран следующим образом. Формируем значение переменной $menu, при этом вызываем функцию шаблонизатора передаем название шаблона menu и передаем массив категорий.

$menu = render('menu',array('cat'=>$cat));

Далее аналогичным образом формируем переменную $content:

$content = render('content',array('result'=>$result));

И наконец, выводим общий шаблон на экран, передавая функции render() его имя и значения переменных, которые были сформированы выше:

echo render('main', array('menu'=>$menu,'content'=>$content));

Опять же если проверить работу скрипта в браузере то мы увидим, что все отлично работает. Вот таким образом мы с Вами создали собственный шаблонизатор, который очень простой по своему коду, но очень функционален.

На этом данный урок я буду завершать. Всего Вам доброго и удачного кодирования!!!

Хотите изучить шаблонизатор Twig?

Прямо сейчас посмотрите 4-х часовой курс по шаблонизатору Twig!

Смотреть курс

Метки: ,

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (2)

  1. Дмитрий

    Спасибо большое за такой интересный и полезный урок. Было бы ещё интересно посмотреть Ваш урок в котором был бы представлен второй вид замены меток.

  2. Дмитрий Беглов

    Добрый день, Виктор.
    Спасибо большое за этот интересный урок. Понял для себя, что такое шаблонизаторы и зачем они нужны.
    Согласен, что очень правильно отделять логику скрипта от внешнего вида. Можно при желании и пользователям предоставить возможность изменять внешний вид контента. Очень удобно.

    P.S. В видео-уроке (и в исходниках тоже, в файлах шаблонов) заметил, что остались лишние закрывающие конструкции «?>» (когда удаляли функцию printf), а также у оператора echo (при выводе нужных переменных в шаблон) в некоторых местах не хватает точки с запятой.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree