Boldewyn
Boldewyn

Reputation: 82734

PHP, Smarty: Check for template in different folders

for our latest project we used Django, where one can specify a list of folders, that are searched for a template, say, with name example.html. Now, we switched back to Smarty (PHP) and are wondering, if there is something similar.

Smarty version: Can be cutting-edge.

Behaviour:

  1. Feed Smarty with an array of folders.
  2. Call a template either with $smarty->display() or {include}.
  3. Smarty searches through the folders and takes the first template matching the name.

I looked at Smarty resources, but they look like overkill for this task, and the docs are a bit sparse on this topic. Any ideas how this could be done?

An additional problem is, that the list of folders may change depending on the requested URL. Any ideas how to tell Smarty, which compiled template to use?

Cheers,

Upvotes: 3

Views: 4717

Answers (4)

joe
joe

Reputation: 69

The Smarty template_dir value can be an array of directories. Smarty will traverse the directories in order until a matching template is found.

Upvotes: 2

Chris L
Chris L

Reputation: 4740

I know its been a while since this question was asked, but for the record I wanted to point out a feature of Smarty that I think does what the OP is asking. Below is a portion of the code from my app.

Basically what it does is first look for the template in /ext/templates. If it does not find it there, it will use the one from /base/templates. My code only requires a single fallback, but more could easily be added.

class View extends Smarty {
    function __construct() {
        parent::Smarty();

        $this->template_dir = LOCAL_APP_ROOT.'/ext/templates';
        $this->compile_dir = LOCAL_APP_ROOT.'/cache/compile';

        $this->default_template_handler_func = '__default_template_handler';
    }
}


function __default_template_handler($resource_type, $resource_name, &$template_source, &$template_timestamp, &$smarty_obj) {
    if ($resource_type == 'file') {
        if (!is_readable($resource_name)) {
            $defaultPath = LOCAL_APP_ROOT."/base/templates/$resource_name";
            if (file_exists($defaultPath)) {
                $template_source = file_get_contents($defaultPath);
                $template_timestamp = filemtime($defaultPath);
                return true;
            }
        }
    }
    return false;
}

Upvotes: 2

Tom Haigh
Tom Haigh

Reputation: 57815

In Smarty.class.php, in the method Smarty::_parse_resource_name() :

foreach ((array)$params['resource_base_path'] as $_curr_path) {
    $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name'];
    if (file_exists($_fullpath) && is_file($_fullpath)) {
        $params['resource_name'] = $_fullpath;
        return true;
    }
    // didn't find the file, try include_path
    $_params = array('file_path' => $_fullpath);
    require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
    if(smarty_core_get_include_path($_params, $this)) {
        $params['resource_name'] = $_params['new_file_path'];
        return true;
    }
}

$params['resource_base_path'] is defaulted to $this->template_dir in Smarty::_fetch_resource_info().

So it looks like you can set $smarty->template_dir to an array of directories to look in. Note that this won't be recursive. This must be an undocumented feature.

Upvotes: 4

chaos
chaos

Reputation: 124307

Unfortunately, Smarty is designed to work with a single template directory (the template_dir property of the Smarty object). You can change this at runtime, though, so that may get you some of the effects you're looking for.

Upvotes: 0

Related Questions