4

I am just getting started with pyramid and chameleon templates.

I have the following code example that renders a site menu.

<li tal:repeat="menu view.site_menu">
    <tal:block tal:condition="menu.current">
        <span>${menu.title}</span>
    </tal:block>
    <tal:block tal:condition="not menu.current">
        <span><a href="/${menu.href}">${menu.title}</a></span>
    </tal:block>
</li>

It highlights the current page menu item by not making it a link. I am trying to use bootstrap pill navigation. I need to conditionally add the class="active" to the <li> tag of the active page.

I tried adding a tal:condition to the <li> tag:

 <li tal:repeat="menu view.site_menu" tal:condition="menu.current" class="active">
    <a href="/${menu.href}">${menu.title}</a>
 </li>

but I get the following error:

builtins.NameError
NameError: menu

 - Expression: "menu.current"
 - Filename:   H:\eta\eta\eta\templates\global_layout.pt
 - Location:   (line 38: col 57)
 - Source:     ... .site_menu" tal:condition="menu.current" class="active">
                                              ^^^^^^^^^^^^

My best guess here is that menu is only available inside the tal:repeat tags.

What is the best way to accomplish what I need.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
cstrutton
  • 5,667
  • 3
  • 25
  • 32

1 Answers1

7

The condition is executed before the repeat; you'd normally nest the statements to put the condition on a tag contained in the repeat. However, to put a conditional attribute, use tal:attributes instead:

<li tal:repeat="menu view.site_menu" tal:attributes="class 'active' if menu.current else None">
    <a href="/${menu.href}">${menu.title}</a>
</li>

Setting an attribute to None removes it from the tag.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Works perfectly. I have one question though. As I understand the docks this will replace the attrib. Is there anyway to add a class (leaving existing classes intact)? Note: this is not an issue today, but can see where I might come across this in the future. I am thinking of some construct similar to `class = class + 'someclass'` – cstrutton Nov 24 '13 at 14:00
  • I normally just list the classes in `tal:attributes`; you cannot reference the original value in the tag from `tal:attributes`. You *can* set things to `default` but that's a sentinel value, you cannot use it in string concatenation, for example. – Martijn Pieters Nov 24 '13 at 14:34
  • 3
    To keep your default classes you can use a simple ${..} expansion: class="your default classes${' active' if menu.current else ''}" – Wichert Akkerman Aug 20 '14 at 15:11