Smarty template for generating cascaded UL based menu

So far, I’ve been happy how this template behaves when I pass a parent/child links into it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
< {$parent_tag|default:'ul'}{if $menu_id} id="{$menu_id}"{/if}{if $parent_class} class="{$parent_class}"{/if}>{* ul tag opens here *}
{foreach from=$links item=link}
  {if $link.class_active && $link.href == $current_uri}
    {if $link.class}
      {assign var=class value="`$link.class` `$link.class_active`"}      
    {else}
      {assign var=class value="`$link.class_active`"}
    {/if}
  {else}
    {assign var=class value="`$link.class`"}
  {/if}
  < {$child_tag|default:'li'}{if $class} class="{$class}"{/if}{if $link.id} id="link_{$link.id}"{/if}>
    <a href="{$link.href}"{if $link.target} target="{$link.target}"{/if}>{$link.text}</a>
  {if $link.children}
    {include file="links.html" links=$link.children parent_class=""}
  {/if}
{/foreach}
< /{$parent_tag|default:'ul'}>

Does something like this when rendered

<ul class="sf-menu">
  <li><a href="http://www.swerteka.com/index.php">Home</a></li>
  <li><a href="http://www.swerteka.com/PostItem">Post Item</a></li>
  <li><a href="http://www.swerteka.com">Blog</a>
    <ul>
      <li><a href="http://www.swerteka.com/BlogComments/do/viewrecent">Comments</a></li>
    </ul>
  </li>
  <li><a href="http://www.swerteka.com/Content/name/about">About</a>
    <ul>
      <li><a href="http://www.swerteka.com/Content/name/contact">Contact Us</a></li>
    </ul>
  </li>
</ul>

Breaking the silence

So, I haven’t really got time posting stuff here. Its because I’ve been trying to finish my new site after my day job. It is called swerteka.com, and I’m gonna give it as free ad posting service.

But it’s still a long way to go, and it will be loaded by the CMS script I’ve been working on.

OOP 101: No logic in template, as much as possible

If you have a repeating region in your template and it doesn’t need a wrapper around it, simply use section

1
2
3
{section name=s loop=$images}
   <div id="image_{$images[s].id}"><img src="{$images[s].src}" alt="" /></div>
{/section}

Cases where you need html wrap tags is like this

1
2
3
4
5
6
7
8
9
{if $navlinks}
<ul>
{section name=s loop=$navlinks}
   <li id="navitem_{$navlinks[s].id}">
     <a href="{$navlinks[s].href}">{$navlinks[s].text}</a>
   </li>
{/section}
</ul>
{/if}

This avoids the <ul> being rendered if $navlinks don’t have a return record. Another way is to access Smarty properties

1
2
3
4
5
6
7
{section name=s loop=$navlinks}
   {if $smarty.section.s.first}<ul>{/if}
   <li id="navitem_{$navlinks[s].id}">
     <a href="{$navlinks[s].href}">{$navlinks[s].text}</a>
   </li>
   {if $smarty.section.s.last}</ul>{/if}
{/section}

But still, this adds an if in the template. As this post title goes, you should avoid them, that’s the basics of OOP system and MVC frameworks, separate logic from code :D

What made me write this post? Template Designers sometimes hate seeing if statements. In my case, my boss transforms into savvy Designer as well, at times! Bummer