Идеальный шаблонизатор

Статус
В этой теме нельзя размещать новые ответы.

Dagdamor

Новичок
dark-demon
Да. Он по умолчанию не экранирует выводимые данные.

-~{}~ 14.10.07 21:06:

*****
гостевая книга. стоит на двух сайтах. с разным дизайном, разумеется.
скрипт патчится (на предмет безопасности, к примеру), и заливается на оба этих сайта
Да. Либо, как вариант, у одного сайта есть небор из нескольких дизайнов (скинов), и посетитель может выбирать, что ему больше приглянется.
 

dark-demon

d(^-^)b
Dagdamor, о каком экранировании идёт речь? пример!

-~{}~ 14.10.07 18:13:

меня тут кстати посетила мысль.. написать xslt на xslt (аналогично всем известному php на php) :D
 

Dagdamor

Новичок
dark-demon
Я об обработке строк функцией htmlspecialchars() перед выводом.
Гм. Виноват. По умолчанию данные экранируются.
Ладно, другой пример: вывод простейшей таблицы. В том же Смарти пример будет выглядеть так:

Код:
<table>
{foreach from=$data item=item}
<tr>
  <td>{$item.field1}</td>
  <td>{$item.field2}</td>
<tr>
{/foreach}
</table>
В случае XSLT спецтегов будет больше...
 

dark-demon

d(^-^)b
Код:
<table>
    <t:for-each select="data/item" >
        <tr>
            <td><t:value-of select="field1" /></td>
            <td><t:value-of select="field2" /></td>
        <tr>
    </t:for-each>
</table>
единственное реальное усложнение - использование value-of, но можно намутить что-нибудь такое:
Код:
<td><v:field1 /></td>
<td><v:field2 /></td>
-~{}~ 14.10.07 18:38:

как вам такой шаблон?

Код:
<div class="menu" x="tree">
    <div class="caps"><x:text value="{@title}" /></div>
    <ul>
        <li x="branch">
            <a href="{@href}" x="leaf">
                <x:text value="{@title}" />
            </a>
        </li>
    </ul>
</div>
 

Dagdamor

Новичок
dark-demon
Все же это смотрится не так опрятно... и непонятно, как быть в случае двух вложенных друг в друга итераторов, если внутри второго нужно вывести данные от первого.

как вам такой шаблон?
Совершенно нечитабелен :)
 

dark-demon

d(^-^)b
Dagdamor, в xpath можно обратиться к предку используя две точки, кроме того всегда можно ввести именованные переменные...

-~{}~ 14.10.07 18:45:

Dagdamor, а какой шаблон дерева является читабельным?
 

Dagdamor

Новичок
dark-demon
Что-нибудь наподобие (branch.tpl):
Код:
<ul>
  {foreach from=$items item=item}
  <li>{$item.title} {include file='branch.tpl' items=$item.children}</li>
  {/foreach}
</ul>
 

dark-demon

d(^-^)b
Dagdamor, это пока нам не нужно различать листья и ветви...

допустим листья должны быть ссылками, а заголовки ветвей должны быть обычным текстом, но выделенным особым образом ( class="caps" будет достаточно )

у меня получилось так:
PHP:
<div class="menu">
    <ul>
        <x:tree select="menu">
            <x:branch>
                <li class="j-off">
                    <div class="caps">
                        <x:text select="@title" />
                    </div>
                    <ul>
                        <apply:branch />
                    </ul>
                </li>
            </x:branch>
            <x:leaf>
                <li>
                    <a href="{@href}">
                        <x:text value="{@title}" />
                    </a>
                </li>
            </x:leaf>
        </x:tree>
    </ul>
</div>
класс j-off используется для индикации, что меню свёрнуто
 

Dagdamor

Новичок
dark-demon
Это тоже можно сделать:
PHP:
<ul>
  {foreach from=$items item=item}
  {if $item.children}
  <li>
    <span class="caps">{$item.title}</span>
    {include file='branch.tpl' items=$item.children}
  </li>
  {else}
  <li><a href="{$item.link}">{$item.title}</a></li>
  {/if}
  {/foreach}
</ul>
 

dark-demon

d(^-^)b
только не говори, что твой код более читабелен.
особенно прикалывает магическое "item=item"
 

Dagdamor

Новичок
dark-demon
Ну, с этим я согласен. Если усложнять задачу, то любой вариант станет одинаково нечитабельным.
 

dark-demon

d(^-^)b
основной недостаток в том, что ты разрываешь шаблон вывода меню на два (причём вынося второй в отдельный файл): шаблон вывода меню и шаблон вывода его внутренностей.
у меня же подряд идут два подшаблона: вывод ветви и вывод листа

-~{}~ 14.10.07 19:48:

> Если усложнять задачу, то любой вариант станет одинаково нечитабельным.

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

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

Dagdamor

Новичок
dark-demon
Вообще-то рекурсия по всех учебниках - наоборот, пример наглядности :) но не буду спорить. И так зафлудили тему ;)
 

dark-demon

d(^-^)b
проблема не в рекурсии ( у меня она тоже есть ), а в том, что рекурсивный блок выносится в отдельный файл.

-~{}~ 14.10.07 20:15:

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

atv

