+
+
+
+
+
+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:
+
<?php
+
+use Smarty\Smarty;
+$smarty = new Smarty();
+
+$smarty->display('homepage.tpl');
+
+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:
+
<?php
+
+use Smarty\Smarty;
+$smarty = new Smarty();
+
+$smarty->display('file:homepage.tpl');
+
+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:
+
{include file='file:D:/usr/local/share/templates/navigation.tpl'}
+
+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), the
+ eval:
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, the string:
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
+
+From within a Smarty template:
+{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:
+
{include file="myresource:bar.tpl"}
+
+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
:
+
<?php
+$smarty->setDefaultResourceType('mysql');
+
+
+
+
+
+
+
+