Для описания этого очень мощного и одновременно лаконичного шаблонизатора просто скопирую текст из мана
«PHPTAL is an implementation of the excellent Zope Page Template (ZPT) system for PHP. PHPTAL supports TAL, METAL, I18N namespaces» и «PHPTALES is the equivalent of TALES, the Template Attribute Language Expression Syntax. It defines how XML attribute values are handled»
Предлагается по LGPL лицензии тут http://phptal.org/.
Я делаю шаблоны на PHPTAL уже около года и считаю его «феерическим» :). В коде есть пара моих патчей, поэтому я знаю тему изнутри.
Далее я сделаю обзорную статью из которой вы точно поймете что я не писатель и почему всячески противился просьбам хабражителей «раскрыть тему» ну и надеюсь хоть чуть-чуть популяризирую данный шедевр.
Шаблоны TAL, и PHPTAL соответственно тоже, это XML документы, причем жестокие и настоящие а не «там где угловые скобочки».
Тут вам и сущности и CDATA-секции и, не поверите, XML-декларация.
Чем это хорошо?
Это дисциплинирует — у вас никогда не останется не закрытых тегов из-за которых «вдруг» поедет верстка, шаблонизатор просто не пропустит такое безобразие.
Наверное нет редактора кода не понимающего XML формат.
Ваш верстальщик не школьник.
Чем это плохо?
Ваш верстальщик не школьник, да я помню что это было в плюсах, но теперь за 10 баксов вам табличками в фронтпейдже не сверстают
Реализация IE хаков может выводить из себя (в конце один из примеров)
Inline-JS лучше оформлять как CDATA секции, ну или делать «по взрослому» в отдельных js файлах.
Кое-кому прийдется почитать книгу про XML, не уверен что это плохо.
Вся мощь TAL скрыта в атрибутах, в спецификации описать ровно 1 (один) элемент, и тот, как сказано в спеке «является синтаксическим сахаром», и без него можно вполне обойтись. Поэтому говорим TAL имеем в виду атрибуты.
Чем это хорошо — ровно всем, когда Вы получаете от верстальщика XHTML верстку она уже является шаблоном TAL, дальше будут только его итеративно «натягивать», именно в TAL «натягивать шаблон» очень точно характеризует процесс.
В упомянутой спеке на PHPTAL описано аж 18 служебных атрибутов, из которых добрую половину Вы никогда не будуте использовать.
Далее очень кратко пройдусь по действительно важным и используемым — описания буду давать кодом:
Обычные константы имеют область видимости ограниченную тегом в котором они определены, эта фича походу из xslt и позволяет избежать пересечения по именам.
Глобальные константы действуют на весь поток обработки шаблона, я пишу поток а не шаблон поскольку шаблоны могут быть наследуемыми и тогда при обработке одного, на самом деле обрабатывается цепочка шаблонов.
Пример когда глобальные константы сильно «доставляют» — в конце топика.
Тут список топиков с опуиональными ссылками на «more» и зеброй.
Тема зебры раскрыта в официальном мане phptal.org/manual/ru/split/tal-attributes.html
При полной обвязке шаблонизатора, в данном шаблоне текст «Read more» будет переводится транслейтором (gettext по умолчанию)
Эти 4 атрибута реализуют наследование шаблонов, далее работаем c home.html шаблоном, который наследует общий для всех базовый layout:
home.html
layout.html
Описанных 10 атрибутов достаточно для начала работы, остальные 8 хорошо описаны в мане
Как Вы могли заметить выше, выражения записываются в спец-формате, общий формат выражения:
В PHPTAL определены 5 типов выражений (path, php, string, not, exists), в оригинальном TAL php заменяется на python.
Каждый тип тейлов, а именно так именуются выражения, опеределяет формат, все хорошо описано в мане, остановлюсь только на базовом path.
Тейл path сделан очень похожим на XPath синтаксис, и знакомым с ним он будет очень удобен, так выражение:
Анализатор path тейлов автоматически пытается вызывать соответствующие методы, члены и ключи массивов в порядке приоритетности из мана.
PHPTAL предумасматривает что разработчик будет дописывать сам нужные ему тейлы, тем самым расширяя фукционал.
Глобальные константы бывают очень удобны, наиболее характерный пример – заголовок страницы. Теперь вы можете определять его в любом месте.
layout.html
home.html
В указанном примере именно home.html шаблон используется для вывода, а давно написанный layout.html используется для однообразного обрамления, но даже в таком случае вы можете им управлять, в частности динамически выводить заголовок, например по названию поста блога из БД
Данный пример несколько перекликается с предыдущим но реализован иначе, допустим на нужно иметь возможность в наследущем шаблоне добавлять ресурсы (css js в head секцию лайоута):
layout.html
home.html
Тут пример как писать JS не опасаясь служебных символов.
json: это мой самописный тейл который мапит переменную в JS код :)
Не всегда удобно пользоваться online версией. Вместе с исходниками шаблонизатора поставляется переведенная процентов на 50 docbook книга, все что вам останется – переконвертить ее в удобный формат. Используя инструменты доступные тут http://docbook.sourceforge.net/ можно получить даже chm, а при определенной сноровке и свободном времени и pdf.
PHPTAL, как и смарти и многие другие, генерирует PHP-runtime код и работает уже с ним, код очень качественный и не избыточный за счет этого скорость очень и очень хорошая —
http://fabien.potencier.org/article/34/templating-engines-in-php
«PHPTAL is an implementation of the excellent Zope Page Template (ZPT) system for PHP. PHPTAL supports TAL, METAL, I18N namespaces» и «PHPTALES is the equivalent of TALES, the Template Attribute Language Expression Syntax. It defines how XML attribute values are handled»
Предлагается по LGPL лицензии тут http://phptal.org/.
Я делаю шаблоны на PHPTAL уже около года и считаю его «феерическим» :). В коде есть пара моих патчей, поэтому я знаю тему изнутри.
Далее я сделаю обзорную статью из которой вы точно поймете что я не писатель и почему всячески противился просьбам хабражителей «раскрыть тему» ну и надеюсь хоть чуть-чуть популяризирую данный шедевр.
XML-синтаксис
Шаблоны TAL, и PHPTAL соответственно тоже, это XML документы, причем жестокие и настоящие а не «там где угловые скобочки».
Тут вам и сущности и CDATA-секции и, не поверите, XML-декларация.
Чем это хорошо?
Это дисциплинирует — у вас никогда не останется не закрытых тегов из-за которых «вдруг» поедет верстка, шаблонизатор просто не пропустит такое безобразие.
Наверное нет редактора кода не понимающего XML формат.
Ваш верстальщик не школьник.
Чем это плохо?
Ваш верстальщик не школьник, да я помню что это было в плюсах, но теперь за 10 баксов вам табличками в фронтпейдже не сверстают
Реализация IE хаков может выводить из себя (в конце один из примеров)
Inline-JS лучше оформлять как CDATA секции, ну или делать «по взрослому» в отдельных js файлах.
Кое-кому прийдется почитать книгу про XML, не уверен что это плохо.
Атрибуты
Вся мощь TAL скрыта в атрибутах, в спецификации описать ровно 1 (один) элемент, и тот, как сказано в спеке «является синтаксическим сахаром», и без него можно вполне обойтись. Поэтому говорим TAL имеем в виду атрибуты.
Чем это хорошо — ровно всем, когда Вы получаете от верстальщика XHTML верстку она уже является шаблоном TAL, дальше будут только его итеративно «натягивать», именно в TAL «натягивать шаблон» очень точно характеризует процесс.
В упомянутой спеке на PHPTAL описано аж 18 служебных атрибутов, из которых добрую половину Вы никогда не будуте использовать.
Далее очень кратко пройдусь по действительно важным и используемым — описания буду давать кодом:
tal:define, tal:content
<div tal:define="global title obj/getTitle; content obj/getContent"> <div class="post_title" tal:content="title" >Lorem ipsum</div> <div class="post_content" tal:content="content" >Lorem ipsum</div> </div>
Обычные константы имеют область видимости ограниченную тегом в котором они определены, эта фича походу из xslt и позволяет избежать пересечения по именам.
Глобальные константы действуют на весь поток обработки шаблона, я пишу поток а не шаблон поскольку шаблоны могут быть наследуемыми и тогда при обработке одного, на самом деле обрабатывается цепочка шаблонов.
Пример когда глобальные константы сильно «доставляют» — в конце топика.
tal:condition, tal:repeat, tal:attributes, i18n:translate
<div tal:repeat="post posts" tal:attributes="class php:repeat.post.odd ? 'odd' : NULL"> <div class="post_title" tal:content="post/getTitle" >Lorem ipsum</div> <div class="post_content" tal:content="post/getContent" >Lorem ipsum</div> <a class="post_cut" tal:condition="post/hasMore" i18n:translate="">Read more</a> </div>
Тут список топиков с опуиональными ссылками на «more» и зеброй.
Тема зебры раскрыта в официальном мане phptal.org/manual/ru/split/tal-attributes.html
При полной обвязке шаблонизатора, в данном шаблоне текст «Read more» будет переводится транслейтором (gettext по умолчанию)
metal:define-macro, metal:use-macro, metal:define-slot, metal:fill-slot
Эти 4 атрибута реализуют наследование шаблонов, далее работаем c home.html шаблоном, который наследует общий для всех базовый layout:
home.html
<?xml version="1.0"?> <tal:block metal:fill-slot="custom-js" > <script rel="stylesheet" src="/mootools-1.2-fx.js" type="text/javascript" /> </tal:block> <tal:block metal:fill-slot="custom-css" > <style type="text/css" media="all"> @import url(<tal:block tal:content="/main.css" />); </style> </tal:block> <tal:block metal:use-macro="layout/page" > <body metal:fill-slot="body" tal:define="global title post/getTitle"> <div tal:content="post/getContent" >Post content text</div> </body> </tal:block>
layout.html
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html metal:define-macro="page" xmlns="http://www.w3.org/1999/xhtml"> <head > <title tal:content="title | default">PHPTAL global title example</title> <tal:block metal:define-slot="meta" > <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="generator" content="velocity framework" tal:attributes="content generator | default" /> <meta name="description" tal:condition="exists: description" content="${description}" /> <meta name="keywords" tal:condition="exists: keywords" content="${keywords}" /> </tal:block> <script rel="stylesheet" src="/mootools-1.2-core.js" type="text/javascript" /> <tal:block metal:define-slot="custom-js" /> <style type="text/css" media="all"> @import url(<tal:block tal:content="/main.css" />); </style> <tal:block metal:define-slot="custom-css" /> </head> <body metal:define-slot="body">Lorem ipsum</body> </html>
Еще
Описанных 10 атрибутов достаточно для начала работы, остальные 8 хорошо описаны в мане
Тейлы
Как Вы могли заметить выше, выражения записываются в спец-формате, общий формат выражения:
prefix:выражение
, если префикс не определен он считается равным «path»В PHPTAL определены 5 типов выражений (path, php, string, not, exists), в оригинальном TAL php заменяется на python.
Каждый тип тейлов, а именно так именуются выражения, опеределяет формат, все хорошо описано в мане, остановлюсь только на базовом path.
Тейл path сделан очень похожим на XPath синтаксис, и знакомым с ним он будет очень удобен, так выражение:
obj/getObject2/path
эквивалентно $obj->getObject2()->path;
.Анализатор path тейлов автоматически пытается вызывать соответствующие методы, члены и ключи массивов в порядке приоритетности из мана.
PHPTAL предумасматривает что разработчик будет дописывать сам нужные ему тейлы, тем самым расширяя фукционал.
Приемы и примеры
Глобальные константы
Глобальные константы бывают очень удобны, наиболее характерный пример – заголовок страницы. Теперь вы можете определять его в любом месте.
layout.html
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html metal:define-macro="page" xmlns="http://www.w3.org/1999/xhtml"> <head > <title tal:content="title | default">PHPTAL global title example</title> <tal:block metal:define-slot="meta" > <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="generator" content="velocity framework" tal:attributes="content generator | default" /> <meta name="description" tal:condition="exists: description" content="${description}" /> <meta name="keywords" tal:condition="exists: keywords" content="${keywords}" /> </tal:block> </head> <body metal:define-slot="body"> </html>
home.html
<?xml version="1.0"?> <tal:block metal:use-macro="layout/page" > <body metal:fill-slot="body" tal:define="global title post/getTitle"> Page body </body> </tal:block>
В указанном примере именно home.html шаблон используется для вывода, а давно написанный layout.html используется для однообразного обрамления, но даже в таком случае вы можете им управлять, в частности динамически выводить заголовок, например по названию поста блога из БД
Наследуемый вывод подключаемых ресурсов
Данный пример несколько перекликается с предыдущим но реализован иначе, допустим на нужно иметь возможность в наследущем шаблоне добавлять ресурсы (css js в head секцию лайоута):
layout.html
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html metal:define-macro="page" xmlns="http://www.w3.org/1999/xhtml"> <head > <script rel="stylesheet" src="/mootools-1.2-core.js" type="text/javascript" /> <tal:block metal:define-slot="custom-js" /> <style type="text/css" media="all"> @import url(<tal:block tal:content="/main.css" />); </style> <tal:block metal:define-slot="custom-css" /> </head> <body metal:define-slot="body"> </html>
home.html
<?xml version="1.0"?> <tal:block metal:use-macro="layout/page" > <tal:block metal:fill-slot="custom-js" > <script rel="stylesheet" src="/mootools-1.2-fx.js" type="text/javascript" /> </tal:block> <tal:block metal:fill-slot="custom-css" > <style type="text/css" media="all"> @import url(<tal:block tal:content="/main.css" />); </style> </tal:block> <body metal:fill-slot="body" > Page body </body> </tal:block>
Inline JS
<script type="text/javascript"> //<![CDATA[ var $var = ${json:var}; // поскольку это CDATA можно юзать угловую скобку if ($var < 1) { // bla....bla } //]]> </script>
Тут пример как писать JS не опасаясь служебных символов.
json: это мой самописный тейл который мапит переменную в JS код :)
Документация
Не всегда удобно пользоваться online версией. Вместе с исходниками шаблонизатора поставляется переведенная процентов на 50 docbook книга, все что вам останется – переконвертить ее в удобный формат. Используя инструменты доступные тут http://docbook.sourceforge.net/ можно получить даже chm, а при определенной сноровке и свободном времени и pdf.
Производительность
PHPTAL, как и смарти и многие другие, генерирует PHP-runtime код и работает уже с ним, код очень качественный и не избыточный за счет этого скорость очень и очень хорошая —
http://fabien.potencier.org/article/34/templating-engines-in-php