MACRO - стотысячная попытка сделать новый PHP шаблонизатор

dark-demon

d(^-^)b
в данном случае применяется дефолтный шаблон страницы. page/make - либо трансформирует массив в dom-xml и натравливает xslt, либо парсит шаблон и сам же трансформирует массив в html. второй вариант геморройней, зато можно расширять xslt. например, можно ввести <xsl:tree><xsl:branch><xsl:leaf> для "деревянной" обработки.
 

pachanga

Новичок
Автор оригинала: ustas
как реализовать хочешь ?
------------------------------
{{tree *****}}
html
{{call tree *****}}
html
{{/tree}}
------------------------------
Сделал proof of concept реализацию {{tree}} макроса, посмотри на тесты - https://svn.limb-project.com/limb/3.x/trunk/limb/macro/tests/cases/tags/lmbMacroTreeTagTest.class.php и собственно реализацию - https://svn.limb-project.com/limb/3.x/trunk/limb/macro/src/tags/tree.tag.php

Там пока можно использовать только массивы, нет проверок на ошибки - это просто демонстрация, что умеет MACRO.

-~{}~ 16.10.07 10:10:

Автор оригинала: dark-demon
ну вот простейший контроллер:
<?
$reg= $scriptArg[1];
$data= [];
$data['news']= inc( 'news', $reg );
$data['menu']= inc( 'menu/main', $reg );
$data['user']= inc( 'user/info', $reg );
$data['content']= inc( $reg[ 'handler' ], $reg );
echo inc( 'page/make', $reg + array( 'output' => $data ) );
?>
Ну вот смотри, у тебя есть 10 подобных "правильных контроллеров" и что каждый из них будет дублировать логику по передаче _второстепенных_ для него данных(это новости) каждый раз? А вдруг заказчик захотел, чтобы еще и последние топики из форума показывались где-то в колонке, и что, ты это опять продублируешь передачу топиков 10 раз?

Ты попытался разделить приложение на "правильные слои", наверное, используя "парадигму MVC", а закончил тем, что ввел дублирование в контроллеры и логику, которой ну вообще никак не должен он заниматься. Браво!

-~{}~ 16.10.07 10:12:

Автор оригинала: CatManZero
Сомнительно, что получится так просто избавиться от последствий XML-мании. Слишком много завязано на нем. Это и HTML и DOM, благодаря которому появились такие замечательные вещи как jQuery и различные wisiwyg-редакторы.
Я не хочу сказать, что XML вселенское зло, но, ведь, и перебарщивать тоже не надо.
 

StUV

Rotaredom
Автор оригинала: pachanga
Воот, самое лаконичное и удачное определение, на самом деле ;)
если это действительно "на самом деле" - зачем тогда этот "syntactic sugar" вообще нужен?
тем более что МАКРО все-равно способен реализовать что угодно и как угодно?

на уровне соглашений можно как запретить обогащать синтаксис шаблонизатора новыми конструкциями так и запретить использовать "сложный" код в native-php-шаблонах

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

а на счет того, что верстальщикам с разных контор трудно читать шаблоны друг-друга
так это будет верно и для смарти, и для xml/xsl, и для blitz
и тем более для native-php

но это имхо проблема самая последняя в ряду

зы: применять xml/xsl действительно имеет смысл в системе сервисов, написанных с использованием разных технологий
+ rss/etc... - в остальных случаях - еще одни тормоза и не более того
 

korchasa

LIMB infected
Автор оригинала: CatManZero
Сомнительно, что получится так просто избавиться от последствий XML-мании. Слишком много завязано на нем. Это и HTML и DOM, благодаря которому появились такие замечательные вещи как jQuery и различные wisiwyg-редакторы.
А зачем выносить преимущества XML за пределы HTML? XML избыточен, поэтому в конфигах все чаще применяют YAML, в AJAX - JSON, и т.д.

...Но нужна замена ... и dom. Надеюсь я это там увижу...
Зачем? С аналогом XPath, как namespaces я согласен.

XML/XSLT - стандарт. Он этим хорош и этим плох. Вероятность найти человека работающего с каким-то стандаротом прямо зависит от его распространенности, и обратно, от его сложности (пусть даже не линейно). MACRO мне и нравится тем, что порог входа в него очень низкий, а ограничения накладываюстся только языком.

