Customizing Smarty Themes

Last modified: October 26, 2009 - 20:37

Create a file in your theme directory named: smartytemplate.php.

<?php
 
function _smarty_variables($hook, $vars = array()) {
    switch (
$hook) {
      case
'page':
      if ((
arg(0) == 'admin')) {
       
$vars['template_file'] = 'admin';
      }
      break;
   }
   return
$vars;
  }
?>

References:

Custom page layout based on URL Alias

smanes - August 19, 2006 - 02:35

I wanted to have more control over the different sections of my site -- different banners, colors, menu blocks, etc -- based on the URL alias. For instance, I have cms,foo.com/house pages where I keep a fairly high-traffic photo diary of my ongoing house renovation, cms.foo.com/dogs where my dogs each have their own web sites, cms.foo.com/resume where I keep my professional resume, etc.

My first attempt was a hack of smarty.engine, which I didn't like doing for future upgrade reasons. I decided to move it all to a function in smartytemplate.php. Here's the code:

function _smarty_variables($hook, $vars = array())
{
    if ($hook == 'page') {
        if (arg(0) == 'comment') {
            if (isset($vars['content'])) {
                $count = preg_match('/<form action="\/\?q=comment\/(\w*)\/(\d*)"/',
                                    $vars['content'],
                                    $matches);

                if ($count > 0 && isset($matches[1]) && isset($matches[2])) {
                    $mode = $matches[1];
                    $id   = $matches[2];

                    // Just in case of SQL injection
                    if (!is_numeric($id)) {
                        return $vars;
                    }

                    $sql    = null;
                    $path   = null;

                    if ($mode == 'reply') {
                        // $id = parent page node id (nid)
                        $sql = "SELECT dst FROM url_alias WHERE src='node/$id'";
                    }
                    else if ($mode == 'edit' || $mode == 'delete') {
                        // $id = comment id (cid)
                        $sql = "SELECT dst FROM url_alias WHERE src='node/' ||
                               (SELECT nid FROM comments WHERE cid=$id)";
                    }

                    if ($sql !== null) {
                        $path = db_result(db_query($sql));
                    }
                }
            }
        }
        else if (arg(0) == 'node' && isset($vars['node']->path)) {
            $path = $vars['node']->path;
        }

        if ($path) {
            $vars['path'] = $path;
            $vars['path_elements'] = split('/', $vars['path']);
            $vars['template_file'] = 'page-' . $vars['path_elements'][0];
        }
    }
    return $vars;
  }

The SQL is for PostgreSQL but should be relatively easy to port to MySQL, if anyone wants to give it a shot.

What it does:

Based on the first node of the URL alias, an alternate page.tpl is served instead of the default page.tpl. That alternative template is named page-NODE.tpl where NODE is the first node of the URL. For example cms.foo.com/dogs would use page-dogs.tpl.

The code also remaps page.tpl for reply postings, previews, edits and deletes. If you forget to create that page-WHATEVER.tpl file, no problem. Drupal will fall back on the default page.tpl.

One more trick: it stuffs an array in the Smarty namespace, path_elements. This contains each mode of the URL alias path so you can fine tune your template at the second and even third levels. For instance, cms.foo.com/motorcycles/harley would use the page-motorcycles.tpl as would cms.foo.com/motorcycles/triumph. But within that page-motorcycles.tpl template you could display photos of a Harley or a Triumph, respectively, based on $path_elements[1], which would contain either 'harley' or 'triumph'.

 
 

Drupal is a registered trademark of Dries Buytaert.