Template resources
The filesystem resource
So far in our examples, we have used simple filenames or paths when loading a template.
For example, to load a template file called homepage.tpl
, from the filesystem, you could write:
The filesystem is the default resource. Templates, however, may come
from a variety of sources. When you render a template, or
when you include a template from within another template, you supply a
resource type, followed by :
and the appropriate path and template name.
If a resource is not explicitly given, the default resource type is assumed.
The resource type for the filesystem is file
, which means that the previous example
can be rewritten as follows:
The file resource pulls templates source files from the directories
specified using Smarty::setTemplateDir()
(see Configuring Smarty).
setTemplateDir
accepts a single path, but can also ben called with an array of paths.
In that case, the list of directories is traversed in the order they appear in the array. The
first template found is the one to process.
Templates from a specific directory
Smarty 3.1 introduced the bracket-syntax for specifying an element from
Smarty::setTemplateDir()
. This allows websites
employing multiple sets of templates better control over which template
to access.
The bracket-syntax can be used as follows:
<?php
// setup template directories
$smarty->setTemplateDir([
'./templates', // element: 0, index: 0
'./templates_2', // element: 1, index: 1
'10' => 'templates_10', // element: 2, index: '10'
'foo' => 'templates_foo', // element: 3, index: 'foo'
]);
/*
assume the template structure
./templates/foo.tpl
./templates_2/foo.tpl
./templates_2/bar.tpl
./templates_10/foo.tpl
./templates_10/bar.tpl
./templates_foo/foo.tpl
*/
// regular access
$smarty->display('file:foo.tpl');
// will load ./templates/foo.tpl
// using numeric index
$smarty->display('file:[1]foo.tpl');
// will load ./templates_2/foo.tpl
// using numeric string index
$smarty->display('file:[10]foo.tpl');
// will load ./templates_10/foo.tpl
// using string index
$smarty->display('file:[foo]foo.tpl');
// will load ./templates_foo/foo.tpl
// using "unknown" numeric index (using element number)
$smarty->display('file:[2]foo.tpl');
// will load ./templates_10/foo.tpl
And, from within a Smarty template:
{include file="file:foo.tpl"}
{* will load ./templates/foo.tpl *}
{include file="file:[1]foo.tpl"}
{* will load ./templates_2/foo.tpl *}
{include file="file:[foo]foo.tpl"}
{* will load ./templates_foo/foo.tpl *}
Using absolute paths
Templates outside the specified template directories
require the file:
template resource type, followed by the absolute
path to the template (with leading slash).
<?php
$smarty->display('file:/export/templates/index.tpl');
$smarty->display('file:/path/to/my/templates/menu.tpl');
````
And from within a Smarty template:
```smarty
{include file='file:/usr/local/share/templates/navigation.tpl'}
Note
With
Security
enabled, access to templates outside of the specified templates directories is not allowed unless you whitelist those directories.
Windows file paths
If you are running on Windows, file paths usually include a drive
letter (such as C:
) at the beginning of the pathname. Be sure to use file:
in
the path to avoid namespace conflicts and get the desired results.
<?php
$smarty->display('file:C:/export/templates/index.tpl');
$smarty->display('file:F:/path/to/my/templates/menu.tpl');
And from within Smarty template:
Handling missing templates
If the file resource cannot find the requested template, it will check if there is
a default template handler to call. By default, there is none, and Smarty will return an error,
but you can register a default template handler calling Smarty::registerDefaultTemplateHandler
with any callable.
<?php
$smarty->registerDefaultTemplateHandler([$this, 'handleMissingTemplate']);
// ...
public function handleMissingTemplate($type, $name, &$content, &$modified, Smarty $smarty) {
if (/* ... */) {
// return corrected filepath
return "/tmp/some/foobar.tpl";
} elseif (/* ... */) {
// return a template directly
$content = "the template source";
$modified = time();
return true;
} else {
// tell smarty that we failed
return false;
}
}
The string and eval resources
Smarty can render templates from a string by using the string:
or
eval:
resource.
-
The
string:
resource behaves much the same as a template file. The template source is compiled from a string and stores the compiled template code for later reuse. Each unique template string will create a new compiled template file. If your template strings are accessed frequently, this is a good choice. If you have frequently changing template strings (or strings with low reuse value), theeval:
resource may be a better choice, as it doesn\'t save compiled templates to disk. -
The
eval:
resource evaluates the template source every time a page is rendered. This is a good choice for strings with low reuse value. If the same string is accessed frequently, thestring:
resource may be a better choice.
Note
With a
string:
resource type, each unique string generates a compiled file. Smarty cannot detect a string that has changed, and therefore will generate a new compiled file for each unique string. It is important to choose the correct resource so that you do not fill your disk space with wasted compiled strings.
<?php
$smarty->assign('foo', 'value');
$template_string = 'display {$foo} here';
$smarty->display('string:' . $template_string); // compiles for later reuse
$smarty->display('eval:' . $template_string); // compiles every time
{include file="string:$template_string"} {* compiles for later reuse *}
{include file="eval:$template_string"} {* compiles every time *}
Both string:
and eval:
resources may be encoded with
urlencode()
or
base64_encode()
. This is not necessary
for the usual use of string:
and eval:
, but is required when using
either of them in conjunction with the extends resource
.
<?php
$smarty->assign('foo','value');
$template_string_urlencode = urlencode('display {$foo} here');
$template_string_base64 = base64_encode('display {$foo} here');
$smarty->display('eval:urlencode:' . $template_string_urlencode); // will decode string using urldecode()
$smarty->display('eval:base64:' . $template_string_base64); // will decode string using base64_decode()
From within a Smarty template:
{include file="string:urlencode:$template_string_urlencode"} {* will decode string using urldecode() *}
{include file="eval:base64:$template_string_base64"} {* will decode string using base64_decode() *}
The extends resource
The extends:
resource is used to define child/parent relationships. For details see section of
Template inheritance.
Note
Using the extends resource is usually not necessary. If you have a choice, it is normally more flexible and intuitive to handle inheritance chains from within the templates using the {extends} tag.
When string:
and eval:
templates are used, make sure they are properly url or base64 encoded.
The templates within an inheritance chain are not compiled separately. Only a single compiled template will be generated.
(If an eval:
resource is found within an inheritance chain, its "don't save a compile file" property is superseded by
the extends:
resource.)
Example:
<?php
$smarty->display('extends:parent.tpl|child.tpl|grandchild.tpl');
// inheritance from multiple template sources
$smarty->display('extends:db:parent.tpl|file:child.tpl|grandchild.tpl|eval:{block name="fooBazVar_"}hello world{/block}');
The stream resource
Smarty allow you to use PHP streams as a template resource. Smarty will first look for a registered template resource. If nothing is found, it will check if a PHP stream is available. If a stream is available, Smarty will use it to fetch the template.
For example,
<?php
stream_wrapper_register('myresource', MyResourceStream::class);
$smarty->display('myresource:bar.tpl');
Or, from within a template:
Adding your own resource type
You can create a class that extends Smarty\Resource\CustomPlugin
to add your own resource type,
for example to load template from a database.
For example:
<?php
class HelloWorldResource extends Smarty\Resource\CustomPlugin {
protected function fetch($name, &$source, &$mtime) {
$source = '{$x="hello world"}{$x}'; // load your template here based on $name
$mtime = time();
}
}
// ..
$smarty->registerResource('helloworld', new HelloWorldResource());
If a Resource's templates should not be run through the Smarty
compiler, the Custom Resource may extend \Smarty\Resource\UncompiledPlugin
.
The Resource Handler must then implement the function
renderUncompiled(\Smarty\Template $_template)
. $_template
is
a reference to the current template and contains all assigned variables
which the implementor can access via
$_template->getSmarty()->getTemplateVars()
. These Resources simply echo
their rendered content to the output stream. The rendered output will be
output-cached if the Smarty instance was configured accordingly. See
src/Resource/PhpPlugin.php
for an example.
If the Resource's compiled templates should not be cached on disk, the
Custom Resource may extend \Smarty\Resource\RecompiledPlugin
. These Resources
are compiled every time they are accessed. This may be an expensive
overhead. See src/Resource/StringEval.php
for an
example.
Changing the default resource type
The default resource type is file
. If you want to change it, use Smarty::setDefaultResourceType
.
The following example will change the default resource type to mysql
: