Здравствуйте.
Лет 5 назад мы работали над одним сайтом, и использовали какой-то open source framework, я уже не помню какой именно. Так вот, он мне нравился, хоть и был слегка замороченный, я в нём ковырялся, и наткнулся на функцию рендеринга конечной веб-страницы. Она мне показалась довольно милой, я её максимально сократил, оставив практически всю функциональность, и облёк в форму класса.
Это мощный рендерер занимает всего строчек 40, очень удобный и быстрый. Я им пользуюсь уже 5 лет и ни разу не пожалел об этом. Всегда используйте этот рендерер, даже в демо-проектах, нечего сваливать PHP-код и HTML-разметку в кучу.
HTML::render
Вот его полный код:
/////////////////////////////////////////////// //////////// PARSE HTML FUNCTIONS //////////// ///////////////////////////////////////////// // use STATIC rendering - используем статический рендеринг class HTML { // deafult folder for html pages (templates) static private $folder = 'html'; // change default folder for html templates static public function changeFolder($folder) { self::$folder = $folder; } static public function render($template, $data = array()) { $content = file_get_contents(self::$folder."/{$template}.html"); $content = self::design_render_text($content, $data); return $content; } static private function design_render_text($content, $data = array()) { $content = self::design_parse_function($content, $data); $content = self::design_parse($content, $data); return $content; } static private function design_parse_function($content, $data = array()) { preg_match_all('/\<\<(.*?)\>\>/is', $content, $res); if (@$res[1]) foreach ($res[1] as $el) { $middle = self::design_parse($el, $data); $middle = '$result = '.$middle.';'; eval($middle); $content = str_ireplace('<<'.$el.'>>', $result, $content); } return $content; } static private function design_parse($content, $data) { preg_match_all('/\%\%(.*?)\%\%/si', $content, $res); if (@$res[1]) foreach ($res[1] as $el) $content = str_ireplace('%%'.$el.'%%', $data[$el], $content); return $content; } }
Достаточно включить этот класс в свой проект и вы можете легко и просто рендерить странички. Как он работает?
Синтаксис:
HTML::render( template [ , array ] );
template – имя шаблона веб-странички. Используется без расширения. По умолчанию шаблоны расположены в папке html (её можно поменять вызовом HTML::changeFolder(‘tpl’), чтобы использовать папку tpl вместо html, к примеру). Шаблоны в папке должны иметь расширение html. Можно использовать любое кол-во вложенных подпапок, естественно.
array – ассоциативный массив, все ключи которого сопоставляются с вхождениями %%…%% в шаблоне и с заменой их значениями. Можно не использовать, если на страничке нет таких элементов.
Например:
$html = array('TITLE' => 'Добро пожаловать!'); $page = HTML::render('index', $html); die($page);
и браузер выдаст нам отрендеренную страничку. Если в шаблоне html/index.html будет присутствовать вхождение %%TITLE%%, оно будет заменено в данном случае на Добро пожаловать!
Странички состоят из простейших шаблонов – HTML-код + вставка переменных и любых PHP-конструкций.
%%VAR%% – используем подстановку для VAR. VAR – ключ ассоциативного массива, который идёт вторым параметром в вызове HTML::render() (см. выше).
<<PHP_code>> – выполнение PHP кода и отображение на страничке его результата. Можно использовать любые доступные при вызове рендерера функции, и супер-глобальные переменные, например <<$_SERVER[‘HTTP_HOST’]>>
Также может быть использовано для логического ветвления в шаблоне, когда рендерер отобразит особую часть из шаблона при выполнении определённого условия. Пример смотрите ниже.
Пример
Но всё слова-слова, но без примера не всё так понятно, верно.
Вот наш шаблон:
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="utf-8"> <title>Ошибка соединения с БД</title> </head> <body> <h1 style="color: blue">Ошибка соединения с БД.<br> Повторите попытку через минуту!</h1> <<('%%DEBUG_MODE%%')?' <div class="info"> %%DB_ERR%% </div>':''>> </body> </html>
Использование:
$dsn = 'mysql:dbname=testdb;host=127.0.0.1'; $user = 'dbuser'; $password = 'dbpass'; try { $dbh = new PDO($dsn, $user, $password); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { die(HTML::render('err/db', array('DEBUG_MODE' => $_DEBUGGING, 'DB_ERR' => $e->getMessage()))) }
В этом примере делается попытка соединиться с БД, и если она не удалась, выводится страница из шаблона, находящегося в файле html/err/db.html. %%DB_ERR%% заменяется значением $e->getMessage(), и оно будет включено в страничку, только если %%DEBUG_MODE%%, который преобразуется в true/false согласно переменной $_DEBUGGING, будет равен true.
Этот класс можно применять не только для рендеринга цельных (оконечных) страничек, но и для обработки любых HTML-кусков. Да, возможно не хватает выполнения циклических блоков, как в Smarty, например, но для 40-ка строчек PHP-кода, я полагаю, и это совсем неплохо. Любую нужную функциональность уже добавляем по мере необходимости и по прихоти клиентов.
Удачи на даче! И крепкого чая, крепкой любви и крепкого имбиря.