Темплейт система с РНР
Нека първо се запознаем с това какво е темплейт система. Когато пишете дадено приложение, ползвайки езика РНР, вие имате общо взето 2 съставки – РНР код и HTML код. Нека разгледаме следния фрагмент:
<html>
<head>
<title>My Page</title>
</head>
<body>
<?
if ( !empty($_REQUEST['lang']))
echo $_REQUEST['lang'];
else
echo "Грешка!";
?>
</body>
</html>
Какво не е наред тук? Нищо – всичко е коректно написано. Ако това е файл test.php и вие напишете в браузера test.php?lang=bg ще се изведе bg, ако променливата lang не е дефинирана ще се изведе грешка. Като синтаксис този код е верен, но не е добре написан. Когато става въпрос за по-големи приложения едно такова изпълнение може да се окаже меко казано лошо. Представете си че имате приложение с 30 файла. Във всеки файл има както HTML, така и РНР код. Един прекрасен ден решавате да смените дизайна на това приложение. Ще трябва да редактирате 30 файла – не е лека работа. Ами ако някой друг е създал това приложение – кошмар!
Така се е родила идеята за разделение на РНР от HTML кода. Ако направите такова разделение, дизайнът ще може да се промени дори и от човек, не познаващ РНР(да кажем вашия уеб дизайнер) и това няма да има никакво отношение към функционалността. Как обаче става това разделение, при положение, че динамичната част е в средата на кода и не би могла да се премести?
Е, отговорът на този въпрос е : лесно. Обикновено в един уебсайт имате заглавна част(хедър) и финална част(футър), които рядко се променят. При това положение може да вземем HTML кода и да го запишем в отделен файл – template.html. Там където се намира динамична информация поставяме ключова дума, оградена в къдрави скоби. Така от горния код получихме следното в template.html:
<html>
<head>
<title>{title}</title>
</head>
<body>
{mainData}
</body>
</html>
Сега, нека преценим какво трябва да направи темплейт системата. Първо тя трябва да зареди темплейт файла, така че да може той да се редактира. Второ, трябва да замести ключовите думи в къдрави скоби с динамична информация и последно, трябва да подаде полученото на браузера. Въз основа на тези изисквания нека създадем шаблона на класа:
class Template
{
var $page;
function Template($template = "template.html")
{ }
function replaceTags($tags = array())
{ }
function parse($file)
{ }
function output()
{
echo $this->page;
}
}
Сега, нека видим кой метод какво трябва да прави. Конструкторът на класа трябва да зареди съдържанието на файла template.html в променливата $page. Винаги може да зададете път до този файл или друг файл викайки функцията с параметър. replaceTags е главният метод на класа – той ще замести ключовите думи с динамична информация. parse е нужен, за да дадем възможност дадена ключова дума да се замести със съдържанието на друг файл – за пример PHP такъв.
Интересното тук е че съдържанието на този файл трябва да се изпълни и на мястото на ключовата дума да се замести полученият резултат. output() e напълно ясен метод – извежда полученото съдържание в $page към браузера на потребителя.
Време е да разпишем и отделните методи. Започвам с конструктора:
function Template($template = "template.html")
{
if (file_exists($template))
$this->page = join("", file($template));
else
die("Файлът $template не е намерен.");
}
Тук използваме функцията join, която отваря файла и записва съдържанието му в променливата, като разбира се, преди това проверяваме дали съществува такъв файл. Следващата функция, която разписваме е parse() :
function parse($file)
{
if (file_exists($file))
{
ob_start();
include($file);
$buffer = ob_get_contents();
ob_end_clean();
return $buffer;
}
else
die("Файлът $file не е намерен.");
}
Удачно е ползването на буфериране в случая. ob_start() дава начало на буферирането, т.е. информацията подавана към браузера на клиента не се извежда, а се записва в променлива $buffer. Така включвайки файла с include кодът му се изпълнява, но резултатът не се изпраща към клиента, а се записва в променлива.
Последен и най-сложен е метода replaceTags() :
function replaceTags($tags = array())
{
if (sizeof($tags) > 0)
foreach ($tags as $tag => $data)
{
$data = (is_file($data) && file_exists($data)) ? $this->parse($data) : $data;
$this->page = eregi_replace("{" . $tag . "}", $data,
$this->page);
}
else
die("Не са подадени данни за замяна.");
}
Първо проверяваме дали големината на $tags е по-голяма от 0, т.е. дали са подадени данни за замяна и ако не са извеждаме грешка. След това обхождаме параметърът-масив с foreach. В променливата $data ще се намира информацията, която трябва да се замести на мястото на ключовата дума $tag. Тук е нужна двойна проверка – файлът едновременно трябва да съществува и да има валидно име. Това се налага, тъй като ако в $data няма име на файл, а код, file_exists може да върне истина, т.е. че файлът съществува. Така ако съществува такъв файл, в $data записваме резултата от изпълнението на кода във файла – това което ще ни върне метода parse, а ако е код $data не се променя. След тези проверки и преобразования с eregi_replace заменяме всяка ключова дума със съдържанието на конкретното $data.
За да стане по-ясно нека разгледаме пример:
<?
if ( !empty($_REQUEST['lang']))
$rslt = $_REQUEST['lang'];
else
$rslt = "Грешка!";
$prams = array(
'title' => 'My Page',
'mainData' => $rslt
);
$t = new Template();
$t->replaceTags($prams);
$t->output();
?>
Това всъщност е примерът с който започнахме. Екземплярът на новия ни клас $t всъщност е без параметър, но по подразбиране това е файлът template.html, който създадохме в началото на статията. Както виждате в примера няма нито един ред HTML код, а във файла template.html няма нито един ред РНР код. По всяко време може да смените съдържанието на един от двата файла, като това няма да се отрази на другия.
В заключение искам да добавя, че е добре да не ползвате никъде HTML тагове, където има и РНР код. Тъй като това е невъзможно винаги, може да направите компромис, като в началото на РНР кода запишете в променливи само HTML таговете, които ще ползвате. Така ако се наложи да сменяте дизайна и начина на визуализиране на информацията, ще промените само съдържанието на тези променливи, а няма да преглеждате целия РНР код и да търсите къде евентуално има нещо за смяна.
Източник: http://www.eadvise.info