Покритикуйте шаблонизатор

12 3
mendel
На сайте с 06.03.2008
Offline
183
1772

Написал новый движок шаблонизатора.

Предлагаю пообсуждать пока еще на нем ничего не написано.

Все замечания и пожелания категорически приветствуются!

Суть вопроса: пока под этим модулем ничего не написано, хочу попросить покритиковать синтаксис потому как хоть я его уже написал, но проще сейчас исправить чем потом с этим жить

Введение
Класс обеспечивает работу с шаблонами. Цель - вынести весь HTML код
в отдельные файлы *.tpl которые будут содержать весь дизайн и т.п. Програмируя суть не заморачиваешься о HTML, код проще писать и читать, дизайнеру нет надобности разбираться в PHP коде.


Описание класса
Класс написан по шаблону singleton, т.е. предусматривает существование только одного экземпляра класса.
Экземпляр создается методом init.
$templ = templ::init(каталог_шаблонов, каталог_скинов, режим_шаблонизатора);

Режим_шаблонизатора может быть: file, folder, db
Режим db подразумевает хранение шаблонов в базе данных. На данный момент в стадии разработки. Режим folder подразумевает, что для каждого скина отдельная папка а не файл. Используется редко. В данном режиме нельзя использовать inc в скинах. По умолчанию используется тип file. В этом режиме каждому скину соответствует
файл в папке скинов. Далее описывается работа именно этого режима.

Каталог_скинов это каталог в котором хранятся скины. По умолчанию равен каталогу шаблонов.

Каталог_шаблонов это каталог в котором лежат шаблоны страниц. По умолчанию равен dirname(__FILE__).'/../templ/' т.е. если модуль шаблонизатора расположен в каталоге /include/ и при инициализации шаблонизатора не указать параметров
$templ = templ::init();
то шаблонизатор будет искать шаблоны и скины в папке /templ/

Метод set добавляет переменную в шаблонизатор.
$templ->set(имя_переменной,значение);
Метод get используется для чтения переменной из шаблонизатора. Строго говоря желательно отправлять переменную в шаблонизатор когда все манипуляции с ней завершены. Плюс как правило если переменная нужна проще сохранить ее в пространстве переменных самого php но в некоторых случаях удобнее взять ее из шаблонизатора.
$templ->get(имя_переменной);
Метод do_templ выполняет интерпретацию шаблона и возвращает результат. В отличии от старых версий выводит результат нужно самому. Так сделано потому, что некоторые классы наследующие шаблонизатор выводят html-заголовки и организуют кэширование.
$templ->go(имя_шаблона,имя_скина);
Имя скина по умолчанию равно template.

Типичная работа с модулем выглядит примерно так:
$templ = templ::init(); // инициируем модуль
// собственно логика приложения
$templ->set(имя_переменной1,значение1); // передаем первую переменную
...
$templ->set(имя_переменнойN,значениеN); // передаем N-ную переменную
echo $templ->do_templ(имя_шаблона); // выводим данные с использованием имя_шаблона
Синтаксис языка шаблонов
HTML-код состоит из двух частей - скина и шаблона. Скин это общие для сайта или раздела элементы, а шаблон это часть которая специфична для конкретной страницы. Как правило "скин" содержит дизайн а шаблон структуру данных конкретной страницы.

Работа шаблонизатора начинается с поиска файла соответствующего скина. Если шаблон не указан ищется шаблон с именем template. Если шаблон не найден, то считается что содержимое шаблона равно {BODY}.

В первую очередь в файле скина производится замена конструкций {inc=имя_инклюда} на содержимое соответствующего файла.
Имена подключаемых файлов, как и имена скинов и шаблонов указываются без расширения, которое равно .tpl
Файлы ищутся в папке со скинами. Все несуществующие инклюды считаются равными пустой строке.

Далее шаблонизатор ищет конструкцию {body} и заменяет ее на содержимое файла шаблона. Если шаблон не найден он считается равным пустой строке.

Следующим шагом шаблонизатор заменяет все конструкции {inc=имя_инклюда} на содержимое соответствующих файлов. Эти файлы ищутся уже в папке шаблонов. Все несуществующие инклюды считаются равными пустой строке.

Далее шаблонизатор ищет все конструкции вида {$имя_переменной=значение переменной}, добавляет соответствующие переменные в массив переменных для подстановки и удаляет эти конструкции из шаблона. Это удобно для хранения текстовых констант прямо в шаблоне давая дизайнеру возможность править тексты, или как один из вариантов организации мультиязычности или тайтл хранить в шаблоне, или разместить бокс с "подсказками" в скине, а сами тексты подсказок хранить в шаблонах.

Основные конструкции шаблонизатора

Все конструкции вида {имя_переменной} которые не являются управляющими конструкциями заменяются на значение соответствующей переменной.

Конструкция вида

{if=имя_переменной}
тело
{/if=имя_переменной}
заменяется на "тело" если значение переменной "имя_переменной" истино, и заменяется на пустую строку если оно ложно.

Конструкция вида

