Extending Smarty With Plugins
Version 2.0 introduced the plugin architecture that is used
for almost all the customizable functionality of Smarty. This includes:
functionsmodifiersblock functionscompiler functionsprefilterspostfiltersoutputfiltersresourcesinserts
With the exception of resources, backwards compatibility with the old
way of registering handler functions via register_* API is preserved. If
you did not use the API but instead modified the class variables
$custom_funcs, $custom_mods, and
other ones directly, then you will need to adjust your scripts to either
use the API or convert your custom functionality into plugins.
How Plugins Work
Plugins are always loaded on demand. Only the specific modifiers,
functions, resources, etc invoked in the templates scripts will be
loaded. Moreover, each plugin is loaded only once, even if you have
several different instances of Smarty running within the same request.
Pre/postfilters and output filters are a bit of a special case. Since
they are not mentioned in the templates, they must be registered or
loaded explicitly via API functions before the template is processed.
The order in which multiple filters of the same type are executed
depends on the order in which they are registered or loaded.
The plugins directory
can be a string containing a path or an array containing multiple
paths. To install a plugin, simply place it in one of the
directories and Smarty will use it automatically.
Naming Conventions
Plugin files and functions must follow a very specific naming
convention in order to be located by Smarty.
The plugin files must be named as follows:
type.name.php
Where type is one of these plugin types:
functionmodifierblockcompilerprefilterpostfilteroutputfilterresourceinsert
And name should be a valid identifier (letters,
numbers, and underscores only).
Some examples: function.html_select_date.php,
resource.db.php,
modifier.spacify.php.
The plugin functions inside the plugin files must be named as follows:
smarty_type_name
The meanings of type and name are
the same as before.
Smarty will output appropriate error messages if the plugin file it
needs is not found, or if the file or the plugin function are named
improperly.
Writing Plugins
Plugins can be either loaded by Smarty automatically from the
filesystem or they can be registered at runtime via one of the
register_* API functions. They can also be unregistered by using
unregister_* API functions.
For the plugins that are registered at runtime, the name of the plugin
function(s) does not have to follow the naming convention.
If a plugin depends on some functionality provided by another plugin
(as is the case with some plugins bundled with Smarty), then the proper
way to load the needed plugin is this:
require_once $smarty->_get_plugin_filepath('function', 'html_options');
As a general rule, Smarty object is always passed to the plugins
as the last parameter (with two exceptions: modifiers do not get
passed the Smarty object at all and blocks get passed
&$repeat after the Smarty object to keep
backwards compatibility to older versions of Smarty).
Template Functionsvoid smarty_function_namearray $paramsobject &$smarty
All attributes passed to template functions from the template are
contained in the $params as an associative
array.
The output (return value) of the function will be substituted in place of the
function tag in the template (fetch function, for
example). Alternatively, the function can simply perform some other
task without any output (assign function).
If the function needs to assign some variables to the template or use
some other Smarty-provided functionality, it can use the supplied
$smarty object to do so.
See also:
register_function(),
unregister_function().
function plugin with output
]]>
which can be used in the template as:
Question: Will we ever have time travel?
Answer: {eightball}.
function plugin without output
trigger_error("assign: missing 'var' parameter");
return;
}
if (!in_array('value', array_keys($params))) {
$smarty->trigger_error("assign: missing 'value' parameter");
return;
}
$smarty->assign($params['var'], $params['value']);
}
?>
]]>
Modifiers
Modifiers are little functions that are applied to a variable in the
template before it is displayed or used in some other context.
Modifiers can be chained together.
mixed smarty_modifier_namemixed $value[mixed $param1, ...]
The first parameter to the modifier plugin is the value on which
the modifier is supposed to operate. The rest of the parameters can be
optional, depending on what kind of operation is supposed to be
performed.
The modifier has to return the result of its processing.
See also
register_modifier(),
unregister_modifier().
simple modifier plugin
This plugin basically aliases one of the built-in PHP functions. It
does not have any additional parameters.
]]>
more complex modifier plugin
$length) {
$length -= strlen($etc);
$fragment = substr($string, 0, $length+1);
if ($break_words)
$fragment = substr($fragment, 0, -1);
else
$fragment = preg_replace('/\s+(\S+)?$/', '', $fragment);
return $fragment.$etc;
} else
return $string;
}
?>
]]>
Block Functionsvoid smarty_block_namearray $paramsmixed $contentobject &$smarty
Block functions are functions of the form: {func} .. {/func}. In other
words, they enclose a template block and operate on the contents of
this block. Block functions take precedence over custom functions of
the same name, that is, you cannot have both custom function {func} and
block function {func} .. {/func}.
By default your function implementation is called twice by
Smarty: once for the opening tag, and once for the closing tag
(see &$repeat below how to change this).
Only the opening tag of the block function may have attributes. All
attributes passed to template functions from the template are contained
in the $params as an associative array. You can
access those values as e.g. $params['start'].
The opening tag attributes are also accessible to your function
when processing the closing tag.
The value of $content variable depends on
whether your function is called for the opening or closing tag. In case
of the opening tag, it will be null, and in case of
the closing tag it will be the contents of the template block.
Note that the template block will have already been processed by
Smarty, so all you will receive is the template output, not the
template source.
The parameter &$repeat is passed by
reference to the function implementation and provides a
possibility for it to control how many times the block is
displayed. By default $repeat is
true at the first call of the block-function
(the block opening tag) and false on all
subsequent calls to the block function (the block's closing tag).
Each time the function implementation returns with
&$repeat being true, the contents between
{func} .. {/func} are evaluated and the function implementation
is called again with the new block contents in the parameter
$content.
If you have nested block functions, it's possible to find out what the
parent block function is by accessing
$smarty->_tag_stack variable. Just do a var_dump()
on it and the structure should be apparent.
See also:
register_block(),
unregister_block().
block function
]]>
Compiler Functions
Compiler functions are called only during compilation of the template.
They are useful for injecting PHP code or time-sensitive static
content into the template. If there is both a compiler function and a
custom function registered under the same name, the compiler function
has precedence.
mixed smarty_compiler_namestring $tag_argobject &$smarty
The compiler function is passed two parameters: the tag argument
string - basically, everything from the function name until the ending
delimiter, and the Smarty object. It's supposed to return the PHP code
to be injected into the compiled template.
See also
register_compiler_function(),
unregister_compiler_function().
simple compiler function
_current_file . " compiled at " . date('Y-m-d H:M'). "';";
}
?>
]]>
This function can be called from the template as:
{* this function gets executed at compile time only *}
{tplheader}
The resulting PHP code in the compiled template would be something like this:
]]>
Prefilters/Postfilters
Prefilter and postfilter plugins are very similar in concept; where
they differ is in the execution -- more precisely the time of their
execution.
string smarty_prefilter_namestring $sourceobject &$smarty
Prefilters are used to process the source of the template immediately
before compilation. The first parameter to the prefilter function is
the template source, possibly modified by some other prefilters. The
plugin is supposed to return the modified source. Note that this
source is not saved anywhere, it is only used for compilation.
string smarty_postfilter_namestring $compiledobject &$smarty
Postfilters are used to process the compiled output of the template
(the PHP code) immediately after the compilation is done but before the
compiled template is saved to the filesystem. The first parameter to
the postfilter function is the compiled template code, possibly
modified by other postfilters. The plugin is supposed to return the
modified version of this code.
prefilter plugin
]+>!e', 'strtolower("$1")', $source);
}
?>
]]>
postfilter plugin
\nget_template_vars()); ?>\n" . $compiled;
return $compiled;
}
?>
]]>
Output Filters
Output filter plugins operate on a template's output, after the
template is loaded and executed, but before the output is displayed.
string smarty_outputfilter_namestring $template_outputobject &$smarty
The first parameter to the output filter function is the template
output that needs to be processed, and the second parameter is the
instance of Smarty invoking the plugin. The plugin is supposed to do
the processing and return the results.
output filter plugin
]]>
Resources
Resource plugins are meant as a generic way of providing template
sources or PHP script components to Smarty. Some examples of resources:
databases, LDAP, shared memory, sockets, and so on.
There are a total of 4 functions that need to be registered for each
type of resource. Every function will receive the requested resource as
the first parameter and the Smarty object as the last parameter. The
rest of parameters depend on the function.
bool smarty_resource_name_sourcestring $rsrc_namestring &$sourceobject &$smartybool smarty_resource_name_timestampstring $rsrc_nameint &$timestampobject &$smartybool smarty_resource_name_securestring $rsrc_nameobject &$smartybool smarty_resource_name_trustedstring $rsrc_nameobject &$smarty
The first function is supposed to retrieve the resource. Its second
parameter is a variable passed by reference where the result should be
stored. The function is supposed to return true if
it was able to successfully retrieve the resource and
false otherwise.
The second function is supposed to retrieve the last modification time
of the requested resource (as a UNIX timestamp). The second parameter
is a variable passed by reference where the timestamp should be stored.
The function is supposed to return true if the
timestamp could be succesfully determined, and false
otherwise.
The third function is supposed to return true or
false, depending on whether the requested resource
is secure or not. This function is used only for template resources but
should still be defined.
The fourth function is supposed to return true or
false, depending on whether the requested resource
is trusted or not. This function is used for only for PHP script
components requested by include_php tag or
insert tag with src
attribute. However, it should still be defined even for template
resources.
See also
register_resource(),
unregister_resource().
resource plugin
query("select tpl_source
from my_table
where tpl_name='$tpl_name'");
if ($sql->num_rows) {
$tpl_source = $sql->record['tpl_source'];
return true;
} else {
return false;
}
}
function smarty_resource_db_timestamp($tpl_name, &$tpl_timestamp, &$smarty)
{
// do database call here to populate $tpl_timestamp.
$sql = new SQL;
$sql->query("select tpl_timestamp
from my_table
where tpl_name='$tpl_name'");
if ($sql->num_rows) {
$tpl_timestamp = $sql->record['tpl_timestamp'];
return true;
} else {
return false;
}
}
function smarty_resource_db_secure($tpl_name, &$smarty)
{
// assume all templates are secure
return true;
}
function smarty_resource_db_trusted($tpl_name, &$smarty)
{
// not used for templates
}
?>
]]>
Inserts
Insert plugins are used to implement functions that are invoked by
insert
tags in the template.
string smarty_insert_namearray $paramsobject &$smarty
The first parameter to the function is an associative array of
attributes passed to the insert.
The insert function is supposed to return the result which will be
substituted in place of the insert tag in the
template.
insert plugin
trigger_error("insert time: missing 'format' parameter");
return;
}
$datetime = strftime($params['format']);
return $datetime;
}
?>
]]>