PHP

индекс
206,76

Иной — PHPTAL

Для описания этого очень мощного и одновременно лаконичного шаблонизатора просто скопирую текст из мана
«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
+5
1 декабря 2009, 14:44
30

комментарии (39)

–2
crazyprog #
Великолепная вещь!!1 А с ORM как прекрасно будет работать.
+2
standov #
да, действительно великолепно — использую с Propel
+6
magnit #
native php похоже не начальный уровень программиста, а конечный
0
standov #
у натива есть 2 огромных минуса:
1. сделанный шаблон (я имею в виду с кодом уже) на доработку верстальщику не вернешь
2. В мешанине html и php сложно ориентироваться — нужная «точка» в TAL шаблоне очень легко находится глазами
+4
magnit #
1. вот так всегда, верстальщиков за людей не держат
2. смотря как смешать.
0
standov #
1. отнюдь, просто я например не вмешиваюсь в работу верстальщика — я не шарю так как он во всех премудростях и так-же не хочу что-бы он вмешивался в мою работу — вот тут разделение и рулит
2. да как не смешай, сейчас один из проектов на ZF c нативными шаблонами, когда перехожу на тал в других проектах — отдыхаю душой и телом, попробуйте.
0
magnit #
1. с помощью нейтив эта задача решается вполне
2. как я на нейтив отдыхаю от XSLT кто бы знал
–1
standov #
XSLT вещь безусловно крайне мощная но очень неповоротливая и достаточно медленная в реализациях
0
magnit #
но в целом я не против
не холивара ради
+1
nayjest #
Т. е. после вставки инструкций phpTal верстка как правило не разлазится (на практике, вы много делали на нем шаблонов)?
Хм, если так, то это конечно же очень хороший аргумент в пользу такого синтаксиса, т. к. чисто визуально лично я нахожу более приятным что-то такое:

<div id="content">

   <h1>%header%</h1>

   <div>
     %content%
   </div>

   <b>Теги.i18n</b>
   %foreach tags as tag:%
     %tag|escape%
     %separator:%, %end%
   %end%
   <br/>

   <b>'Дата публикации'.i18n</b>
   %format(date,'D M Y')%

</div>


Что вы думаете по этому поводу?
0
standov #
извините, я не понял ваш пример, какой участок xhtml верстки тут итерируется?
Да, я достаточно много сделал шаблонов на TALе
0
kurokikaze #
Интересная штука :)
0
resurtm #
Когда смотрел PHPTAL появилось стойкое ощущение упрощённой lightweight версии XSLT. :) А так отличная штука.
0
standov #
в общем да, так и есть, даже область видимости переменных распространяется на узел только XSLT работает с XML а TAL c переменными
0
aps #
Шаг.1 Нативный php
Шаг.2 Нативный php заменяются на {макросы}
Шаг.3 {макросы} заменяются на XML

Когда php-программисты дойдут до логического конца?
–1
standov #
а какой конец? XML+XSLT дык дошли и прошли, затык в производительности и цене XSLT специалиста
+1
aps #
>затык в производительности и цене
И то и другое так часто обсуждалось, что как-то даже неинтересно.
Лучше всего здесь habrahabr.ru/blogs/about_cms/22018/ (Дискуссия разработчиков UMI и Bitrix)

>а какой конец? XML+XSLT
Я вас за язык не тянул :)
0
standov #
я говорю о своем опыте а в приведенной вами статье человек пишет маркетинговые лозунги не подтверждая фактами.

В общем, если вас устраивает XSLT — замечательно, технология действительно мощная но я для view его применить успешно не смог.
0
aps #
Как-то не заметил маркетинговых лозунгов. Да и смысла упираться Котыреву нет. В его UMI кроме XSLT имеет традиционный шаблонизатор.
Вопрос с производительностью — не вопрос при правильной архитектуре проекта.
Вопрос с кадрами — не знаю. Мои наблюдения совпадают с котыревскими. За месяц нормального верстальщика вполне можно обучить работать с XSLT на более-менее приемлемом уровне.
–1
standov #
мои наблюдения не совпадают, для вещей в которых xslt имеет преимущества (ключи и группировки) вы верстальщика и за 6 месяцев не обучите поскольку это чистой воды программинг — он уволится. а без этого юзать xslt с предварительным преобразованием данных в XML — это как-то не оправдано мне кажется.
Для меня тал это как-раз та золотая середина — почти xslt только без XML преобразования и «лишних» и навороченных штук
0
aps #
Может вы и правы. На хабре каждый второй «девелопер» выступает за неподдержку IE6. Таким уродцам за полгода ключи действительно не освоить. Просто мне везло с верстальщиками.
0
standov #
угу, меня — программера по сути и, как я считаю, достаточно опытного :) при словах «группировка Мюнча» начинает типать, группировка описание которой в хорошей книге сопровождается словами «вы все равно не поймете, поэтому просто запомните» осваивать верстальщику.

