Темплейт система с РНР

Нека първо се запознаем с това какво е темплейт система. Когато пишете дадено приложение, ползвайки езика РНР, вие имате общо взето 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