Новичок
Для начала определимся на берегу, что идеальный шаблонизатор это элемент "View" парадигмы MVC.
Идеальный шаблонизатор не должен быть привязяан к какой -то конкретной парадигме.

Базовая функциональность шаблонизатора:

- подстановка переменных
- условное ветвление
- организация циклов
- включение другого шаблона
- вызов функциональных модулей (для активных шаблонов)

Вряд ли кто-то будет оспаривать данный список.
Bakti9rov привёл более правильный список:
а) шаблонные сущности
б) шаблонная разметка (блоки, "теги") и
в) шаблонные правила, которые в зависимости от разметки преобразуют шаблон.
Но оказалось, что кроме функционального кода, существует еще код представления.
В Event Driven подходе логика представления красиво укладывается в событие "onShow" объектов, в котором меняется какой нибудь атрибут объекта, например "class". А уже для каждого значения атрибута дизайнер пишет шаблон и CSS стиль. И всё!

Напомню, что образец идеального шаблона будет иметь примерно такой вид:
Не согласен с таким примером. Не забывайте, что вся структура документа представляет собой дерево, наиболее удачное и гибкое решение предоставляет XSLT:
Код:
<xsl:template match="tree">
  <ul>
    <xsl:apply-templates />
  </ul>
</xsl:template>

<xsl:template match="item">
  <li>
    <xsl:apply-templates />
  </li>
</xsl:template>
Обратите внимание - xsl:apply-templates, вот тот элемент абстрактности (и не единственный), который делает XSLT таким гибким и позволяет увеличить коэффициент повторно используемого кода.

Для примера с таблицей не нужно никаких вложенных циклов, просто добавляется ещё один шаблон:

Код:
<xsl:template match="table">
  <table>
    <xsl:apply-templates />
  </table>
</xsl:template>

<xsl:template match="row">
  <tr>
    <xsl:apply-templates />
  </tr>
</xsl:template>

<xsl:template match="cell">
  <td>
    <xsl:apply-templates />
  </td>
</xsl:template>
XSLT наиболее близок к идеальному шаблонизатору, вот только если б не этот синтаксис :-(

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

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

Да все нормально, это ж оффтоп Просто по-моему ты пока единственный, кто понял как работает MACRO.
А ты похоже не единственный, кто не понял требований к шаблонизатору :)

Ты всё-таки попробуй вплотную поработать с XSLT, не обращая внимания на синтаксис.
 

pachanga

Новичок
А ты похоже не единственный, кто не понял требований к шаблонизатору :)
Да куда уж нам...

Ты всё-таки попробуй вплотную поработать с XSLT, не обращая внимания на синтаксис.
Спасибо, на XML я уже напрограммировался.
 

dark-demon

d(^-^)b
atv, плохие примеры :) ты фактически заменяешь table/tr/td на table/row/cell, что не имеет никакого смысла.
 

Dagdamor

Новичок
atv
Чем больше я вижу примеров по XSLT, тем сильнее складывается впечатление, что от этой технологии надо держаться подальше ;)

Для примера с таблицей не нужно никаких вложенных циклов, просто добавляется ещё один шаблон:
И как будет происходить отображение? В твоем примере я не вижу даже использования исходных данных. Мое требование №1 к идеальному шаблонизатору - шаблон должен быть простым и интуитивно понятным. В Смарти, в Macro это так, там ничего не усложняется сверх меры. А в XSLT порой идет просто какой-то сюрреализм, как например здесь.

Кстати говоря, HTML и XML - не единственные типы данных, которые приходится генерировать при помощи шаблонизатора. Иногда приходится генерировать plain text - например, для почтовых уведомлений. Просто к слову :)

а) шаблонные сущности
б) шаблонная разметка (блоки, "теги") и
в) шаблонные правила, которые в зависимости от разметки преобразуют шаблон.
А зачем шаблон как-то преобразовывать? Дайте вы дизайнеру возможность изначально задать шаблон таким, каким он будет в результате. Пусть лишь динамические данные подставляются где нужно. Не усложняйте вещи.
 

CatManZero

Новичок
Автор оригинала: Dagdamor
atv
В твоем примере я не вижу даже использования исходных данных. Мое требование №1 к идеальному шаблонизатору - шаблон должен быть простым и интуитивно понятным. В Смарти, в Macro это так, там ничего не усложняется сверх меры. А в XSLT порой идет просто какой-то сюрреализм, как например здесь.
Ну можно и попонятнее составлять шаблоны. Например так:
PHP:
<table>
<xsl:for-each select="/site/news/row">
  <tr>
<!-- заголовок новости -->
     <td><xsl:value-of select="topic"/></td>
  </tr>
  <tr>
<!-- текст новости -->
     <td><xsl:value-of select="text"/></td>
  </tr>
</xsl:for-each>
</table>
А если ещё и прокоментировать код, то при последующей правке верстки в большинстве случаев вообще становится пофиг какой шаблонизатор используется.
Кстати говоря, HTML и XML - не единственные типы данных, которые приходится генерировать при помощи шаблонизатора. Иногда приходится генерировать plain text - например, для почтовых уведомлений. Просто к слову :)
Возможности XSLT не ограничиваются XML и HTML. Ему и генерация rtf-документа под силу. Это тоже так к слову :)
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху