如何使用 TALES 在 tal:attributes 中为同一属性设置多个值

发布于 2024-12-14 13:30:28 字数 1579 浏览 1 评论 0原文

我正在尝试在一个元素上设置多个 css 类。

不幸的是,这不起作用,因为它返回: LanguageError: Duplicate attribute name in attribute.

<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>

将这 3 种情况合并到一个表达式中会使事情变得非常复杂,因为有 6 种不同的 CSS 状态 em>:

  • 第一个+活动
  • 第一个
  • 最后一个+活动
  • 最后一个
  • 活动
  • (无)

我能想到有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类的方法

现在,是否有更好的方法,如果没有,这两种方法中哪一种更好(可能是后一种,就好像它变得更加复杂,内联脚本将变得不可读/无法管理)。

顺便说一句,是否有关于 ChameleonTALES 的任何好的资源和示例(除了 http://chameleon.repoze.org/docs/latest)

I'm trying to set multiple css classes on one element.

Unfortunately this doesn't work, as it returns: 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>

Combining those 3 cases into one expression makes it quite complicated, because there are 6 different css states:

  • first + active
  • first
  • last + active
  • last
  • active
  • (none)

There are 2 possible solutions that I can think of:

-> check each combination inline:

<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>

-> create a method that returns the combined css classes

Now, is there a better approach and if not, which of those 2 is better (probably the latter one, as if it gets more complicating the inline script will become unreadable/unmanageable).

BTW, are there any good resources and examples about Chameleon, TALES (other than http://chameleon.repoze.org/docs/latest)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

等你爱我 2024-12-21 13:30:28

您可以多次使用 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,只要您考虑到 Chameleon 的默认 TALES 模式是 python:,而 ZPT 默认为 path : 相反。例如,Zope Book 的高级页面模板章节也适用于 Chameleon 。

You can use tal:define multiple times to define the various parts of your class string, then construct the actual attribute from those parts:

<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>

This could result in an empty class attribute, which is harmless.

As for additional documentation; Chameleon is an implementation of TAL, originally developed for Zope Page Templates. As such, you'll find a lot of documentation for the latter also applies to Chameleon, as long as you take into account that Chameleon's default TALES modus is python:, while ZPT defaults to path: instead. The Advanced Page Templates chapter of the Zope Book applies to Chameleon as well, for example.

心凉怎暖 2024-12-21 13:30:28

在变色龙中你可以这样做:

<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>

In Chameleon you can do:

<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>

[Edit]
Or better like this:

<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>
泪痕残 2024-12-21 13:30:28

您没有使用 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>

You're not using tal:condition, it has a purpose. I don't like overly nested conditionals, gets you no where.
Haven't tested this but you may get the idea.

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文