Предисловие: Сам я использую простой шаблонизатор, основанный на регулярках, который просто ищет плейсхолдеры в шаблоне и заменяет их на хтмл блоки. И пока задачи являлись лёгкими, структура - простейшей, а кода было не так много, всё было шикарно. Контент блоков формировался внутри пхп фукнций. Однако с усложнением блоков, работа с формированием хтмл-кода внутри пхп стала затруднительной, т.к. мешала читабельности кода. Использовать свой шаблонизатор не представляется возможность, т.к. тот не поддерживает циклы, условия и прочие необходимые фишки. Выводить напрямую в браузер тоже нельзя - нужно получить скомплированных хтмл код блока, чтобы затем вставить его в основной шаблон. Задача: как совместить простоту пхп, выделить шаблоны в отдельные файлы и чтобы не было необходимости разучивать новый синтаксис шаблонизатора? Возможное решение: index.php PHP: <?php function templater($template_path, $vars){ extract($vars, EXTR_OVERWRITE); ob_start(); include($template_path); $content = ob_get_contents(); ob_end_clean(); return $content; } $vars = array(); $vars['array'] = array('abc', 'cde', 'efg', 'hij'); $content = templater('template.html', $vars); ?> <html> <head> <title>Simple templater</title> </head> <body> <?php echo $content; ?> </body> </html> template.html HTML: <table> <?php foreach($array as $value){ ?> <tr><td><?php echo $value; ?></td></tr> <?php } ?> </table> Конструктивные комментарии приветствуются.
а как вот такой вариант? http://www.php.ru/forum/viewtopic.php?p=211516#211516 сам пользуюсь таким типом PHP: <?php foreach ($this->vars as $var => $val){ $content = str_replace('{' . $var . '}', $val, $content); } пожалел, думаю в следующий раз что нибудь потяжелее взять, либо, попробовать то что по ссылке выше
Базовое решение любого нативного шаблонизатора. Основа основ Только я бы посоветовал синтаксис в шаблоне юзать альтернативный: PHP: <table> <?php foreach($array as $value):?> <tr> <td><?php echo $value;?></td> </tr> <?php endforeach;?> </table> Для любителей копнуть поглубже phpsavant.org
Padaboo просматривая тему, не добрался до 13 страницы мой велосипед по сути тот же самый, только кода меньше. это как?
есть какие-либо условия или противопоказания использования ob_ функций? влияет ли это на вывод, использование памяти или время генерации?
Gromo ускоряет работу скрипта память вроде как после того как скрипт отработает освобождается, мне кажется разницы нету в этом плане Apple надо спросить, он всегда такие вещи знает )
Padaboo А не делайте так, что бы куча подшаблонов была. Слишком мелкое деление тоже плохо и у вас будет дырка в производительности из-за слишком большого кол-ва I/O.
Psih Странный совет. Наоборот, надо структурировать свои шаблоны как можно детальнее (но не чрезмерно, конечно). Если в двух шаблонах повторяется одна и та же верстка - это основание для выноса повторяющегося фрагмента в отдельный шаблон. Как в программировании: копипаста=плохо. Ну а если вас от такой стратегии удерживают соображения типа "слишком много I/O" - значит ваш шаблонизатор плохой, возьмите нормальный. Который не требует большого количества "I/O" для работы.
Vladson угу, осознал, что это велосипед по ссылке от Padaboo. похоже, что к данному решению приходят многие из тех, кому пришлось столкнуться с неуклюжестью или навороченностью готовых шаблонизаторов. просто я не нашёл среди тем форума данной реализации (а точнее не хватило терпения дойти до 13 страницы темы Шаблонизатора), но всё же я дошёл до этого решения сам. расту потихоньку не я первый, не я последний изобретатель велосипеда
>function templater($template_path, $vars){ был тоже подобный велосипед. но еще там добавлена была поддержка функций-снипетов - т.е. шаблонов реализованых не в виде файла, а в виде функции имя которой состоит из названия шаблона и префикса (например block1_snippet). примерно такая: Код (Text): function block1_snippet($vars){ extract($vars, EXTR_OVERWRITE);?> <!-- template code --> <?} тоесть проверяется название шаблона - если такая функция есть - вызывается она если нет то подключается файл. таким образом и структурирование будет и накладные расходы на подключение файлов значительно снизятся. получается некий аналог подключаемых хелперов для вьювсов.
PHP: <? ob_start(); include('topmenu.php'); $topmenu = ob_get_contents(); ob_end_clean(); ob_start(); include('headmenu.php'); $headmenu = ob_get_contents(); ob_end_clean(); ////// requested page have to be the last one! ob_start(); include($file); $main .= ob_get_contents(); ob_end_clean(); PHP: <? //RENDER PAGE! echo <<<HEREDOC $hat <head> <title>$title</title> $head </head> <body> <div class="main"> <div id="header"> </div> <div id="topmenu"> $topmenu <div id="topmenu-preloader-hover"></div> <div id="topmenu-preloader-active"></div> <div id="topmenu-preloader-active-hover"></div> </div> <div id="headmenu" class="corner5"> $headmenu </div> <!--content --> <div id="content"> $main </div> </div>
Из Yii...CBaseController.php Код (Text): public function renderInternal($_viewFile_,$_data_=null,$_return_=false) { // we use special variable names here to avoid conflict when extracting data if(is_array($_data_)) extract($_data_,EXTR_PREFIX_SAME,'data'); else $data=$_data_; if($_return_) { ob_start(); ob_implicit_flush(false); require($_viewFile_); return ob_get_clean(); } else require($_viewFile_); }
Ужоснах ваши "шаблонизаторы", ребята, честное слово. Чем такими костылями, лучше уж действительно на нативном похапэ писать. Так же громоздко и неудобно верстать, как и у ваших вариантов, но хотя бы работает быстро и надежно. Без обид.
По порядку постов: 1. (Шаблонизатор от Gromo). Почему половина верстки в пхп-коде, половина в шаблоне? 2. (Шаблонизатор от Padaboo). Глючить же будет (нельзя подставлять значения циклом str_replace'ов), и неужели один strtr не будет быстрее и надежнее? 3. (Шаблонизатор от Psih). А экранизация данных где? Каждый раз будем писать htmlspecialchars() или будем писать шаблоны, уязвимые к XSS? Ко всем троим вопрос: как планируете вызывать вспомогательные шаблоны? Неужели ни разу не сталкивались? Как быстро будут работать такие вызовы, если вспомогательных шаблонов на странице штук 20?