Применение темплейтов, при создании сайтов на PHP.
Технология темплейтов (или по-русски "шаблоны") сейчас используется очень широко. Например в всяческих CMS (системах управления сайтом), форумах и прочих интернет-приложениях.
Смысл технологии довольно прост. Он заключается в разделении дизайна и логики работы (php - кода). Получаем красивый структуированный код. И отделенный от кода дизайн странички. В "дизайне" определяются пользовательские определения, заполняемые в "коде". На выходе получаем динамически сгенерированные странички.
Существут большое количество темплейтеров (систем управления темплейтами).FastTemplate
/* Был очень популярен. Правда о нем написали: If you need a PHP Template Engine then please, use SMARTY. FastTemplate was good when I first wrote it (not great though, since there are at least two places in the code where I’m wasting huge numbers of cycles) but Smarty is a lot… smarter. More importantly it’s updated fairly often. */Cached Fast Template
PowerTemplate
PHemplate
XTemplate
И самое главное супер пупер мощный и развитой :)
Smarty
/* Очень мощная система управления шаблонами с развитым внутренним языком. Имеет возможность компилировать шаблоны в php-скрипт, который впоследствии будет выполняться много быстрее. Сейчас содержит много очень интересных дополнений: Smarty: The PHP compiling template engine. Smarty Forums: The discussion forums for Smarty. SmartyValidate: A form validation class for the Smarty template language. SmartyFormtool: A javascript form tool class for the Smarty template language. SmartyPaginate: A pagination class for the Smarty template language. SmartyMenu: A dropdown menu class for the Smarty template language. TinyMVC An extremely compact MVC development framework for PHP. SafeSQL: A PHP class for automating the task of making SQL queries safe for use. Snoopy: A PHP class for simulating a web browser. Date_Calc: A PHP class for manipulating and calculating calendar dates. pmatch: A PHP grep-like command line utility with enhancements ContentFeeder: A PHP content feed assembling library (create RSS 2.0 feeds.) XMLParser: Parse XML documents into PHP arrays. Also comes with RSSParser, an extension of XMLParser that creates simple RSS-specific array structures from RSS feeds. GoogleMapAPI A fully functional Google Map API for PHP. Easy Reflections Helped make some improvements to alpha blending and caching. Online CSS Compressor Efficiently compress CSS. str2img: View strings on an image. Basecamp PHP API: a PHP library wrapper for the Basecamp REST API. */
Их много и все они чем-то хороши.
Но иногда полезно написать свой, благо ничего сложного в этом нет.
Самый простой темплейтер получает на вход массив элементов ключ => значение.
Затем делает перебор полученного массива заменяя все найденные ключи на их значения.
И в конечном этапе производит вывод текста темплейта с замененными ключами.
Мне был необходим следующий функционал:
- Замена ключей на значения.
- Замена массива массивов ключей, для организации вывода однотипных блоков информации (например сообщений на форуме, гостевой книге и т.д.).
- А также такая особенность как выполнение в теле темплейта встроенных в них php скриптов.
Таким способом можно сделать темплейтер другого типа, в котором нет необходимости в замене ключей на значения, а для входного массива используется php-функция explode, обеспечивающая преобразования массива в php-переменные. Они уже автоматически заменятся на свои значения. Т.е. переменные вписываются в тело шаблона в виде <? =$var ?>. Сам шаблон выводится при помощи require "template.htm"
Реализовывать будем с применением ООП.
Организуем класс TEMPL.
Конструктор TEMPL() принимает имя файла темплейта и инициализирует переменные.
В качестве начала и конца ключа выберем <$ и $> соответственно. Они записываются в $BC и $EC. При необходимости можно перенастроить.
Флаг Prepared - флаг подготовки к выводу на экран. Не особо нужная вещь :) Но как-то прижилась.
Два ассоциативных массива $AA и $AAA для одномерного и многомерного массива значений.
В классе 8 методов:
Load | Для загрузки файла используется метод Load() он загружает файл в переменную $T. |
SetValue | установка значения массива, в аргументе массив ключ => значение |
SetValueA | установка значения многомерного массива, в аргументе многомерный массив |
AddVal | добавляет пару ключ значение в массив $AA, в аргументах ключ и значение |
AddValA | добавляет одномерный массив в $AAA, в аргументе массив |
Prepare | подготовка темплейта к выводу на экран, используется $AA |
PrepareA | подготовка темплейта к выводу на экран, используется $AAA |
Out | производит подготовку к выводу, если еще не подготовленно и собственно вывод (т.е. не вывод, а возврат строки). В Out также предусмотренна возможность исполнения внутришаблонных php-скриптов. Делается при помощи eval. Да не безопасно, но работает. И для моего применения не особо важно.eval выполняется внутри блока ob_start(); ... ob_end_clean();. Все что выводится внутри этого блока попадает в переменную $out = ob_get_contents(); которую мы и возвращаем. |
ob_start();
eval("?>".$this->O."<?");
$out = ob_get_contents();
ob_end_clean();
Вот собственно код: Скачать
Код класса TEMPL
<?php
/*
TEMPLATE class
evg_n@mail.ru
http://uggway.ru
*/
class TEMPL{
var $fname; //template file
var $AA; //associative array
var $AAA; //array of associative array
var $T;
var $O;
var $Prepared;
var $BC;
var $EC;
function TEMPL($fname)
{
$this->fname = $fname;
$this->BC="<$";
$this->EC="$>";
$this->AA=array();
$this->AAA=array();
$this->Load();
$this->Prepared=FALSE;
}
function Load()
{
if(file_exists($this->fname)){
$this->T=file($this->fname);
}
}
function SetValue($vals)//array of values
{
$this->AA = array();
foreach($vals as $vk =>$vv){
$this->AA[$this->BC.$vk.$this->EC]=$vv;
}
$this->Prepared=FALSE;
}
function SetValueA($vala)
{
$this->AA = array();
$this->AAA = $vala;
}
function AddVal($var,$val)
{
$this->AA[$this->BC.$var.$this->EC] = $val;
}
function AddValA($val)
{
$this->AAA[] = $val;
}
function Prepare()
{
if($this->T){
$v = join("", $this->T);
if(count($this->AA) > 0)
$this->O = strtr($v, $this->AA);
else $this->O = $v;
$this->Prepared = TRUE;
}
}
function PrepareA()
{
if($this->T){
$v = join("",$this->T);
$ret = "";
if(count($this->AAA)>0){
foreach($this->AAA as $i){
$this->SetValue($i);
if(count($this->AA)>0)
$ret .= strtr($v,$this->AA);
else $ret .= $v;
}
}
else
$ret = $v;
$this->O = $ret;
$this->Prepared = TRUE;
}
}
function Out()
{
if($this->Prepared == FALSE)
{
if(count($this->AAA) > 0) $this->PrepareA();
else
$this->Prepare();
}
if($this->Prepared == FALSE) return "";
ob_start();
eval("?>".$this->O."<?");
$out = ob_get_contents();
ob_end_clean();
return $out;
}
}
?>
Рассмотрим применение данного шаблонизатора для генерации меню:
index.tmpl Текст indexf.php
<html>
<head>
<title><$title$></title>
<style>
#wrap {width:500px; border:1px solid gray;}
#menu {border:1px solid gray;}
#bodym {height:400px;}
#footer {border:1px solid gray;height:20px;}
.menuelt { border:1px solid black;padding:10px;float:left;}
.clearb {clear:both;}
</style>
</head>
<body>
<center>
<div id='wrap'>
<div id='menu'>
<?
//load menu
$menu = new TEMPL("menu.tmpl");
$menuarray = <$menu$>; //<-- this replacing
foreach($menuarray as $i) {
$menu->AddValA($i);
}
echo $menu->Out();
?>
<div class='clearb'></div>
</div>
<div id='bodym'> <$bodymessage$> </div>
<div id='footer'> <$footer$> </div>
</center>
</body>
</html>
menu.tmpl Текст menu.tmpl
<div class='menuelt'><a href='<$url$>'><$name$></a></div>
indexf.php Текст indexf.php
<?php
include_once "templ.php";
$ma = "array(
array('name'=>'menu1', 'url' => 'url.html'),
array('name'=>'menu2', 'url' => 'url2.html'),
array('name'=>'menu3', 'url' => 'url3.html')
)
";
$index_t = new TEMPL("index.tmpl");
$index_t->AddVal("menu", $ma);
$index_t->AddVal("title", "Title");
$index_t->AddVal("bodymessage", "Body message :)");
$index_t->AddVal("footer", "evg 27.02.2011");
echo $index_t->Out();
?>
После всех манипуляций у нас получится вот такая вот страничка: Открыть в новом окне Полученная страничка
Скачать всё
Скачать templ.php