{if!=имя_переменной}
тело
{/if!=имя_переменной}
в отличии от предидущей заменяется на "тело" если значение переменной "имя_переменной" ЛОЖНО, и заменяется на пустую строку если оно ИСТИННО.

Массивы

Вывод таблиц и прочих массивов обеспечивается следующей конструкцией:
<array=имя_массива>
тело
</array=имя_массива>
Для каждого элемента массива выводится "тело" с заменой соответствующих переменных. Внутри "тела" массива применимы переменные вида {имя_массива.имя переменной}. Аналогично и условия в условных конструкциях.

Пример php-кода передачи массива:

$people=array();
$people[]=array('name'=>'Иван','woman'=>FALSE,'age'=>18);
$people[]=array('name'=>'Петр','woman'=>FALSE,'age'=>36);
$people[]=array('name'=>'Анна','woman'=>TRUE,'age'=>20);
$people[]=array('name'=>'Гена','woman'=>FALSE,'age'=>33);
$people[]=array('name'=>'Лена','woman'=>TRUE,'age'=>21);
$templ->set('people',$people);
код шаблона для вывода этого массива:

{array=people}
{people.name}, {people.age} лет.
{if=people.woman}Женщина{/if=people.woman}
{if!=people.woman}Мужчина{/if!=people.woman}
{/array=people}
"Волшебные" переменные

В шаблонизаторе есть некоторые предопределенные переменные:
_SELF - адрес страницы откуда вызван скрипт (аналог PHP_SELF) удобна для форм.

В массивах есть такие переменные:
_first - истина если это первая запись в массиве и ложна если НЕ первая.
_last - истинна если последняя запись в массиве и ложна если НЕ последняя.
_odd - истина если запись нечетная по порядку
_even - истина если четная по порядку

Четность/нечетность удобна для того, чтобы можно было выделять разным цветом рядом идущие строки, что улучшает юзабилити интерфейса. Часто не нужно выводить тот или иной тег или надпись если запись первая или последняя но выводить для всех остальных.

Зарезервированные выражения
if=
if!=
array
$
inc
body
_self
_first
_last
_odd
_even
прочие переменные через _
а также аналогичные выражения большими буквами.

HOOK`и шаблонов
HOOK`и это когда в шаблоне делается некая пометка типа "здесь кончается главный блок" или "это начало верхнего меню" или "тут конец левой колонки" и т.п. Когда программист пишет плагин, то он просто указывает что такой-то шаблон нужно вставить вместо того или иного хука. Т.о. при разработке дизайна сайта не обязательно учитывать сразу все плагины. Достаточно расставить в нужных местах хуки, а уже разработчик плагина будет задумываться о том как правильно оформить свой плагин. Далее разработчик плагина хочет в этом месте вывести свой код... к примеру блок тэгов или календарь или рекламную ссылку или любой другой.

Метки хуков в шаблонизаторе имеют такой синтаксис: {#имя_метки}
Программист должен зарегистрировать соответствующий хук примерно таким кодом:
$templ->hook('имя_метки','имя_шаблона');
шаблонизатор встретив метку в шаблоне смотрит есть ли хуки для этой метки.
Если хуков нет, то он просто удаляет метку. Если хуки есть, то он добавляет соответствующие файлы шаблонов вместо метки. Для каждой метки может быть неограниченное количество хуков. Они выводятся в порядке их объявления в программе. Шаблоны хуков берутся в папке шаблонов а не скинов.
Существует также дополнительный синтаксис хуков:
$templ->hook('имя_метки','#код_хука');
т.е. если хук начинается со знака решетки, то вместо того, чтобы искать файл с хуком шаблонизатор просто вставляет все что идет после решетки в шаблон. Рекомендуется использовать такой синтаксис в исключительных случаях, поскольку правила хорошего стиля говорят, что весь html-код должен быть в шаблонах а не в коде, однако в некоторых случаях это является разумным - например когда код вводится в админке и хранится в базе, или когда код настолько прост, что глупо плодить сотни маленьких файлов шаблонов. К примеру код банеров проще выводить напрямую без шаблонов.

Оригинал и актуальная версия здесь.

PS: говорите какие еще нужны "волшебные переменные"

Шутку любишь над Фомой, так люби и над собой. (с) народ. Бесплатные списки читабельных(!) свободных доменов (http://burzhu.net/showthread.php?t=2976) (5L.com) Сайты, All inclusive. 5* (/ru/forum/962215)
kil
На сайте с 03.04.2006
Offline
84
kil
#1

Несмотря на то, что я вряд ли когда-нибудь пойму фишку шаблонизаторов, хотелось бы поинтересоваться насчет быстродействия.

Хотя бы приблизительный порядок времени обработки типового шаблона.

mendel
На сайте с 06.03.2008
Offline
183
#2
kil:
Несмотря на то, что я вряд ли когда-нибудь пойму фишку шаблонизаторов,

А какие могут быть недостатки в использовании шаблонизаторов?

Чем плоха концепция - код отдельно дизайн отдельно?

kil:
хотелось бы поинтересоваться насчет быстродействия.
Хотя бы приблизительный порядок времени обработки типового шаблона.

Ничего пока не скажу потому что ничего под ним не написано пока, но его прадедушка очень шустренький :)

На днях допишу весь движок и переделаю истио под него, тогда добавлю тайминг... но вообще там счет на милисекунды идет...

[Удален]
#3
mendel:
милисекунды идет

это не вау, а стандарт :)

