What’s Smarty?

Six months later… and I don’t miss Smarty at all. I’m perfectly happy with Zend Framework’s view scripts and PHP’s alternate syntax tags. Accepting view scripts was easy enough, it’s part of the framework so I might as well use it. However I still couldn’t accept seeing PHP code in my HTML templates:

<table>
<?php foreach($tableData as $dataRow) { ?>
   <tr>
   <?php foreach($dataRow as $data) { ?>
      <td><?php echo $data; ?></td>
   <?php } ?>
   </tr>
<?php } ?>
</table>

When I discovered PHP’s alternate syntax, it just made sense. Especially if one keeps the alternate syntax in the view script only. And I think the syntax itself is much easier for The Designer (who doesn’t know/care about anything that is PHP) to understand:

<table>
<? foreach($tableData as $dataRow): ?>
   <tr>
   <? foreach($dataRow as $data): ?>
      <td><?= $data ?></td>
   <? endforeach; ?>
   </tr>
<? endforeach; ?>
</table>

And at the same time I don’t get asked those endless ‘what the hell does {section} mean?’ questions anymore.

I Miss Smarty

The last couple of days I’ve been getting my hands dirty with the codebase of one of the projects at work. At first I was kind of excited because it’s always a good experience becoming familiar with the unfamiliar. But imagine how my heart sank when I opened that first .php file and saw code like the following:

<table>
<?php foreach($tableData as $dataRow) { ?>
   <tr>
   <?php foreach($dataRow as $data) { ?>
      <td><?php echo $data; ?></td>
   <?php } ?>
   </tr>
<?php } ?>
</table>

Yes that’s right. PHP code mixed with the HTML markup. It’s a far cry from the neatly formatted Smarty templates that I’ve been working with the past 2-3 months.

There are three places where I usually see this kind of ‘unfortunate’ code:

  1. PHP for dummies books
  2. Templating systems
  3. Ajax payloads from the server

A free cookie to the first reader to guess correctly which category The Project falls in.

Although there’s a good reason why much the codebase is written like the above, that justification doesn’t make working with it any easier. Case in point: I spent the better part of this afternoon pulling my hair out trying to figure out why a block of HTML wasn’t showing up and it was all because I misplaced a </div> insde a triple nested <foreach> structure.

Not the best way to spend your afternoon. Especially during the first week of a new job…

Another Smarty Plugin Hack

The Client wanted the date select boxes of all forms defaulted to ‘January 1 1900′ as opposed to the current date that I implemented. The only problem is that Smarty’s html_select_date defaults to the current date when the time parameter is null (which is the case sometimes). And I’m not very comfortable forcing the time parameter to ‘1900-01-01′ in my controller scripts.

I figured I could somehow modify the html_select_date plugin and as it turns out it wasn’t so hard. All I did was force the plugin to default to ‘1900-01-01′ and add an optional parameter (default_time) to the cases when I wanted the plugin to default to some other date.

// use smarty_make_timestamp to get an unix timestamp and
// strftime to make yyyy-mm-dd
if (isset($params['default_time']))
   $time = strftime('%Y-%m-%d', smarty_make_timestamp($time));
else
   $time = '1900-01-01';

So for example if I wanted the date to default to January 1 1900 I would write:

{html_select_date}

If I wanted the date to default to some other date (let’s say the current one) I would write:

{html_select_date default_time=$smarty.now}

Yes it’s a bit of a hack but whatever it works for me.

Displaying Zebra Tables In Smarty

How come I’ve never heard of {cycle} before? It turns crap like this:

<table>
{section name = i loop = $items}
   {if $smarty.section.i.index % 2 == 0}
      {assign var = 'rowStyle' value = 'odd'}
   {else}
      {assign var = 'rowStyle' value = 'even'}
   {/if}

   <tr class = "{$rowStyle}">
   ...
   </tr>
{/section}
</table>

Into concise stuff like this:

<table>
{section name = i loop = $items}
   <tr class = "{cycle values = 'odd,even'}">
   ....
   </tr>
{/section}
</table>

Which may not seem like much until you realize that The Designer uses zebra tables everywhere in The Project.

Custom Smarty Plugins

One of Smarty’s big selling points is that you could easily extend it by writing your own custom plugins. Here are a couple…

A drop down box for countries:

{html_select_country}

function smarty_function_html_select_country($params, &$smarty)
{
   require_once($smarty->_get_plugin_filepath('function',
                'html_options');

   $options = array
   (
      'USA' => 'United States',
      'CAN' => 'Canada',
      .... <snip> ....
      'ZWE' => 'Zimbabwe'
   );

   $params['options'] = $options;

   return smarty_function_html_options($params, $smarty);
}

A drop down box for US states / Canadian provinces:

{html_select_state country = '<your country>'}

function smarty_function_html_select_state($params, &$smarty)
{
   require_once($smarty->_get_plugin_filepath('function',
                'html_options');

   $options = array();

   $usa_states = array
   (
      'AL' => 'Alabama',
      'AK' => 'Alaska',
      .... <snip> ....
      'WY' => 'Wyoming'
   );

   $can_provinces = array
   (
      'AB' => 'Alberta',
      'BC' => 'British Columbia',
      .... <snip> ....
      'YT' => 'Yukon Territories'
   );

   $country = $params['country'];

   switch($country)
   {
      case 'USA':
      case NULL;
      $options = $usa_states;

      default:
      $options = $can_provinces;
   }

   $params['options'] = $options;

   return smarty_function_html_options($params, $smarty);
}

Incidentally I’ve been using Smarty for about two years now and it was only until today that I actually wrote my very own custom plugin. I can’t believe how straight forward it was.

Next Page →