Как сделать собственный шаблонизатор
Рано или поздно у каждого программиста возникает желание написать свой Smarty
.
Называются разные аргументы - более быстрый, гибкий, удобный и так далее.
После того, как я начал пользоваться CakePHP ко мне неожиданно пришло просветление - это было как раз то, что я хотел. Но иногда возникают задачи, когда действительно нужны простейшие шаблонизаторы и CakePHP становится слишком тяжёлой артиллерией.
И тут все сразу смотрят в сторону eval. Первое, что приходит в голову - написать eval(file_get_contents('template.htm')). И, конечно же, это не работает. Потом читается документация и пишется что-то вроде eval('echo("'.file_get_contents('template.htm').'");');. Но и это тоже не работает.
А потом наконец включается мозг и приходит понимание, что нужно учится у умных людей. Например, тех, кто написал CakePHP ![]()
Они устанавливают нужные переменные, отключают вывод на экран, инклюдят шаблон, берут вывод из буфера и обрабатывают. Обычно даже это сильно сложно, можно переменные не устанавливать.
Например, чтобы
превратилось в
можно написать такую простенькую функцию.
-
<?php
-
-
include($template);
-
-
foreach ($params as $key=>$value) {
-
}
-
-
return $html;
-
}
-
-
$html = parsePage($params);
-
-
?>
Преимущество в том, что работает очень быстро, кода мало, верстальщикам можно объяснить суть шаблонов за пару минут.
Если вы знаете, как сделать шаблонизатор ещё проще - расскажите.
Однако, велосипед
Вот, здесь, например.. Датировано 2003 годом
http://spectator.ru/technology/php/easy_templates
Да, ту статью помню. Кажется, пару лет назад её читал, когда делал свой фреймворк.
Но это не совсем то. Была задача сделать именно с параметрами {=$title}, а не < ?=$title?> (нужна совместимость с шаблонами определённой CMS).
В указанной статье нет упоминания об ob_*, а это важно, так как даёт определённую свободу, если надо делать более сложные шаблоны с вложениями и другой чепухой.
Я сам в большинстве случаев за шаблоны на PHP, но ведь даже в Хабре решили от них отказаться. Что-то знают...
А вот как Смарти прикрутили не подходит? http://bakery.cakephp.org/articles/view/how-to-use-smarty-with-cake-smartyview
Идея в том, чтобы создать простейший шаблонизатор, который будет настолько лёгким, насколько можно, потому что непонятно, где он будет работать.
Единственным требованием должно быть только наличие PHP.
А у CakePHP есть неплохие требования по памяти, да ещё и базу данных ему подавай
При этом бонусное требование - понятность для верстальщиков, которые не знают, что такое PHP; совместимость с какой-то странной CMS в которой они привыкли работать.
Поэтому Smarty тоже не подходит.
Smarty будет работать быстрее с его предкомпиляцией
Так, как на этом сайте принято замечать даже мелкие неточности, то код метода нужно написать так:
function parsePage($params=array(), $template='main.tpl') {
ob_start(); // echo to buffer, not screen
include($template);
$html = ob_get_clean(); // get buffer contents
foreach ($params as $key=>$value) {
$html = str_replace('{=$'.$key.'}', $value, $html);
}
return $html;
}
ничего себе мелочь - забыл return сделать
исправил, спасибо
Дан шаблон main.tpl:
{=$var1}
{=$var2}
'hack {=$var2} motherfuck',
'var2' => 'ha-ha'
);
parsePage($vars);
?>
Конечно же, то, что в include нельзя доверять менять пользователям, только обученым людям.
Тогда, это не баг, а фича
Ошибка:
str_replace('{=$'.$key.'}', $value, $html);
А нужно:
$html = str_replace('{=$'.$key.'}', $value, $html);
Спасибо. Видимо, нельзя писать в блог в конце рабочего дня - сплошные глюки.
Помоему ошибка:
str_replace('{=$'.$key.'}', $value, $html);
А надо:
$html = str_replace('{=$'.$key.'}', $value, $html);
Велосипед...
Так однозначно быстрее
//template bla.phtml
PHP и есть шаблонизатор, причем самый быстрый и самый гибкий из всех написанных .
Это холивар, кому как.
И тут все сразу смотрят в сторону eval. Первое, что приходит в голову - написать eval(file_get_contents('template.htm')). И, конечно же, это не работает. Потом читается документация и пишется что-то вроде eval('echo("'.file_get_contents('template.htm').'");');. Но и это тоже не работает.
Мы в своих шаблонах используем eval, не не та как вы описали:
например есть файл file.tpl:
{$main}
</html
И мы делаем так:
$main = "ou la la :-)";
$template = @file_get_contents('file.tpl');
$t = '';
@eval("\$t=<<<HTML\n{$template}\nHTML\n;");
Потом, в нужном месте делаем: echo $t;
Даже не нужно включать буфферизацию вывода ))
естественно, это упрощённый вариант. наш код оформлен в целый класс, где есть условия, циклы, компилирование шаблонов
признаюсь, я очень боюсь конструкций с @ и eval.
стараюсь их использовать только в самом-самом крайнем случае и то если уверен, что сам контролирую то, что эвалится.
.....я конечно извиняюсь...НО....как в этом шаблоне проделывать фокусы с использованием
do{}
While()
или
For()
куда я только не вписывл...и как только не пробывал....что-то не то получалось.
подскажите.....а
Заранее спасибо
Никак. Это не баг, а фича
Если нужно использовать управляющие конструкции PHP, то нужно пользоваться CakePHP и его шаблонами.
Ну зачем сразу чужие шаблоны? Использовать MVC можно и без таких вещей... Если нужен цикл - используем 1 шаблон (который описывает отображение элемента) и оборачиваем во враппер (тобишь - другой шаблон).
И код от шаблона отделен, и функционал реализован
А я пользуюсь своим и он мне нравится
http://maxreplace.zx6.ru/