views:

572

answers:

3

Hi,

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,

+1  A: 

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.

Tom Haigh
Does Smarty then compile based on the path or still based on the provided template name? In the latter case, providing changing lists of template folders will break the templating...
Boldewyn
I think it does it based on the path. I have different templates in different folders which are called the same thing, and the compiled files all have a different prefix.
Tom Haigh
I hadn't time to test this yet, but if it works with compiling, it'd be really cool.
Boldewyn
A: 

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.

chaos
+1  A: 

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;
}
Chris