ЗЫ: Я работал с XSLT, в частности с генерацией PDF через FO. В таких задачах он мне понравился, т.к. генерировать приходилось формы отчетности, т.е. под строго определенные размеры. Зачем переносить весь этот геморой в "нестандартизированные" странички хоть убейте не понимаю.
 

pachanga

Новичок
Автор оригинала: StUV
если это действительно "на самом деле" - зачем тогда этот "syntactic sugar" вообще нужен?
тем более что МАКРО все-равно способен реализовать что угодно и как угодно?
Ну вот, например, я показал пример реализации дерева с помощью макроса {{tree}}, давай посмотрим, что получится, если сделать то же самое на голом PHP? Или, например, {{wrap}} макрос, который компилируется очень оптимально и не вызывает оверхеда во время исполнения при этом добавляет, на мой взгляд, крайне полезный функционал. Опять же, попробуй сделать это на голом PHP ;) Или {{include}} макрос - в случае статического подключения происходит включение шаблона на _этапе компиляции_, а не во время исполнения. Я могу долго перечислять ;)

Т.е я сам совершенно не против PHP в шаблонах, однако если макросы могут сделать шаблон более экспрессивными, читабельным и эффективными на этапе исполнения, не вижу причин их не использовать.
 

atv

Новичок
Стандартный для кого? Для руководителей, которые живут в иллюзорном мире различных парадигм и "грамотном разделении приложения на слои"? Которые заставляют верстальщика мучиться с XSLT красотами вместо того, чтобы быстро, и самое главное, понятно решать задачу?
pachanga, ты опускаешься до уровня банального флеймера? По моему, здесь обсуждается MACRO, и XSLT упоминался в контексте примера функциональности, которой в макро нет. Никто не говорит что у XSLT нет недостатков, и никто не воздвигает его на постамент, но та функциональность, о которой я говорил, полезна, и глупо это отрицать.

На все свои вопросы, которые ты задавал dark-demonу, "особо опытному" пользователю XSLT, ты можеш найти ответы в PHP_Application.

Ну вот смотри, у тебя есть 10 подобных "правильных контроллеров" и что каждый из них будет дублировать логику по передаче _второстепенных_ для него данных(это новости) каждый раз? А вдруг заказчик захотел, чтобы еще и последние топики из форума показывались где-то в колонке, и что, ты это опять продублируешь передачу топиков 10 раз?
Даже в MVC реализациях есть события preExecute и postExecute, в которые можно вставить дублирующиеся участки кода, и тем самым избежать дублирования. Так что не надо тут панику поднимать, и в ладоши хлопать.
 

pachanga

Новичок
Автор оригинала: atv
...XSLT упоминался в контексте примера функциональности, которой в макро нет.
Какой еще раз функциональности нет в MACRO?

Даже в MVC реализациях есть события preExecute и postExecute, в которые можно вставить дублирующиеся участки кода, и тем самым избежать дублирования. Так что не надо тут панику поднимать, и в ладоши хлопать.
Покажи пример, плиз, как бы ты решил ту же саму задачу.

-~{}~ 16.10.07 11:33:

Автор оригинала: atv
pachanga, ты опускаешься до уровня банального флеймера?
Я разговариваю с человеком его же языком...
 

StUV

Rotaredom
pachanga
самый удачный пример с {{tree}}
с пхп-натив реально придется писать сложный для понимания верстальщика контроллер (ну не более сложный чем "class lmbMacroTreeTag ..." ;)) с простым использованием подключением в самом шаблоне, или получить весь этот хкод в шаблоне, если им займется "неразумный кодер"...

Или, например, {{wrap}} макрос
это я как-то пропустил, сорри, наверно не очень внимательно читал тред - что там за проблема?

{{include}} макрос - в случае статического подключения происходит включение шаблона на _этапе компиляции_, а не во время исполнения.
хм
/me придумал раздельную компиляцию натив-пхп-инклудов на ob_*-функциях с возможностью раздельного кеширования подшаблонов в иерархии документа + с повторным использованием структур данных в разных местах страницы
не так все сложно оказалось ;)

