Как установить несколько значений для одного и того же атрибута в tal:attributes с помощью TALES

Я пытаюсь установить несколько классов css для одного элемента.

К сожалению, это не работает, так как возвращается: LanguageError: Duplicate attribute name in attributes.

<ul>
    <li tal:repeat="item mainnav"
        tal:attributes="class 'first' if repeat.item.start else nothing; 
                        class 'last' if repeat.item.end else nothing;
                        class 'active' if item.active else nothing">
        <a tal:attributes="href item.href" tal:content="item.title">title</a>
    </li>
</ul>

Объединение этих трех случаев в одно выражение делает его довольно сложным, поскольку существует 6 различных состояний css:

  • первый + активный
  • первый
  • последний + активный
  • прошлой
  • активный
  • (никто)

Есть 2 возможных решения, о которых я могу думать:

-> проверить каждую встроенную комбинацию:

<ul>
    <li tal:repeat="item mainnav" 
        tal:attributes="
            class 'first active' if (repeat.item.start and item.active) else
                  'first'        if repeat.item.start else
                  'last active'  if (repeat.item.end and item.active) else
                  'last'         if repeat.item.end else
                  'active'       if item.active else nothing">
        <a tal:attributes="href item.href" tal:content="item.title">title</a>
    </li>
</ul>

-> создать метод, который возвращает объединенные классы css

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

Кстати, есть ли хорошие ресурсы и примеры по Chameleon, TALES (кроме http://chameleon.repoze.org/docs/latest)


person roberkules    schedule 07.11.2011    source источник
comment
Вы когда-нибудь получали хороший ответ на этот вопрос? Мне также нужно добавить несколько стилей CSS в класс, используя TAL.   -  person h0st1le    schedule 23.02.2012
comment
Извините, но не. Наконец-то я перешел на MAKO и даже подумываю в ближайшем будущем перейти на Jinja2.   -  person roberkules    schedule 23.02.2012


Ответы (3)


Вы не используете tal:condition, у него есть цель. Мне не нравятся чрезмерно вложенные условные операторы, это никуда не приведет. Не проверял это, но вы можете получить идею.

<ul>
    <tal:myloop tal:repeat="item mainnav">
        <li tal:condition="item.active" tal:attributes="class 
            'active first' if repeat.item.start 
            else 'active last' if repeat.item.end 
            else 'active'">
            <a tal:attribute="href item.href" tal:content="item.title"></a>
        </li>
        <li tal:condition="not item.active" tal:attributes="class 
            'first' if repeat.item.start 
            else 'last' if repeat.item.end else None">
            <a tal:attribute="href item.href" tal:content="item.title"></a>
        </li>
    </tal:myloop>
</ul>
person jules    schedule 04.05.2012
comment
это кажется громоздким решением, так как вам нужно дублировать код. а если возможностей больше? я согласен, что это решило бы мою проблему, но должно быть лучшее решение? - person roberkules; 09.05.2012

Вы можете использовать tal:define несколько раз, чтобы определить различные части строки вашего класса, а затем создать фактический атрибут из этих частей:

<tal:loop repeat="item mainnav">
    <li tal:define="class_first  'first'  if repeat.item.start else '';
                    class_last   'last'   if repeat.item.end else '';
                    class_active 'active' if item.active else '';"
        tal:attributes="class string:$class_first $class_last $class_active">
       <a tal:attributes="href item.href" tal:content="item.title">title</a>
    </li>
</tal>

Это может привести к пустому атрибуту класса, что безвредно.

Что касается дополнительной документации; Chameleon — это реализация TAL, изначально разработанная для шаблонов страниц Zope. Таким образом, вы обнаружите, что много документации для последнего также относится к Chameleon, если вы принимаете во внимание, что модус TALES Chameleon по умолчанию — python:, а ZPT по умолчанию — path:. Глава Расширенные шаблоны страниц книги Zope также относится к Chameleon, например .

person Martijn Pieters    schedule 28.07.2012

В Хамелеоне вы можете:

<ul>
    <li tal:repeat="item mainnav"
        class="${'first' if repeat.item.start else ''}
               ${'last' if repeat.item.end else ''}
               ${'active' if item.active else ''">
        <a tal:attributes="href item.href" tal:content="item.title">title</a>
    </li>
</ul>

[править] А лучше так:

<ul>
    <li tal:repeat="item mainnav"
        class="${('first ' if repeat.item.start else '') +
                 ('last ' if repeat.item.end else '') +
                 ('active' if item.active else '')}">
        <a tal:attributes="href item.href" tal:content="item.title">title</a>
    </li>
</ul>
person bismigalis    schedule 28.01.2013
comment
Работает, но мне пришлось использовать непосредственно item.<property> внутри ${...} вместо префикса repeat, как в repeat.item.<property>. - person Tuukka Mustonen; 23.09.2013