diff options
Diffstat (limited to 'docs/api/resources.md')
| -rw-r--r-- | docs/api/resources.md | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/docs/api/resources.md b/docs/api/resources.md new file mode 100644 index 00000000..5ca52b12 --- /dev/null +++ b/docs/api/resources.md @@ -0,0 +1,322 @@ +# 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 +<?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 +<?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](configuring.md)). + +`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 +<?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: + +```smarty +{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 +<?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`](security.md) 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 +<?php +$smarty->display('file:C:/export/templates/index.tpl'); +$smarty->display('file:F:/path/to/my/templates/menu.tpl'); +``` + +And from within Smarty template: +```smarty +{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](https://www.php.net/manual/en/language.types.callable.php). + +```php +<?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 +<?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: +```smarty +{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()`](https://www.php.net/urlencode) or +[`base64_encode()`](https://www.php.net/urlencode). 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`](#the-extends-resource). + +```php + <?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: +```smarty + {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](inheritance.md). + +> **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](inheritance.md). + +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 +<?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](https://www.php.net/manual/en/function.stream-wrapper-register.php) +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 +<?php +stream_wrapper_register('myresource', MyResourceStream::class); +$smarty->display('myresource:bar.tpl'); +``` + +Or, from within a template: +```smarty + {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 +<?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 +<?php +$smarty->setDefaultResourceType('mysql'); +``` |
