pachanga
Новичок
MACRO - стотысячная попытка сделать новый PHP шаблонизатор
Всем привет! Что может быть лучше того, чтобы пофлеймить в оффтопе в выходные дни на счет еще одной(возможно тщетной) попыткой сделать новый шаблонизатор
Хотел бы начать с того, что, на мой взгляд, лучшим шаблонизатором для PHP является...сам PHP Для кого-то это может быть спорным утверждением, но никто же не будет отвергать тот факт, что изначально PHP именно и задумывался с этой целью: перемешивание разметки с программной логикой. И с этой задачей PHP справляется просто замечательно, так почему же этим не воспользоваться и лишь сделать этот процесс более удобным?
Как обычно говорится в такие моменты, meet MACRO! Основная цель MACRO - облегчить процесс использования PHP вперемешку с какой-либо разметкой при помощи макросов. Идея с макросами концептуально взята из C/C++, однако в MACRO намного расширена. В конечном итоге макросы, как и в C/C++ преобразуются в PHP код. Процесс компиляции шаблона, естественно, не сверх быстрый, поэтому MACRO поддерживает кеширования результат компиляции.
В принципе, в качестве шаблонов для MACRO можно использовать обычный PHP код, например:
Но, согласитесь, вот это более читабельно:
В этом плане MACRO похож на Smarty, но, наверное, здесь сходства и кончаются.
Или, например, следующий PHP код, который можно спокойно использовать в MACRO:
...можно переписать так, используя макрос {{list}}:
Внимательный читатель возмутится - "как же так, ведь PHP версия короче!", и именно для этого случая будет прав. Но, a) никто и не мешает использовать PHP напрямую в MACRO b) на самом деле, {{list}} макрос умеет делать намного больше(кстати, в PHP версии вместо <?php echo $item;?> можно использовать просто {$item}).
Покажу более продвинутый пример использования {{list}}:
PHP версия бы выглядела как-то так(примерно это MACRO и генерирует для этого случая):
Опять же, этот код можно так и использовать, но, думаю, на этот раз преимущество макроса {{list}} более очевидно. И опять же, {{list}} умеет делать еще некоторые довольно полезные вещи, о которых, если будет интересно, я могу рассказать.
В общем, если вы все еще читаете, то наверное, уже стало понятно что {{foo}} - макрос, а {$foo} - так называемое output expression в терминах MACRO. Написать свой простейший макрос довольно просто, например, создав файл hello.tag.php(в определенной директории) с таким содержанием:
Теперь, этот макрос, который автоматически "подцепится", можно использовать в шаблоне так:
..и это выведет "Hello world!"
В поставке с MACRO, кроме {{list}} идет еще ряд макросов, например, {{include}} и {{wrap}}. Хороший пример всегда лучше кучи нудных речей, поэтому сразу к примерам и перейдем:
page.phtml
layout.phtml
Когда происходит рендеринг page.phtml, он "обворачивается" в шаблон layout.phtml и вставляется в слот content. Шаблон layout.phtml же в свою очередь подключает шаблоны header.phtml и footer.phtml(которые для экономии места я здесь не привожу).
В принципе, {{include}} макрос можно заменить обычной <?php include(..); ?> вставкой, однако MACRO делает это более оптимально, включая содержимое подключаемого шаблона на этапе компиляции(с оговоркой, если подключаемый файл задается константой, когда же используется динамическое подключение типа {{include file="$some_file"}}, то подключение происходит в runtime).
Если {{include}} имеет довольно простой PHP эквивалент, то {{wrap}} работает намного сложнее и PHP версия будет выглядеть не столь тривиально. Однако и {{wrap}} в случае статического обертывания(т.е когда используется {{wrap with="some_tpl.phtml ..}}) компилируется оптимально в один единственный шаблон. В случае же динамического обворачивания, конечный результат не столь оптимален, но более гибок. Покажу пример:
page.phtml
В этом примере, мы можем при помощи переменной $layout контролировать процесс обворачивания в конкретный шаблон. Кстати, здесь же можно увидеть, что все переменные, которые передаются в MACRO из вне, доступны глобально через $this. {{include}} и {{wrap}} умеют делать еще некоторые полезные вещи(например, неограниченная глубина обворачиваний, передача параметров и проч), о которых, опять же, я расскажу, если будет интерес.
Еще несколько слов про output expressions, они поддерживают фильтры, т.е:
В конечном итоге это скомпилируется в PHP код вида:
Фильтры, как и макросы, писать также довольно просто, например:
Кроме этого output expressions поддерживают metnods chaining:
Что в итоге превратится примерно в следующее:
Мелочь, но довольно удобно. Output expressions умеют еще много чего, но...не все же карты раскрывать сразу
Из основных возможностей MACRO, пожалуй, все. Собственно, зачем я затеял этот тред: 1) хотелось бы просто услышать мнения людей 2) чисто корыстные цели заинтересовать еще кого-то и, возможно, найти единомышленников
MACRO доступен в Limb3 репозитории и является кандидатом на включение в стандарную поставку пакетов, как только все задуманное будет сделано. А задуманного осталось довольно много: {{pager}} макрос, набор удобных {{form}}, {{input}}, {{textarea}} и проч. макросов.
P.S. Если кто-то интересуется Limb3, возможно спросит, " а как же WACT?". В двух словах, я разочаровался в нем, хотя он пока и является шаблонизатором Limb3 по-умолчанию. Скажем так, MACRO является продолжателем идей WACT, однако в более простой и логичной оболочке. Кстати, в Limb3 уже в данный момент можно использовать одновременно и WACT и MACRO, однако однажды в будущем хотелось бы полностью переключиться на MACRO.
Всем привет! Что может быть лучше того, чтобы пофлеймить в оффтопе в выходные дни на счет еще одной(возможно тщетной) попыткой сделать новый шаблонизатор
Хотел бы начать с того, что, на мой взгляд, лучшим шаблонизатором для PHP является...сам PHP Для кого-то это может быть спорным утверждением, но никто же не будет отвергать тот факт, что изначально PHP именно и задумывался с этой целью: перемешивание разметки с программной логикой. И с этой задачей PHP справляется просто замечательно, так почему же этим не воспользоваться и лишь сделать этот процесс более удобным?
Как обычно говорится в такие моменты, meet MACRO! Основная цель MACRO - облегчить процесс использования PHP вперемешку с какой-либо разметкой при помощи макросов. Идея с макросами концептуально взята из C/C++, однако в MACRO намного расширена. В конечном итоге макросы, как и в C/C++ преобразуются в PHP код. Процесс компиляции шаблона, естественно, не сверх быстрый, поэтому MACRO поддерживает кеширования результат компиляции.
В принципе, в качестве шаблонов для MACRO можно использовать обычный PHP код, например:
Код:
<?php echo $foo;?>
Код:
{$foo}
Или, например, следующий PHP код, который можно спокойно использовать в MACRO:
Код:
<?php foreach($items as $item) {?>
<b><?php echo $item;?></b>
<?php } ?>
Код:
{{list using="$items" as="$item"}}
{{list:item}}
<b>{$item}</b>
{{/list:item}}
{{/list}}
Покажу более продвинутый пример использования {{list}}:
Код:
{{list using="$items" as="$item" counter="$count"}}
Items:
{{list:item}}
{$count})<b>{$item}</b>
{{/list:item}}
done!
{{list:empty}}
Nothing
{{/list:empty}}
{{/list}}
Код:
<?php
$count=0;
foreach($items as $item) {
$count++;
if($count == 1) {
?>
Items
<?php } ?>
<php echo $count;?>)<b><?php echo $item;?></b>
<?php } ?>
<?php if(!$count){ ?>
Nothing
<?php } else { ?>
done!
<?php } ?>
В общем, если вы все еще читаете, то наверное, уже стало понятно что {{foo}} - макрос, а {$foo} - так называемое output expression в терминах MACRO. Написать свой простейший макрос довольно просто, например, создав файл hello.tag.php(в определенной директории) с таким содержанием:
Код:
<?php
/**
* @tag hello
*/
class HelloWorldMacro extends lmbMacroTag
{
function generateContents($code)
{
$code->writePHP('echo "Hello world!";');
}
}
Код:
{{hello}}
В поставке с MACRO, кроме {{list}} идет еще ряд макросов, например, {{include}} и {{wrap}}. Хороший пример всегда лучше кучи нудных речей, поэтому сразу к примерам и перейдем:
page.phtml
Код:
{{wrap with="layout.phtml" into="content"}}
Some contents...
{{/wrap}}
Код:
{{include file="header.phtml"/}}
{{slot id="content"}}
{{include file="footer.phtml"/}}
В принципе, {{include}} макрос можно заменить обычной <?php include(..); ?> вставкой, однако MACRO делает это более оптимально, включая содержимое подключаемого шаблона на этапе компиляции(с оговоркой, если подключаемый файл задается константой, когда же используется динамическое подключение типа {{include file="$some_file"}}, то подключение происходит в runtime).
Если {{include}} имеет довольно простой PHP эквивалент, то {{wrap}} работает намного сложнее и PHP версия будет выглядеть не столь тривиально. Однако и {{wrap}} в случае статического обертывания(т.е когда используется {{wrap with="some_tpl.phtml ..}}) компилируется оптимально в один единственный шаблон. В случае же динамического обворачивания, конечный результат не столь оптимален, но более гибок. Покажу пример:
Код:
$macro = new lmbMacroTemplate("page.phtml");
$macro->set("layout", $layout);
Код:
{{wrap with="$this->layout" into="content"}}
Hello!
{{/wrap}}
Еще несколько слов про output expressions, они поддерживают фильтры, т.е:
Код:
{{$foo|trim|uppercase}}
Код:
<?php echo uppercase(trim($foo));?>
Код:
class UpperFilter extends lmbMacroFilter
{
function getValue()
{
return 'strtoupper(' . $this->base->getValue() . ')';
}
}
Код:
{{$foo.bar.zoo}}
Код:
<?php echo $foo->get('bar')->get('zoo');?>
Из основных возможностей MACRO, пожалуй, все. Собственно, зачем я затеял этот тред: 1) хотелось бы просто услышать мнения людей 2) чисто корыстные цели заинтересовать еще кого-то и, возможно, найти единомышленников
MACRO доступен в Limb3 репозитории и является кандидатом на включение в стандарную поставку пакетов, как только все задуманное будет сделано. А задуманного осталось довольно много: {{pager}} макрос, набор удобных {{form}}, {{input}}, {{textarea}} и проч. макросов.
P.S. Если кто-то интересуется Limb3, возможно спросит, " а как же WACT?". В двух словах, я разочаровался в нем, хотя он пока и является шаблонизатором Limb3 по-умолчанию. Скажем так, MACRO является продолжателем идей WACT, однако в более простой и логичной оболочке. Кстати, в Limb3 уже в данный момент можно использовать одновременно и WACT и MACRO, однако однажды в будущем хотелось бы полностью переключиться на MACRO.