В который раз задаюсь вопросом каким же должен быть шаблонизатор?
При разработке последнего проекта на enigm'e делал свой шаблонизатор - некий гибрид DLE'шного... получилось очень сыро, но уже тогда задумался о необходимости использовать условия и switch'и...
От концепции блочных тегов я ушёл сразу - крайне неудобная штука имхо... конструкция $tpl->set также не прижилась...
Обработка регулярными выражениями тегов (+ блоков) также крайне неправильна...
ТеорияВ который раз задаюсь вопросом каким же должен быть шаблонизатор?
Вот список требований которым он как Я считаю должен удовлетворять:
Замена простых тегов в пределах одного шаблона.
Замена глобальных тегов для всех шаблонов. (например языковых констант)
Использование условий и switch'ей. Обязательно необходимо поддерживать вложенность операторов друг в друга.
Использование определённого набора ф-ций (например translit) и возможность вставки php кода. Набор функций должен расширяться динамически.
Шаблоны необходимо кэшировать, но при этом соблюдая актуальность данных.
Шаблонизатор должен обеспечивать обработку иерархических данных т.е. если из модуля пришёл результат в определённом формате (в моём случае это массив), то шаблонизатор должен автоматически подгрузить необходимые шаблоны и подставить нужные данные.
Дополнительно... при компиляции можно реализовать следующее:
* Автоматически вырезать весь js код и стили из тела шаблона, сжимать всё (в gzip) и сохранять в отдельные файлы.
* Автоматически валидировать html, пробывать "причесать" код.
Основная задача — максимально разграничить труд программера и дизайнера, при этом сохранив чоткую, простую и понятную структуру шаблонов и тегов, в которой смог бы разобраться любой.
Очевидной проблемой для меня является, то что чем больше шаблонов, тем выше будет нагрузка на всю систему.
После очень долгих размышлений и просмотра уже готовых решений Я всё же пришёл к такому выводу (здесь я расматриваю шаблонизатор как часть CMS):
Каждый шаблон закреплён за определённым модулем и Я всегда имею в наличии список шаблонов для того или иного модуля.
Шаблоны компилируются в отдельные файлы-классы, которые затем инклудяться. Каждый такой класс представляет собой группу шаблонов одного модуля.
Каждый такой класс содержит ф-ции, которые возвращают обычный HTML текст!
Такой подход создаёт некоторые неудобства:
* При изменении одного или нескольких шаблонов необходимо будет перекомпилировать все шаблоны в пределах модуля. Поэтому нужно всегда проверять наличие ф-ции в классе и в случае необходимости автоматически делать перекомпиляцию.
* Необходимо иметь репозиторий всех шаблонов и всегда знать какой шаблон к какому модулю относится. Это не проблема, мы всегда можем закешировать эти данные и хранить их в массиве.
КодимИ что же у меня вышло?! :)
Примерно следующее...
$core = class_core::instance ();
$core->init ();
$buffer = array ();
for ( $i = 1; $i <= 50; $i ++ )
{
$buffer[] = array
(
'template' => 'main',
'plugin' => 'news',
'is_logged' => rand ( 0, 1 ),
);
}
$start = microtime ( true );
$core->template->cache_dir = CACHE_DIR . 'skin_cache/';
echo $core->template->compile (
array
(
'template' => 'main',
'plugin' => 'core',
'content' => $buffer,
));
$stop = microtime ( true ) - $start;
echo $stop;
Как видим Я загружаю один основной шаблон main, который принадлежит модулю core и в него, внутрь тега {content}, 50 шаблонов main, принадлежащие news, при этом они располагаются один за другим внутри этого тега.
При всём этом обработка всех этих шаблонов у меня заняла 0.00217 сек., к примеру обработка шаблонизатора в DLE около 15 шаблонов с
включённым кэшированием заняла 0.02411 секунд (а всё из за загрузки огромного кол-ва файлов)!
Думаю скорость налицо! И при всём при этом я имею огромную функциональность для дизайнера и строго ограниченное кол-во кэш-файлов, т.е. кэш шаблонов не разрастается как в DLE.