Я могу долго перечислять
ну... я могу долго перечислять грабли с другой стороны ;)

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

pachanga

Новичок
это я как-то пропустил, сорри, наверно не очень внимательно читал тред - что там за проблема?
Посмотри, плиз внимательно выше я объяснил, как работает {{wrap}}, если интересно, посмотри тесты на него https://svn.limb-project.com/limb/3.x/trunk/limb/macro/tests/cases/tags/lmbMacroWrapTagTest.class.php(обрати внимание на multi и nested wrap). Вот как это можно реализовать просто средствами PHP в шаблоне?

но если этим занимаются пхп-кодеры - причин использования надстройки над пхп, имхо, нет
Я даже и не знаю, какие еще аргументы приводить. Улучшения понятности, читабельности, экспрессивности, эффективности, наверное, недостаточно ;)
 

CatManZero

Новичок
...Но нужна замена ... и dom. Надеюсь я это там увижу...
Автор оригинала: korchasa

Зачем? С аналогом XPath, как namespaces я согласен.
Я не имел ввиду конкретную реализацию. Я подразумевал, что раз YAML претендует на лавры XML, он должен иметь необходимый инструментарий: средства для поиска (альтернативу XPath, необязательно такую навороченную) и средства управления (альтернативу DOM).
 

dark-demon

d(^-^)b
> Ну вот смотри, у тебя есть 10 подобных "правильных контроллеров"
> и что каждый из них будет дублировать логику по передаче _второстепенных_
> для него данных(это новости) каждый раз?

да, так. основной контроллер должен иметь полный контроль над формированием страницы.
когда я пишу в контроллере, что нужно вывести только меню и новости - должны быть выведены
только меню и новости. и я не должен беспокоиться, что верстальщику приспичит вставить куда-то
вызов модуля NewsVersion10 вместо NewsVersion20, и мне потом придётся оправдываться,
что это верстальщик порушил бизнес-логику.


> А вдруг заказчик захотел, чтобы еще и последние топики из форума показывались
> где-то в колонке, и что, ты это опять продублируешь передачу топиков 10 раз?

нет, для этого добавляем такую строчку:
foreach( $reg[ 'widgets' ] as $widget ) $data[ $widget ]= inc( 'widgets/'.$widget, $reg );
где в $reg[ 'widgets' ] содержится дефолтный набор модулей. при этом контроллер может из своих соображений
скрыть какие-то из них или наоборот добавить своих.


> Даже в MVC реализациях есть события preExecute и postExecute, в которые можно вставить дублирующиеся участки кода

не стоит так делать, ибо когда потребуется их не выполнять - начнутся танцы с бубном.
preExecute и postExecute должны носить рекомендательный характер, но право вызова должно
оставаться за контроллером.
 

StUV

Rotaredom
Посмотри, плиз внимательно выше я объяснил, как работает {{wrap}}
посмотрел
часто возникают задачи, когда те же данные нужно _быстро_ обработать в другом контексте?
у меня нет
возможно, если появятся, я посмотрю в эту сторону
пока что xml/xsl для "фоновых" (не требующих повышенной производительности) задач хватает...
 

pachanga

Новичок
Автор оригинала: StUV
тесты производительности
возможно с предкомпиляцией, но без кеширования ;)
Ну ты же понимаешь, что в конечном итоге выполняется просто PHP код, что может быть быстрее?

Я начал создавать основу для бенчей https://svn.limb-project.com/limb/3.x/trunk/limb/macro/tests/bench/. Там пока только простейшие бенчи, однако я добавлю бенч, который будет сравнивать нативный PHP include с MACRO {{include}}, и, поверь, нативный вариант будет медленнее, просто потому что в MACRO не происходит вызов PHP include в runtime.
 

dark-demon

d(^-^)b
CatManZero, YAML трансформируется в наивные типы => ни xpath, ни DOM.. если, конечно, не реализовать их руками :)

и YAML никак не может претендовать на лавры XML, потому как ему не хватает X хромосомы, те eXstensible-а
можно, например, в качестве значения в YAML использовать вложенный YAML? :)

-~{}~ 16.10.07 12:31:

pachanga, а с опкодкэшем?
 

pachanga

Новичок
Автор оригинала: StUV
посмотрел
часто возникают задачи, когда те же данные нужно _быстро_ обработать в другом контексте?
Вообще, идея {{wrap}} в другом, он позволяет, избежать дублирование в шаблонах. Вместо того, чтобы в каждом шаблоне писать:

Код:
{{include file="header.phtml"}}
Content
{{include file="footer.phtml"}}
Можно сделать один шаблон layout.phtml:

Код:
<html>
...
{{slot id="content"}}
...
</html>
И в шаблонах просто писать:

Код:
{{wrap with="layout.phtml" into="content"}}
Content
{{/wrap}}
Но это не все, можно обворачивать и вставлять содержимое в несколько зон:

Код:
{{wrap with="layout.phtml"}}
  {{into slot="title"}}
   Some title
  {{/into}}
  {{into slot="content"}}
   Some content
  {{/into}}
{{/wrap}}
Тогда шаблон layout.phtml будет например такой:
Код:
...
<h1>{{slot id="title"}}</h1>
...
<div class="body">
{{slot id="content"}}
</div>
...
Но и это еще не все, layout можно менять на лету, если использовать переменную: {{wrap with="$this->layout"}}, в этом случае мы жертвуем эффективностью за повышенную гибкость - обворачивание происходит в runtime.

-~{}~ 16.10.07 12:40:

и YAML никак не может претендовать на лавры XML, потому как ему не хватает X хромосомы, те eXstensible-а
можно, например, в качестве значения в YAML использовать вложенный YAML? :)
Какой-то прямо клинический случай идолопоклонничества XML.

pachanga, а с опкодкэшем?
И с ним тоже.

-~{}~ 16.10.07 12:45:

Автор оригинала: dark-demon
> Ну вот смотри, у тебя есть 10 подобных "правильных контроллеров"
> и что каждый из них будет дублировать логику по передаче _второстепенных_
> для него данных(это новости) каждый раз?

да, так. основной контроллер должен иметь полный контроль над формированием страницы.
Кто кому "должен"? Мне очень забавно тебя читать. Ты, наверное, совсем недавно прочитал PoEAA и теперь полностью и бесповоротно следуешь "библии архитектора"?

> Даже в MVC реализациях есть события preExecute и postExecute, в которые можно вставить дублирующиеся участки кода

не стоит так делать, ибо когда потребуется их не выполнять - начнутся танцы с бубном.
Я смотрю, "в друзьях согласья нет" ;) Ну что, давайте теперь еще поговорим про "парадигмы MVC"...
 

StUV

Rotaredom
Вместо того, чтобы в каждом шаблоне писать:
зачем?
html-документ в конечном счете дерево
сложная страница бьется на нужное количество подшаблонов
контроллер собирает окончательный вариант из поддеревьев и листьев
дублирования не будет


нативный вариант будет медленнее, просто потому что в MACRO не происходит вызов PHP include в runtime.
тесты покажут.... - все зависит от качества твоего компилера ;)
+
в отладке проще нормальный пхп-шаблон, чем то что получается напр в смарти после компиляции (но это уже "дело вкуса" ;))

+
мне вообще нельзя использовать предкомпиляцию
раздельное кеширование/компиляцию вложенных структур - могу
но полную предкомпиляцию страницы "в общепринятом" смысле я себе даже не представляю как организовать для тех структур данных, с которыми в последнее время приходится работать
 

pachanga

Новичок
Автор оригинала: StUV
зачем?
Ладно, это бесполезный спор ;)

тесты покажут.... - все зависит от качества твоего компилера ;)
Точнее от качества реализации конкретного макроса. Естественно накосячить можно везде, но ведь есть же тесты, бенчи ;)

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

мне вообще нельзя использовать предкомпиляцию
Почему?
 

StUV

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

-~{}~ 16.10.07 13:35:

зы: если я на бэк-енде буду сразу компилировать данные по событию во весь набор статических структур - вот тут я точно получу столько дублирования, что .... ну ты знаешь ;)
 

pachanga

Новичок
Автор оригинала: StUV
т.е. конечная страница все-равно компилируется по запросу
Ну не верю я, что этот процесс нельзя никак оптимизировать в вашем случае ;) Просчеты архитектуры?
 
Сверху