http://helldude.ru/inner/projects/php/DudeTpl/trunk/

пишет 0.004, но если скомпилить все классы в один файл, то будет точно быстрее :)

mendel
На сайте с 06.03.2008
Offline
183
#4
bearman:
это не вау, а стандарт :)

http://helldude.ru/inner/projects/php/DudeTpl/trunk/

пишет 0.004, но если скомпилить все классы в один файл, то будет точно быстрее :)

А кто говорит что это "Вау!"? ;)

Я к тому что какая разница сколько оно жрет если оно несоизмеримо с расходами на модель иконтролер? Есть у меня "самый быстрый" шаблонизатор - всего с десяток строк, да только нафига эта нанооптимизация?

ewg777
На сайте с 04.06.2007
Offline
225
#5
mendel:
А кто говорит что это "Вау!"? ;)
Я к тому что какая разница сколько оно жрет если оно несоизмеримо с расходами на модель иконтролер? Есть у меня "самый быстрый" шаблонизатор - всего с десяток строк, да только нафига эта нанооптимизация?

Почему не смарти? Скорость - фтопку, но столько плюсиков.

[Удален]
#6
ewg777:
но столько плюсиков.

и шашечек

scorpion061181
На сайте с 20.01.2010
Offline
3
#7

А зачем писать свой, если все уже есть?

pelvis
На сайте с 01.09.2005
Offline
345
#8

И все-таки, я не пойму, зачем дизайнеру код нужно знать. Допустим, есть у нас в Boss Cms стандарт:

$this->AppendTemplate('Техническое название блока') - включение шаблона блока
$php echo $this->НазваниеКласса['Какое_поле_выводим']

И встроено это все в html каркас. Вопрос, зачем нужен шаблонизатор, если есть программист? А если нет программиста, то чей карман мешает его нанять на работу?

Продаю вывески. Задарма и задорого (https://www.ledsvetzavod.ru/)
DeveloperRu
На сайте с 27.02.2009
Offline
72
#9

мне кажется, шаблонизатор должен быть по синтаксису похож на Blitz Алексея Рыбака

http://alexeyrybak.com/blitz/blitz_ru.html

Ответы на вопросы (http://telenok.com)
mendel
На сайте с 06.03.2008
Offline
183
#10
ewg777:
Почему не смарти? Скорость - фтопку, но столько плюсиков.
bearman:
и шашечек
scorpion061181:
А зачем писать свой, если все уже есть?

Скорость действительно вопрос не критичный, но помимо скорости есть еще два критерия - фуункционал и простота. В смарти много шашечек.. очень много.

Если взять смарти и оставить только самый минимальный функционал, то все равно кто-то начнет использовать остальные функции, кто-то не поймет что-то и мне это все прийдется поддерживать. Зачем поддерживать чужого монстра если есть свой, который ты знаешь и который полегче как по скорости так и по простоте?

Что касается других шаблонизаторов, то все что я видел меня не устраивало либо по критерию простоты либо по функционалу. Ну и есть еще один ответ на вопрос "зачем писать если уже все есть" - собственно говоря мой шаблонизатор тоже уже давно существует. У меня старшая цифра четверка т.е. это уже 4.1.0b (старшая цифра меняется только при потере совместимости с предыдущими)

Ну а в целом фреймворк пишу потому что свой старый не устраивает излишней закрытостью (т.е. удобен мне, но неудобен другим) а чужие не устраивают либо излишней сложностью либо излишней простотой.

pelvis:
И все-таки, я не пойму, зачем дизайнеру код нужно знать. Допустим, есть у нас в Boss Cms стандарт:

Не совсем ясно, но кажется Вы говорите о том чем ваш код отличается от {пользователь.фамилия} или же просто {фамилия}. Как мне кажется что мой вариант проще для понимания.

pelvis:
Вопрос, зачем нужен шаблонизатор, если есть программист?

Чем плох и хорош виндовый сервер? Решения от майкрософт дороги, и требуют гораздо больших усилий для поддержания его работоспособности. Поставив более удачное решение ты получишь меньше денег и не будешь зарабатывать на обслуживании. :)

pelvis:
А если нет программиста, то чей карман мешает его нанять на работу?

Есть разные подходы к работе. Лично для меня не приемлемо продавать решение за 500р. а потом его поддерживать. Я предпочитаю продать все права на продукт за более крупную сумму и пусть уже другой человек его поддерживает а мне остаются только сложные моменты за отдельные деньги. Причем здесь шаблонизатор? Да при том, что я стараюсь минимизировать работу программиста. Это просто разные подходы. Каждый имеет право на жизнь.

Вон посмотри как Дуров пишет - это же истерика для "ортодоксального" программиста... Одни его ляпы типа возможности перевода отрицательных голосов чего стоят. Зато небольшими ресурсами поднял такую махину...

12 3

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий