С.
Продвинутый новичок
Идеальный шаблонизатор
В стотысячный раз мы становимся свидетелями написания шаблона "с обратного конца". Есть у человека идея синтаксиса или реализации и дай, думает он, сделаем из этого шаблонизатор. Строить проект, отталкиваясь от его реализации -- немного странно, не кажется ли вам? Ничуть не менее странный и другой подход: "Чтоб как в Смарти, но быстрее".
Предлагаю поставить вещи с головы на ноги и разработать идеальный шаблонизатор, а уж потом придумывать его конкретные реализации. Чтоб не создавать изначально лоскутных одеял с торчащими белыми нитками.
Для начала определимся на берегу, что идеальный шаблонизатор это элемент "View" парадигмы MVC. То есть ничего, не относящегося ко View там не должно быть. Например кеширование результата работы шаблонизатора (выходных данных) не явлается его прерогативой. К этому не относится компилирование шаблона и кеширование кода. Эта часть, если она имеет место, является внутренней функцией шаблонизатора.
Базовая функциональность шаблонизатора:
- подстановка переменных
- условное ветвление
- организация циклов
- включение другого шаблона
- вызов функциональных модулей (для активных шаблонов)
Вряд ли кто-то будет оспаривать данный список. Все страсти, как правило, кипят вокруг расширений базовой функциональности. Собственно все разнообразие шаблонизаторов -- это множество расширений. В базовой функциональности они все близнецы-братья, отличающиеся лишь кучерявостью и угловатостью скобок.
Таким образом мы получаем следующий вывод: базовой функциональности шаблонизатора недостаточно для реальной работы. Практичный шаблонизатор должен обладать некоторой расширенной функциональностю.
Существуют два крайних подхода к расширению базовой фунциональности. Одни предлагают нативные вставки кода, а другие - конечное множество интерфейсных свойств, как то например четность или нечетность итерации. Первый подход просто уродец, рушащий сам принцип шаблонизации, а второй обладает неприятным свойством недостаточности. Нужного вам интерфейса всегда не будет хватать.
Далее я предлагаю выработать подход к расширению фукциональности шаблонизатора без потерь его качеств, удобства использования и не внося неоправданных ограничений.
В чем собственно состоит смысл расширения функциональности? Мы привыкли говорить об отделении кода от представления (Model от View). Но оказалось, что кроме функционального кода, существует еще код представления. То есть мы обсчитали модель, выдали "на гора" результат и пихнули их во View. Но этого оказывается мало. Для построения соответствующего визуального представления во View надо написать немалый код.
Совершенно естественно, если бы шаблонизатор подхватил эстафету и предоставил эту визуальную логику внутри себя. Тут мы и сталкиваемся с проблемой, что в шаблонизаторе общего назначения мы не можем предусмотреть все возможные варианты визуальной логики. Напрашивается единственное решение -- расширение функциональности шаблонизатора за счет "макросов", "хелперов" и т.п.
Не спешите говорить, что это все просто. Мы ведь создаем идеальный шаблонизатор, а в идеальном шаблонизаторе дизайнер должен также иметь доступ к HTML, как и в базовой функциональности. То есть шаблон вида
не годится. Все HTML нутро этого макроса должно быть здесь же и совершенно очевидно и логично занимать свое место в общем потоке HTML.
В качестве тест-драйва для создания идеального шаблона я предлагаю две задачи. Как для браузеров существует ACID тест, так же примерно по решению этих двух задач можно будет судить, на сколько шаблонизатор функционален и элегантен.
Первая задача уже поднималась на форуме -- построение дерева. Напомню, что образец идеального шаблона будет иметь примерно такой вид:
Вторая задача немного из другой степи. В принципе она решается базовой функциональностью, но де факто имеет очень "неопрятный" вид. Я говорю о создании форм. Из рассмотрения исключаются генераторы форм, вид которых задается где-то в другом месте, кроме шаблона. По сути задача состоит в создании генератора форм, встроенного в шаблонизатор. Условия те же: HTML код, отвечаюший за визуальное представление находится в шаблоне в "свободном доступе" и "на своем месте". Технические детали, как то присвоение начальных данных, возведение CHECKED или SELECTED должны быть скрыты.
Предлагаю в первую очередь обсудить сами принципы построения шаблонизатора. А уже исходя из них подвергать оценке какие-либо конкретные реализации. Призываю также убрать из рассмотрения предмет кучерявости скобок, скорости исполнения и компилируемости, как не относящиеся к принципам шаблонизации в данной теме.
В стотысячный раз мы становимся свидетелями написания шаблона "с обратного конца". Есть у человека идея синтаксиса или реализации и дай, думает он, сделаем из этого шаблонизатор. Строить проект, отталкиваясь от его реализации -- немного странно, не кажется ли вам? Ничуть не менее странный и другой подход: "Чтоб как в Смарти, но быстрее".
Предлагаю поставить вещи с головы на ноги и разработать идеальный шаблонизатор, а уж потом придумывать его конкретные реализации. Чтоб не создавать изначально лоскутных одеял с торчащими белыми нитками.
Для начала определимся на берегу, что идеальный шаблонизатор это элемент "View" парадигмы MVC. То есть ничего, не относящегося ко View там не должно быть. Например кеширование результата работы шаблонизатора (выходных данных) не явлается его прерогативой. К этому не относится компилирование шаблона и кеширование кода. Эта часть, если она имеет место, является внутренней функцией шаблонизатора.
Базовая функциональность шаблонизатора:
- подстановка переменных
- условное ветвление
- организация циклов
- включение другого шаблона
- вызов функциональных модулей (для активных шаблонов)
Вряд ли кто-то будет оспаривать данный список. Все страсти, как правило, кипят вокруг расширений базовой функциональности. Собственно все разнообразие шаблонизаторов -- это множество расширений. В базовой функциональности они все близнецы-братья, отличающиеся лишь кучерявостью и угловатостью скобок.
Таким образом мы получаем следующий вывод: базовой функциональности шаблонизатора недостаточно для реальной работы. Практичный шаблонизатор должен обладать некоторой расширенной функциональностю.
Существуют два крайних подхода к расширению базовой фунциональности. Одни предлагают нативные вставки кода, а другие - конечное множество интерфейсных свойств, как то например четность или нечетность итерации. Первый подход просто уродец, рушащий сам принцип шаблонизации, а второй обладает неприятным свойством недостаточности. Нужного вам интерфейса всегда не будет хватать.
Далее я предлагаю выработать подход к расширению фукциональности шаблонизатора без потерь его качеств, удобства использования и не внося неоправданных ограничений.
В чем собственно состоит смысл расширения функциональности? Мы привыкли говорить об отделении кода от представления (Model от View). Но оказалось, что кроме функционального кода, существует еще код представления. То есть мы обсчитали модель, выдали "на гора" результат и пихнули их во View. Но этого оказывается мало. Для построения соответствующего визуального представления во View надо написать немалый код.
Совершенно естественно, если бы шаблонизатор подхватил эстафету и предоставил эту визуальную логику внутри себя. Тут мы и сталкиваемся с проблемой, что в шаблонизаторе общего назначения мы не можем предусмотреть все возможные варианты визуальной логики. Напрашивается единственное решение -- расширение функциональности шаблонизатора за счет "макросов", "хелперов" и т.п.
Не спешите говорить, что это все просто. Мы ведь создаем идеальный шаблонизатор, а в идеальном шаблонизаторе дизайнер должен также иметь доступ к HTML, как и в базовой функциональности. То есть шаблон вида
Код:
...
{MySuperMacros($data)}
...
В качестве тест-драйва для создания идеального шаблона я предлагаю две задачи. Как для браузеров существует ACID тест, так же примерно по решению этих двух задач можно будет судить, на сколько шаблонизатор функционален и элегантен.
Первая задача уже поднималась на форуме -- построение дерева. Напомню, что образец идеального шаблона будет иметь примерно такой вид:
Код:
...
{TREE}
<ul>
{BRANCH}
<li>{DATA}</li>
{/BRANCH}
</ul>
{/TREE}
...
Предлагаю в первую очередь обсудить сами принципы построения шаблонизатора. А уже исходя из них подвергать оценке какие-либо конкретные реализации. Призываю также убрать из рассмотрения предмет кучерявости скобок, скорости исполнения и компилируемости, как не относящиеся к принципам шаблонизации в данной теме.