Sidebar Block Plugin for Smarty Templates

HTML templates allow presentation to be abstracted from control. Abstraction, like water, is good—but be careful or you'll drown.

Take sidebar blocks. HTML templates make it easy to abstract the sidebar, but what about the individual blocks?

You could make each block its own template, but you end up juggling so many miniscule pieces you lose track of all the bits. Do you really need a dedicated template just to put an RSS icon in a box?

On the other hand, if you eschew templates and code the blocks all up in the sidebar, you get a large unstructured mess of HTML.

What we need to do here is abstract the structure, not all the little bits of content.

The Smarty template system for PHP has a good solution. You can use the plugin mechanism to create a custom template tag such as {block}. That makes it easy to place blocks in a sidebar template in a structured fashion. I did this for the Holidailies web site.

Here is how a sidebar block looks on Holidailies:

a sample sidebar block from the Holidailies web site

The following code in the sidebar template created that block:

{block id="news" title="Holidailies News"}
  <p>{$News_Headline}
  <a class="more-link" href="news.php">[More...]</a></p>
{/block}

The {block} template tag has two parameters (id and title) that control the block. The text between the open and close tags defines the block content.

The $News_Headline template variable contains the news headline to display. Smarty replaces a variable enclosed in curly braces with its value.

The HTML that results from this looks something like:

<div id="block-news" class="block">
<h3 class="block-title">Holidailies News</h3>
<div class="block-content">
  <p>Dec 3: Portal registration is now closed
  <a class="more-link" href="news.php">[More...]</a></p>
</div>
</div><!-- #block-news -->

The {block} template tag is not a standard part of the Smarty template language. I added it using the Smarty plugin mechanism. Here is the PHP code that did it:

/**
* Smarty plugin callback to generate a sidebar block.
*
* @param $params
*   Array containing the parameters in the opening tag.
* @param $content
*   The content between the opening and close tag.
* @param $smarty
*   Reference to a Smarty object.
* @param $repeat
*   Repeat count, not used here.
* @return
*   HTML content, the sidebar block.
*/
function smarty_block_block($params, $content, &$smarty, &$repeat)
{
    if (isset($content)) {

        // Add the block content to the tag parameters list.
        $params['content'] = $content;

        // Create a $Block_Params template variable that contains these settings.
        $smarty->assign('Block_Params', $params);

        // Generate the block.
        $output = $smarty->fetch('block.tpl');

        // Clean up.
        $smarty->clear_assign('Block_Params');

        return $output;
    }
}

$smarty->register_block('block', 'smarty_block_block');

Smarty calls this type of plugin a block function, because it operates on a block of content between an opening and closing tag. That's why I named the callback function smarty_block_block(): it creates a template block function that returns the HTML for a sidebar block. Confusing, isn't it?

One bit remains. This function references a template called block.tpl. I started this article complaining about using templates for individual blocks. This is different. This isn't a template per block, but one template that abstracts the structure of sidebar blocks. The block.tpl that generates the HTML shown above is:

<div id="block-{$Block_Params.id}" class="block">
<h3 class="block-title">{$Block_Params.title}</h3>
<div class="block-content">
{$Block_Params.content}
</div>
</div><!-- #block-{$Block_Params.id} -->

The {block} tag really helped me cleanup my sidebar template. The benefit may not appear significant for the one example shown here (a simple block with two lines of HTML content). As the number of blocks expands and the controls get more complicated (such as deciding whether or not to place a block), the benefit of this structure becomes significant.

Or, if I ever decide to make a global change to the site such as adding rounded corners to the boxes, it's easy. The only thing that changes is the block.tpl template.

In fact, I did just this. Take another look at the image at the top of this article. You may notice the rounded corners on the heading. The {block} tag made it much easier to develop, test, and deploy.