Объем достойной книги по технологии XSLT порядка 800 страниц и все эти 800 засалены поскольку постоянно к ним обращаешься — вот мой опыт общения с XSLT, очень красиво, чертовски мощно но также и тяжело для хорошего понимания.
0
aps #
>при словах «группировка Мюнча» начинает типать
А меня всякий раз, когда приходится учить очередной шаблонизатор, который «намного лучше Smarty» :)
Но метод Мюнха я действительно просто вызубрил наизусть. Правда не помню, когда последний раз его использовал.
0
standov #
вот я так не могу, если я чего-то не понимаю в том что использую — плохо сплю, я согласен про новый шаблонизатор, я никого не призываю пересаживаться особенно если все устраивает, это скорее для тех кто в поиске либо кто подыскивает технологию для фреймворка, cms как я когда-то.
0
aps #
>я никого не призываю пересаживаться
Тут дело не в насильной пересадке, а в том что нет единого стандарта. В каждой команде php-разработчиков свои вкусы, в каждой CMS свой шаблонизатор.
Поэтому и зверею и спасение вижу только в общепринятом стандарте.
Накладные расходы конечно есть. Но при миграции верстальщика (а я >11 лет верстаю) лучше иметь под рукой стандарт.
0
standov #
полностью согласен, для меня именно этот шаблонизатор привлекателен еще и тем что это тоже почти стандарт :)
Zope это почти икона (пусть и не очень удачным названием :)) — wiki.zope.org/ZPT/TALSpecification14
0
aps #
>именно этот шаблонизатор привлекателен еще и тем что
>еще и тем что это тоже почти стандарт
И приверженцы Smarty такого же мнения, и у любого другого также 1000 аргументов. А стандарт то только один. И только он включен в PHP5+

>Zope это почти икона
Первый раз я сталкнулся (в качестве верстальщика) с XSLT на Java проекте. Основательно выучил на .NET А уж потом на своих собственных PHP-проектах внедрил.
Вряд ли я единственный кому приходится мигрировать из команды в команду. И работать в нескольуих средах параллельно. Как бы хорош не был Tal — это при таком раскладе не выход.
Я начал с того что все идет к логическому концу. Оно к нему и придет.
Бардак в области разработок среди php-программистов рано или поздно закончится. Придут к единому стандарту. Или двум-трем :)
0
egorinsk #
Что-то у меня сомнения, что он генерирует хороший php на выходе, тут эти теги в код так просто не преобразуешь. И да, синтаксис адский.
0
egorinsk #
Хотя, вещь, надо признать, интересная, а ограничения, типа «все в аттрибутах» добавляют строгости и уменьшают ошибки.

Но ничего такого, что нельзя сделать в других шаблонизаторах, тут нет,
0
standov #
ну наследование реализовано далеко не во всех шаблонизаторах, а вообще да, ничего нового но то что нужно делает красиво и непринужденно
0
standov #
попробуйте, по другому я ответить не могу
0
galk_in #
Меня зацепили Ваши слова, Ваш верстальщик не школьник.
В защиту верстальщиков-школьников.
По моему глубокому убеждению верстку должны делать верстальщики, а программировать программисты. Поэтому вопрос, standov, вы написали это статью как верстальщик или программист??? Вы же сделали не один шаблон, поэтому должны понимать и тех и других.
Я понимаю что Вам нравиться эта технология, но она для тех людей которые и программируют и делают верстку. А это экономически не правильно. Попробую объяснить почему я так считаю.
Точно так же как есть ModelViewController, есть ДизайнВерсткаПрограммирование и именно верстка это наименее оплачиваемая часть. Или Вы хотите, что бы верстальщик получал за час своего времени столько же сколько программист? Это у Вас так происходит, потому что Вы так работаете. Но это не значит, что это правильно. Разделение труда, вот к чему приходят все так или иначе.
Поймите, очень трудно найти хороших верстальщиков на адекватную зарплату. Приходится брать студентов-школьников о которых Вы так пренебрежительно отзываетесь в статье. Или по вашему кто-то отучившись 5 лет в универе, поучаствовав в десятке проектов идет работать верстальщиком?

0
standov #
да, я абсолютно с вами согласен во всем кроме «но она для тех людей которые и программируют и делают верстку»
я не верю в безшовную конвергенцию всего, я получаю от верстальщика XHTML верстку ни больше ни меньше, я уважаю его труд — сам я не способен на такое по причине ориентации на другое — я даже думаю не так, и вот моя задача имея результат работы верстальщика с минимальными моими затратами (читайте с максимальной экономической целесообразностью) привести его верстку в формат доступный фреймворку, cms и т.п., приведя в этот формат и обнаружив вдруг ошибку в верстке (при определенных обстоятельствах этот див налазит на этот) я отдаю результат уже моей работы обратно верстальщику, он правит и я с усилиями равными проверке на «не тронутость» tal разметки реинтегрирую новую версию в конечный продукт — вот она максимальная эффективность в моем понимании, в чем я заблуждаюсь?
0
standov #
знаете, я не верю что из верстальщика может получится программист как и из дизайнера и нового направления — фронтенд девелопера и, соответственно, наоборот. я работал с гениальными верстальщиками, гениальными фронтами, гениальными девами — никто не претендует на хлеб друг-друга по причине разного склада ума и разного мышления, я не говорю «лучше-хуже» он просто разный
+1
aps #
>Или по вашему кто-то отучившись 5 лет в универе,
> поучаствовав в десятке проектов идет работать верстальщиком?
Я например. В основном работаю как верстальщик и фронт-енд программист.
На PHP (до того PERL) программирую только свои собственные проекты, или когда в конторе затык и все программисты заняты. Как сейчас.
0
crazyprog #
>Или по вашему кто-то отучившись 5 лет в универе,
> поучаствовав в десятке проектов идет работать верстальщиком?

0
crazyprog #
А я лично видел такого человека — вполне адекватную верстку делал. Более того, он учился и работал, закончил институт, еще проработал пол года и ушел в другую контору опять же верстальщиком. Занимался ТОЛЬКО версткой и немного JS.
0
xaxoxy #
PHPTAL отличается от XSLT так же, как Smarty от блочных шаблонизаторов.

здесь не используется XSL файл для задания логики.

я бы выделил данный шаблонизатор в отдельную группу шаблонизаторов (TAL).
0
meglio #
Абсолютно поддерживаю автора статьи и подтверждаю великолепие PHPTAL.
Сам использую уже несколько лет.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.