Files
smarty/docs.sgml
2001-12-06 22:52:15 +00:00

6170 lines
206 KiB
Plaintext

<!dOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN">
<book>
<bookinfo>
<title>Smarty - the compiling PHP template engine</title>
<author>
<firstname>Monte</firstname><surname>Ohrt</surname>
<affiliation>
<address><email>monte@ispi.net</email></address>
</affiliation>
</author>
<author>
<firstname>Andrei</firstname><surname>Zmievski</surname>
<affiliation>
<address><email>andrei@php.net</email></address>
</affiliation>
</author>
<edition>Version 1.5.0</edition>
<copyright><year>2001</year><holder>ispi of Lincoln, Inc.</holder></copyright>
</bookinfo>
<chapter>
<title>Overview</title>
<para>
It is undoubtedly one of the most asked questions on the PHP mailing
lists: how do I make my PHP scripts independent of the layout? While
PHP is billed as "HTML embedded scripting language", after writing a
couple of projects that mixed PHP and HTML freely one comes up with the
idea that separation of form and content is a Good Thing [TM]. In
addition, in many companies the roles of layout designer and programmer
are separate. Consequently, the search for a templating solution
ensues.
</para>
<para>
In our company for example, the development of an application goes on
as follows: After the requirements docs are done, the interface
designer makes mockups of the interface and gives them to the
programmer. The programmer implements business logic in PHP and uses
interface mockups to create skeleton templates. The project is then
handed off to the HTML designer/web page layout person who brings the
templates up to their full glory. The project may go back and forth
between programming/HTML a couple of times. Thus, it's important to
have good template support because programmers don't want anything to
do with HTML and don't want HTML designers mucking around with PHP
code. Designers need support for config files, dynamic blocks and
other interface issues, but they don't want to have to deal with
intricacies of the PHP programming language.
</para>
<para>
Looking at many templating solutions available for PHP today, most of
them provide a rudimentary way of substituting variables into templates
and do a limited form of dynamic block functionality. But our needs
required a bit more than that. We didn't want programmers to be dealing
with HTML layout at ALL, but this was almost inevitable. For instance,
if a designer wanted background colors to alternate on dynamic blocks,
this had to be worked out with the programmer in advance. We also
needed designers to be able to use their own configuration files, and
pull variables from them into the templates. The list goes on.
</para>
<para>
We started out writing out a spec for a template engine back in late
1999. After finishing the spec, we began to work on a template engine
written in C that would hopefully be accepted for inclusion with PHP.
Not only did we run into many complicated technical barriers, but there
was also much heated debate about exactly what a template engine should
and should not do. From this experience, we decided that the template
engine should be written in PHP as a class, for anyone to use as they
see fit. So we wrote an engine that did just that and
<emphasis>SmartTemplate</emphasis> came into existence (note: this
class was never submitted to the public). It was a class that did
almost everything we wanted: regular variable substitution, supported
including other templates, integration with config files, embedding PHP
code, limited 'if' statement functionality and much more robust dynamic
blocks which could be multiply nested. It did all this with regular
expressions and the code turned out to be rather, shall we say,
impenetrable. It was also noticably slow in large applications from all
the parsing and regular expression work it had to do on each
invocation. The biggest problem from a programmer's point of view was
all the necessary work in the PHP script to setup and process templates
and dynamic blocks. How do we make this easier?
</para>
<para>
Then came the vision of what ultimately became Smarty. We know how fast
PHP code is without the overhead of template parsing. We also know how
meticulous and overbearing the PHP language may look to the average
designer, and this could be masked with a much simpler templating
syntax. So what if we combined the two strengths? Thus, Smarty was
born...
</para>
<sect1>
<title>What is Smarty?</title>
<para>
Smarty is a template engine for PHP. One of the unique aspects about
Smarty is that it compiles the template files into native PHP scripts
upon the first invocation. After that, it just executes the compiled
PHP scripts. Therefore, there is no costly template file parsing for
each request, and each template can take full advantage of PHP compiler
cache solutions such as Zend Cache (http://www.zend.com) or APC
(http://apc.communityconnect.com).
</para>
<para>
Some of Smarty's features:
</para>
<itemizedlist>
<listitem><para>It is extremely fast.</para></listitem>
<listitem><para>It is efficient since the PHP parser does the
dirty work.</para></listitem>
<listitem><para>No template parsing overhead, only compiles once.</para></listitem>
<listitem><para>It is smart about recompiling only the template
files that have changed.</para></listitem>
<listitem><para>You can make <link linkend="custom.functions">custom
functions</link> and custom <link linkend="variable.modifiers">variable
modifiers</link>, so the template language is extremely extensible.</para></listitem>
<listitem><para>Configurable template delimiter tag syntax, so you can use
{}, {{}}, &lt;!--{}--&gt;, etc.</para></listitem>
<listitem><para>The if/elseif/else/endif constructs are passed to the
PHP parser, so the {if ...} expression syntax can be as simple or as complex
as you like.</para></listitem>
<listitem><para>Unlimited nesting of sections, ifs, etc. allowed.</para></listitem>
<listitem><para>It is possible to embed PHP code right in your template files,
although this may not be needed (nor recommended)
since the engine is so customizable.</para></listitem>
<listitem><para>Built-in caching support (new in 1.3.0)</para></listitem>
<listitem><para>Arbitrary template sources (new in 1.4.0)</para></listitem>
<listitem><para>Custom cache handling functions (new in 1.4.7)</para></listitem>
</itemizedlist>
</sect1>
<sect1>
<title>How Smarty works</title>
<sect2><title>Compiling</title>
<para>
Smarty compiles the templates into native PHP code on-the-fly. The actual
PHP scripts that are generated are created implicitly, so theoretically you
should never have to worry about touching these files, or even know of their
existence. The exception to this is debugging Smarty template syntax errors,
discussed later in this document.
</para>
</sect2>
<sect2 id="section.caching">
<title>Caching</title>
<para>
Smarty can cache the output of your generated templates. By default
this is disabled. If you <link linkend="setting.caching">enable
caching</link>, Smarty will store a copy of the generated template
output, and use this until the copy <link
linkend="setting.cache.lifetime">expires</link>, regenerating a new
one. The default cache expire time can be configured from the
class. The exception to the rule is the <link
linkend="builtin.functions.insert">insert</link> tag. Anything
generated by the insert tag is not cached, but run dynamically on
every invocation, even within cached content.
</para>
<para>
TECHNICAL NOTE: Any time you change a template, change values in
config files or change the content that gets displayed in a
template, you can turn on compile_check to regenerate the caches
that are affected, or wait for the cache to expire to see the
results of the changes. You clear caches manually by deleting files
from the cache directory, programatically with <link
linkend="api.clear.cache">clear_cache</link> or <link
linkend="api.clear.all.cache">clear_all_cache</link>, or turn on
$compile_check (or $force_compile).
</para>
<para>
TECHNICAL NOTE: As of Smarty 1.4.6, if you have caching enabled AND
you have compile_check enabled, the cached file will regenerate if
an involved template or config file has been modified, regardless
of the cache expire time. This results in a slight performance hit
since it has to check the templates and config files for
modification times. Therefore if you are not actively changing
templates or config files, it is advisable to leave compile_check
off. As of Smarty 1.4.7, enabling $force_compile will cause cache
files to always be regenerated.
</para>
</sect2>
</sect1>
</chapter>
<chapter>
<title>Installation</title>
<sect1>
<title>Requirements</title>
<para>
Smarty requires PHP 4.0.4pl1 or later. See the
<link linkend="bugs">BUGS</link> section for caveats.
</para>
</sect1>
<sect1>
<title>Installing Smarty</title>
<para>
Installing Smarty is fairly straightforward, there are a few things to
be aware of. Smarty creates PHP scripts from the templates. This
usually means allowing user "nobody" (or whomever the web server runs
as) to have permission to write the files. Each installation of a
Smarty application minimally needs a templates directory and a compiled
templates directory. If you use configuration files you will also need
a directory for those. By default these are named "templates",
"templates_c" and "configs" respectively. If you plan on using caching,
you will need to create a "cache" directory, also with permission to
write files.
</para>
<para>
TECHNICAL NOTE: You can get around the need to allow the web server
user write access to compile templates. Smarty needs to compile the
templates only once. This can be done from the command line, using the
CGI version of PHP. example: "php -q index.php". Once the templates are
compiled, they should run fine from the web environment. If you change
a template, you must recompile from the command line again. If you do
not have the CGI version of PHP available and you are concerned about
world-writable directory access, you can chmod 777 the compile_dir, let
the templates compile once as the web server user, then change the
directory mode to 755. If you are using the caching feature of Smarty,
the cache directory must always have write access for the web server
user.
</para>
<para>
TECHNICAL NOTE: If you do not have access to the php.ini file, you can
change non-server settings (such as your include_path) with the
ini_set() command (available in PHP 4.0.4 or later.) example:
ini_set("include_path",".:/usr/local/lib/php");
</para>
<para>
Copy the Smarty.class.php, Smarty.addons.php and Config_File.class.php
scripts to a directory that is in your PHP include_path. NOTE: PHP will
try to create a directory alongside the executing script called
"templates_c". Be sure that directory permissions allow this to happen.
You will see PHP error messages if this fails. You can also create the
directory yourself before hand, and change the file ownership
accordingly. See below.
</para>
<para>
TECHNICAL NOTE: If you don't want to use include_path to find the
Smarty files, you can set the SMARTY_DIR constant to the full path to
your Smarty library files. Be sure the path ends with a slash!
</para>
<example>
<title>Example of installing Smarty</title>
<programlisting>
# be sure you are in the web server document tree
# this assumes your web server runs as user "nobody"
# and you are in a un*x environment
gtar -zxvf Smarty-[version].tar.gz
mkdir templates_c
chown nobody:nobody templates_c
chmod 700 templates_c
# if you are using caching, do the following
mkdir cache
chown nobody:nobody cache
chmod 700 cache
</programlisting>
</example>
<para>
Next, try running the index.php script from your web browser.
</para>
</sect1>
</chapter>
<chapter>
<title>Setting up Smarty</title>
<para>
There are several variables that are at the top of the Smarty.class.php
file. The default settings work for all of the examples and tutorials.
</para>
<sect1>
<title>Constants</title>
<para></para>
<sect2 id="constant.smarty.dir">
<title>SMARTY_DIR</title>
<para>
This should be the full system path to the location of the Smarty
class files. If this is not defined, then the include_path will be
used to locate the files. If defined, the path must end with a
slash.
</para>
<example>
<title>SMARTY_DIR</title>
<programlisting>
// set path to Smarty directory
define("SMARTY_DIR","/usr/local/lib/php/Smarty/");
require_once(SMARTY_DIR."Smarty.class.php");
</programlisting>
</example>
</sect2>
</sect1>
<sect1>
<title>Configuration variables</title>
<para></para>
<sect2 id="setting.template.dir">
<title>$template_dir</title>
<para>
This is the name of the default template directory. If you do
not supply a resource type when including files, they will be
found here. By default this is "./templates", meaning that it
will look for the templates directory in the same directory as
the executing php script.
</para>
<para>
TECHNICAL NOTE: It is not mandatory to put this directory under
the web server document root.
</para>
</sect2>
<sect2 id="setting.compile.dir">
<title>$compile_dir</title>
<para>
This is the name of the directory where compiled templates are
located. By default this is "./templates_c", meaning that it
will look for the compile directory in the same directory as
the executing php script. This was added to Smarty version
1.2.1.
</para>
<para>
TECHNICAL NOTE: This setting must be either a relative or
absolute path. include_path is not used for writing files.
</para>
<para>
TECHNICAL NOTE: It is not mandatory to put this directory under
the web server document root.
</para>
</sect2>
<sect2 id="setting.config.dir">
<title>$config_dir</title>
<para>
This is the directory used to store config files used in the
templates. Default is "./configs", meaning that it will look
for the configs directory in the same directory as the
executing php script.
</para>
<para>
TECHNICAL NOTE: It is not mandatory to put this directory under
the web server document root.
</para>
</sect2>
<sect2 id="setting.debugging">
<title>$debugging</title>
<para>
This enables the <link
linkend="chapter.debugging.console">debugging console</link>.
The console is a javascript window that informs you of the
included templates and assigned variables for the current
template page.
</para>
<para>
NOTE: This was added to Smarty 1.4.3.
</para>
</sect2>
<sect2 id="setting.debug.tpl">
<title>$debug_tpl</title>
<para>
This is the name of the template file used for the debugging
console.
</para>
<para>
NOTE: This was added to Smarty 1.4.3.
</para>
</sect2>
<sect2 id="setting.debugging.ctrl">
<title>$debugging_ctrl</title>
<para>
This allows alternate ways to enable debugging. NONE means no
alternate methods are allowed. URL means when the keyword
SMARTY_DEBUG is found in the QUERY_STRING, debugging is enabled
for that invocation of the script. If $debugging is true, this
value is ignored.
</para>
<para>
NOTE: This was added to Smarty 1.4.4.
</para>
</sect2>
<sect2 id="setting.global.assign">
<title>$global_assign</title>
<para>
This is a list of variables that are always implicitly assigned
to the template engine. This is handy for making global
variables or server variables available to all templates
without having to manually assign them. Each element in the
$global_assign should be either a name of the global variable,
or a key/value pair, where the key is the name of the global
array and the value is the array of variables to be assigned
from that global array. $SCRIPT_NAME is globally assigned by
default from $HTTP_SERVER_VARS.
</para>
</sect2>
<sect2 id="setting.undefined">
<title>$undefined</title>
<para>
This sets the value of $undefined for Smarty, default is null.
Currently this is only used to set undefined variables in
$global_assign to a default value.
</para>
</sect2>
<sect2>
<title>$compile_check</title>
<para>
Upon each invocation of the PHP application, Smarty tests to
see if the current template has changed (later time stamp)
since the last time it was compiled. If it has changed, it
recompiles that template. As of 1.4.0, if the template has not
been compiled, it will compile regardless of this setting. By
default this variable is set to true. Once an application is
put into production (templates won't be changing), the
compile_check step is no longer needed. Be sure to set
$compile_check to "false" to improve performance! Note that if
you change this to "false" and a template file is changed, you
will *not* see the change since the template will not get
recompiled. If caching is enabled and compile_check is enabled,
then the cache files will get regenerated if an involved
template file was updated. See <link
linkend="setting.force.compile">$force_compile</link> or <link
linkend="api.clear.compiled.tpl">clear_compiled_tpl</link>.
</para>
</sect2>
<sect2 id="setting.force.compile">
<title>$force_compile</title>
<para>
This forces Smarty to (re)compile templates on every
invocation. This setting overrides $compile_check. By default
this is disabled. This is handy for development and debugging.
It should never be used in a production environment. If caching
is enabled, the cache file(s) will be regenerated every time.
</para>
</sect2>
<sect2 id="setting.caching">
<title>$caching</title>
<para>
This tells Smarty whether or not to cache the output of the
templates. By default this is set to false. If your templates
generate redundant redundant content over and over again and
again repeatedly, it is advisable to turn on caching. This will
result in significant performance gains. You can also have
multiple caches for the same template. See <link
linkend="api.is.cached">is_cached</link> for details. This was
added to Smarty 1.3.0.
</para>
<para>
If $compile_check is enabled, the cached content will be
regenerated if any of the involved templates are changed. (new
to 1.4.6). If $force_compile is enabled, the cached content
will always be regenerated (new to 1.4.7).
</para>
</sect2>
<sect2 id="setting.cache.dir">
<title>$cache_dir</title>
<para>
This is the name of the directory where template caches are
stored. By default this is "./cache", meaning that it will
look for the cache directory in the same directory as the
executing php script. This was added to Smarty version 1.3.0.
You can also use your own custom cache handler function to
control cache files, which will ignore this setting.
</para>
<para>
TECHNICAL NOTE: This setting must be either a relative or
absolute path. include_path is not used for writing files.
</para>
<para>
TECHNICAL NOTE: It is not mandatory to put this directory under
the web server document root.
</para>
</sect2>
<sect2 id="setting.cache.lifetime">
<title>$cache_lifetime</title>
<para>
This is the length of time in seconds that a template cache is
valid. Once this time has expired, the cache will be
regenerated. $caching must be set to "true" for this setting to
work. You can also force the cache to expire with <link
linkend="api.clear.all.cache">clear_all_cache</link>. This was
added to Smarty 1.3.0.
</para>
</sect2>
<sect2 id="setting.insert.tag.check">
<title>$insert_tag_check</title>
<para>
If you have $caching enabled and you do not use the <link
linkend="builtin.functions.insert">insert</link> tag anywhere in
your templates, set this to false. This saves the insert tag
search, speeding up cached page fetches.
</para>
</sect2>
<sect2 id="setting.cache.handler.func">
<title>$cache_handler_func</title>
<para>
You can supply a custom function to handle cache files instead
of using the built-in method using the $cache_dir. See the
custom cache handler function section for details.
</para>
</sect2>
<sect2 id="setting.tpl.file.ext">
<title>$tpl_file_ext</title>
<para>
This is the extention used for template files. By default this
is ".tpl". All other files in the template directory are
ignored.
</para>
<para>
NOTE: $tpl_file_ext is no longer needed in 1.4.0. This is kept
for backward compatability.
</para>
</sect2>
<sect2 id="setting.php.handling">
<title>$php_handling</title>
<para>
This tells Smarty how to handle PHP code embedded in the
tempalates. There are four possible settings, default being
SMARTY_PHP_PASSTHRU. Note that this does NOT affect php code
within <link linkend="builtin.functions.php">{php}{/php}</link>
tags in the template.
</para>
<itemizedlist>
<listitem><para>SMARTY_PHP_PASSTHRU - Smarty echos tags as-is.</para></listitem>
<listitem><para>SMARTY_PHP_QUOTE - Smarty quotes the tags as
html entities.</para></listitem>
<listitem><para>SMARTY_PHP_REMOVE - Smarty removes the tags from
the templates.</para></listitem>
<listitem><para>SMARTY_PHP_ALLOW - Smarty will execute the tags
as PHP code.</para></listitem>
</itemizedlist>
<para>
NOTE: Embedding PHP code into templates is highly discouraged.
Use <link linkend="custom.functions">custom functions</link> or
<link linkend="variable.modifiers">modifiers</link> instead.
</para>
</sect2>
<sect2 id="setting.security">
<title>$security</title>
<para>
$security true/false, default is false. Security is good for
situations when you have untrusted parties editing the templates
(via ftp for example) and you want to reduce the risk of system
security compromises through the template language. Turning on
security enforces the following rules to the template language,
unless specifially overridden with $security_settings:
</para>
<itemizedlist>
<listitem><para>If $php_handling is set to SMARTY_PHP_ALLOW, this is
implicitly changed to SMARTY_PHP_PASSTHRU</para></listitem>
<listitem><para>PHP functions are not allowed in IF statements,
except those specified in the $security_settings</para></listitem>
<listitem><para>templates can only be included from directories
listed in the $secure_dir array</para></listitem>
<listitem><para>local files can only be fetched from directories
listed in the $secure_dir array using {fetch}</para></listitem>
<listitem><para>{php}{/php} tags are not allowed</para></listitem>
<listitem><para>PHP functions are not allowed as modifiers, except
those specified in the $security_settings</para></listitem>
</itemizedlist>
<para>
NOTE: Security features were added to Smarty 1.4.3.
</para>
</sect2>
<sect2 id="setting.secure.dir">
<title>$secure_dir</title>
<para>
This is an array of all local directories that are considered
secure. {include} and {fetch} use this when security is enabled.
</para>
</sect2>
<sect2 id="setting.security.settings">
<title>$security_settings</title>
<para>
These are used to override or specify the security settings when
security is enabled. These are the possible settings:
</para>
<itemizedlist>
<listitem><para>PHP_HANDLING - true/false. If set to true, the
$php_handling setting is not checked for security.</para></listitem>
<listitem><para>IF_FUNCS - This is an array of the names of permitted
PHP functions in IF statements.</para></listitem>
<listitem><para>INCLUDE_ANY - true/false. If set to true, any
template can be included from the file system, regardless of the
$secure_dir list.</para></listitem>
<listitem><para>PHP_TAGS - true/false. If set to true, {php}{/php}
tags are permitted in the templates.</para></listitem>
<listitem><para>MODIFIER_FUNCS - This is an array of the names of permitted
PHP functions used as variable modifiers.</para></listitem>
</itemizedlist>
</sect2>
<sect2 id="setting.trusted.dir">
<title>$trusted_dir</title>
<para>
$trusted_dir is only for use when $security is enabled.
This is an array of all directories that are considered
trusted. When a directory is considered trusted, $security is
temporarily disabled while any templates from here are
included. New in Smarty 1.5.0.
</para>
</sect2>
<sect2 id="setting.left.delimiter">
<title>$left_delimiter</title>
<para>
This is the left delimiter used by the template language.
Default is "{".
</para>
</sect2>
<sect2 id="setting.right.delimiter">
<title>$right_delimiter</title>
<para>
This is the right delimiter used by the template language.
Default is "}".
</para>
</sect2>
<sect2 id="setting.custom.funcs">
<title>$custom_funcs</title>
<para>
This is a mapping of the names of <link
linkend="custom.functions">custom functions</link> in the
template to the names of functions in PHP. The default custom
functions that come bundled with Smarty are located in
Smarty.addons.php.
</para>
</sect2>
<sect2 id="setting.custom.mods">
<title>$custom_mods</title>
<para>
This is a mapping of the names of variable
<link linkend="variable.modifiers">modifiers</link> in the template to
the names of functions in PHP. The default variable modifiers
that come bundled with Smarty are located in
Smarty.addons.php.
</para>
</sect2>
<sect2 id="setting.show.info.header">
<title>$show_info_header</title>
<para>
Shows an HTML comment at the beginning of the templates output,
displaying smarty version and date generated. Default is false.
</para>
</sect2>
<sect2 id="setting.show.info.include">
<title>$show_info_include</title>
<para>
Shows an HTML comment before and after each included template.
Default is false.
</para>
</sect2>
<sect2 id="setting.compiler.class">
<title>$compiler_class</title>
<para>
Specifies the name of the compiler class that Smarty will use
to compile the templates. The default is 'Smarty_Compiler'. For
advanced users only.
</para>
</sect2>
<sect2 id="setting.resource.funcs">
<title>$resource_funcs</title>
<para>
An array of functions that resource handlers are mapped to.
</para>
</sect2>
<sect2 id="setting.prefilter.funcs">
<title>$prefilter_funcs</title>
<para>
An array of functions that templates are filtered through before
compilation.
</para>
</sect2>
<sect2 id="setting.postfilter.funcs">
<title>$postfilter_funcs</title>
<para>
An array of functions that templates are filtered through after
compilation.
</para>
</sect2>
<sect2 id="setting.request.vars.order">
<title>$request_vars_order</title>
<para>
The order in which request variables are registered, similar to
variables_order in php.ini
</para>
</sect2>
<sect2 id="setting.compile.id">
<title>$compile_id</title>
<para>
Persistant compile identifier. As an alternative to passing the
same compile_id to each and every function call, you can set this
compile_id and it will be used implicitly thereafter.
</para>
</sect2>
</sect1>
</chapter>
<chapter>
<title>Smarty API</title>
<para>
These functions are used in the PHP portion of your application.
</para>
<sect1>
<title>API Functions</title>
<sect2 id="api.assign">
<title>assign</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>assign</function></funcdef>
<paramdef>mixed <parameter>var</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>assign</function></funcdef>
<paramdef>string <parameter>varname</parameter></paramdef>
<paramdef>mixed <parameter>var</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This is used to assign values to the templates. You can
explicitly pass name/value pairs, or associative arrays
containing the name/value pairs.
</para>
<example>
<title>assign</title>
<programlisting>
// passing name/value pairs
$smarty->assign("Name","Fred");
$smarty->assign("Address",$address);
// passing an associative array
$smarty->assign(array("city" => "Lincoln","state" => "Nebraska"));
</programlisting>
</example>
</sect2>
<sect2 id="api.assign.debug.info">
<title>assign_debug_info</title>
<para>
This is used to assign debugging data to the template. This is
used by the <link linkend="chapter.debugging.console">debugging
console</link>, and should probably never be used directly.
</para>
<example>
<title>assign_debug_info</title>
<programlisting>
// passing name/value pairs
$smarty->assign("Name","Fred");
$smarty->assign("Address",$address);
// passing an associative array
$smarty->assign(array("city" => "Lincoln","state" => "Nebraska"));
</programlisting>
</example>
</sect2>
<sect2 id="api.append">
<title>append</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>append</function></funcdef>
<paramdef>mixed <parameter>var</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>append</function></funcdef>
<paramdef>string <parameter>varname</parameter></paramdef>
<paramdef>mixed <parameter>var</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This is used to append data to variables in the template. You
can explicitly pass name/value pairs, or associative arrays
containing the name/value pairs.
</para>
<example>
<title>append</title>
<programlisting>
// passing name/value pairs
$smarty->append("Name","Fred");
$smarty->append("Address",$address);
// passing an associative array
$smarty->append(array("city" => "Lincoln","state" => "Nebraska"));
</programlisting>
</example>
</sect2>
<sect2 id="api.clear.assign">
<title>clear_assign</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>clear_assign</function></funcdef>
<paramdef>string <parameter>var</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This clears the value of an assigned variable. This
can be a single value, or an array of values. Array
functionality was added to Smarty 1.3.0.
</para>
<example>
<title>clear_assign</title>
<programlisting>
// clear a single variable
$smarty->clear_assign("Name");
// clear multiple variables
$smarty->clear_assign(array("Name","Address","Zip"));
</programlisting>
</example>
</sect2>
<sect2 id="api.clear.all.assign">
<title>clear_all_assign</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>clear_all_assign</function></funcdef>
<paramdef><parameter></parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This clears the values of all assigned variables.
</para>
<example>
<title>clear_all_assign</title>
<programlisting>
// clear all assigned variables
$smarty->clear_all_assign();
</programlisting>
</example>
</sect2>
<sect2 id="api.clear.cache">
<title>clear_cache</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>clear_cache</function></funcdef>
<paramdef>string <parameter>template</parameter></paramdef>
<paramdef>string <parameter>cache id</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This clears the cache for the specified template. If you have
multiple caches for this template, you can clear a specific
cache by supplying the cache id as the second parameter. See the
<link linkend="section.caching">caching section</link> for more
information. This was added to Smarty 1.3.0.
</para>
<example>
<title>clear_cache</title>
<programlisting>
// clear the cache for a template
$smarty->clear_cache("index.tpl");
// clear the cache for a particular cache id in an multiple-cache template
$smarty->clear_cache("index.tpl","CACHEID");
</programlisting>
</example>
</sect2>
<sect2 id="api.clear.all.cache">
<title>clear_all_cache</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>clear_all_cache</function></funcdef>
<paramdef><parameter></parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This clears the entire template cache. This was added to Smarty
1.3.0.
</para>
<example>
<title>clear_all_cache</title>
<programlisting>
// clear the entire cache
$smarty->clear_all_cache();
</programlisting>
</example>
</sect2>
<sect2 id="api.clear.compiled.tpl">
<title>clear_compiled_tpl</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>clear_compiled_tpl</function></funcdef>
<paramdef>string <parameter>tpl_file</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This clears the compiled version of the specified template
resource, or all compiled template files if one is not specified.
This function is for advanced use only, not normally needed.
</para>
<example>
<title>clear_compiled_tpl</title>
<programlisting>
// clear a specific template resource
$smarty->clear_compiled_tpl("index.tpl");
// clear entire compile directory
$smarty->clear_compiled_tpl();
</programlisting>
</example>
</sect2>
<sect2 id="api.register.function">
<title>register_function</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>register_function</function></funcdef>
<paramdef>string <parameter>funcname</parameter></paramdef>
<paramdef>string <parameter>funcimpl</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Use this to dynamically register functions with Smarty. Pass in
the template function name, followed by the actual PHP function
name that it will map to.
</para>
<example>
<title>register_function</title>
<programlisting>
$smarty->register_function("date_now","print_current_date");
function print_current_date ($params) {
extract($params);
if(empty($format))
$format="%b %e, %Y";
echo strftime($format,time());
}
// now you can use this in Smarty to print the current date: {date_now}
// or, {date_now format="%Y/%m/%d"} to format it.
</programlisting>
</example>
</sect2>
<sect2 id="api.unregister.function">
<title>unregister_function</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>unregister_function</function></funcdef>
<paramdef>string <parameter>funcname</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Use this to dynamically unregister functions with Smarty. Pass in
the Smarty function name.
</para>
<example>
<title>unregister_function</title>
<programlisting>
// we don't want template designers to have access to system files
$smarty->unregister_function("fetch");
</programlisting>
</example>
</sect2>
<sect2 id="api.register.modifier">
<title>register_modifier</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>register_modifier</function></funcdef>
<paramdef>string <parameter>modname</parameter></paramdef>
<paramdef>string <parameter>funcimpl</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Use this to dynamically register modifiers with Smarty. Pass in
the template modifier name, followed by the actual PHP function name
that it will map to.
</para>
<example>
<title>register_modifier</title>
<programlisting>
// let's map PHP's stripslashes function to a Smarty modifier.
$smarty->register_modifier("sslash","stripslashes");
// now you can use {$var|sslash} to strip slashes from variables
</programlisting>
</example>
</sect2>
<sect2 id="api.unregister.modifier">
<title>unregister_modifier</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>unregister_modifier</function></funcdef>
<paramdef>string <parameter>modname</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Use this to dynamically unregister modifiers with Smarty. Pass in
the template modifier name.
</para>
<example>
<title>unregister_modifier</title>
<programlisting>
// we don't want template designers to strip tags from elements
$smarty->unregister_modifier("strip_tags");
</programlisting>
</example>
</sect2>
<sect2 id="api.register.resource">
<title>register_resource</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>register_resource</function></funcdef>
<paramdef>string <parameter>resource_name</parameter></paramdef>
<paramdef>string <parameter>function_name</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Use this to dynamically register a resource to fetch templates
with Smarty. See <link
linkend="section.template.resources">template resources</link>
for more information on how to setup a function for fetching
templates.
</para>
<example>
<title>register_resource</title>
<programlisting>
$smarty->register_resource("db","get_db_template");
</programlisting>
</example>
</sect2>
<sect2 id="api.unregister.resource">
<title>unregister_resource</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>unregister_resource</function></funcdef>
<paramdef>string <parameter>resource_name</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Use this to dynamically unregister a resource.
</para>
<example>
<title>unregister_resource</title>
<programlisting>
$smarty->unregister_resource("db");
</programlisting>
</example>
</sect2>
<sect2 id="api.register.prefilter">
<title>register_prefilter</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>register_prefilter</function></funcdef>
<paramdef>string <parameter>function_name</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Use this to dynamically register prefilters to run templates
through before they are compiled. See <link
linkend="section.template.prefilters">template prefilters</link> for
more information on how to setup a prefiltering function.
</para>
<example>
<title>register_prefilter</title>
<programlisting>
$smarty->register_prefilter("remove_dw_comments");
</programlisting>
</example>
</sect2>
<sect2 id="api.unregister.prefilter">
<title>unregister_prefilter</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>unregister_prefilter</function></funcdef>
<paramdef>string <parameter>function_name</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Use this to dynamically unregister a prefilter.
</para>
<example>
<title>unregister_prefilter</title>
<programlisting>
$smarty->unregister_prefilter("embed_asp_jokes");
</programlisting>
</example>
</sect2>
<sect2 id="api.register.postfilter">
<title>register_postfilter</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>register_postfilter</function></funcdef>
<paramdef>string <parameter>function_name</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Use this to dynamically register postfilters to run templates
through after they are compiled. See <link
linkend="section.template.postfilters">template postfilters</link> for
more information on how to setup a postfiltering function.
</para>
<example>
<title>register_postfilter</title>
<programlisting>
$smarty->register_postfilter("remove_dw_comments");
</programlisting>
</example>
</sect2>
<sect2 id="api.unregister.postfilter">
<title>unregister_postfilter</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>unregister_postfilter</function></funcdef>
<paramdef>string <parameter>function_name</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Use this to dynamically unregister a postfilter.
</para>
<example>
<title>unregister_postfilter</title>
<programlisting>
$smarty->unregister_postfilter("embed_asp_jokes");
</programlisting>
</example>
</sect2>
<sect2 id="api.register.compiler.function">
<title>register_compiler_function</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>register_compiler_function</function></funcdef>
<paramdef>string <parameter>funcname</parameter></paramdef>
<paramdef>string <parameter>funcimpl</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Use this to register a template compiler function. These
functions are called only during compilation of the template.
They are useful for injecting PHP code or time-sensitive static
content into the template. The first parameter specifies the
template function name, and the second one the PHP function
implementing it. If there is both a compiler function and a
custom function registered under the same name, the compiler
function has precedence. For advanced users only.
</para>
<para>
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 code to be injected into the compiled
template.
</para>
<example>
<title>register_compiler_function</title>
<programlisting>
// PHP code
$smarty-&gt;register_compiler_function("tplheader", "smarty_template_header");
function smarty_template_header($tag_arg_string, $smarty)
{
return "\necho '" . $smarty-&gt;_current_file . "' compiled at " . date('Y-m-d H:M'). ";";
}
{* this function gets executed at compile time only *}
{tplheader }
</programlisting>
</example>
</sect2>
<sect2 id="api.unregister.compiler.function">
<title>unregister_compiler_function</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>unregister_compiler_function</function></funcdef>
<paramdef>string <parameter>funcname</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
Use this to unregister a compiler function.
</para>
<example>
<title>unregister_compiler_function</title>
<programlisting>
$smarty->unregister_compiler_function("tplheader");
</programlisting>
</example>
</sect2>
<sect2 id="api.is.cached">
<title>is_cached</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>is_cached</function></funcdef>
<paramdef>string <parameter>template</parameter></paramdef>
<paramdef>[string <parameter>cache_id</parameter>]</paramdef>
</funcprototype>
</funcsynopsis>
<para>
This returns true if there is a valid cache for this template.
This only works if <link
linkend="setting.caching">caching</link> is set to true. This
was added to Smarty 1.3.0.
</para>
<example>
<title>is_cached</title>
<programlisting>
$smarty->caching = true;
if(!$smarty->is_cached("index.tpl")) {
// do database calls, assign vars here
}
$smarty->display("index.tpl");
</programlisting>
</example>
<para>
You can also pass a cache id as an an optional second parameter
in case you want multiple caches for the given template.
</para>
<example>
<title>is_cached with multiple-cache template</title>
<programlisting>
$smarty->caching = true;
if(!$smarty->is_cached("index.tpl","FrontPage")) {
// do database calls, assign vars here
}
$smarty->display("index.tpl","FrontPage");
</programlisting>
</example>
</sect2>
<sect2 id="api.get.template.vars">
<title>get_template_vars</title>
<funcsynopsis>
<funcprototype>
<funcdef>array <function>get_template_vars</function></funcdef>
<paramdef><parameter></parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This gets an array of the currently assigned template vars.
</para>
<example>
<title>get_template_vars</title>
<programlisting>
// get all assigned template vars
$tpl_vars = $smarty->get_template_vars();
// take a look at them
var_dump($tpl_vars);
</programlisting>
</example>
</sect2>
<sect2 id="api.display">
<title>display</title>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>display</function></funcdef>
<paramdef>string <parameter>template</parameter></paramdef>
<paramdef>string <parameter>cache id</parameter></paramdef>
<paramdef>string <parameter>compile id</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This displays the template. Supply a valid <link
linkend="section.template.resources">template resource</link>
type and path. As an optional second parameter, you can pass a
cache id. See the <link linkend="section.caching">caching
section</link> for more information.
</para>
<para>
As an optional third parameter, you can pass a compile id. This
is in the event that you want to compile different versions of
the same template, such as having separate templates compiled
for different languages. This was added to Smarty 1.4.5.
</para>
<example>
<title>display</title>
<programlisting>
include("Smarty.class.php");
$smarty = new Smarty;
// only do db calls if cache doesn't exist
if(!$smarty->is_cached("index.tpl"))
{
// dummy up some data
$address = "245 N 50th";
$db_data = array(
"City" => "Lincoln",
"State" => "Nebraska",
"Zip" = > "68502"
);
$smarty->assign("Name","Fred");
$smarty->assign("Address",$address);
$smarty->assign($db_data);
}
// display the output
$smarty->display("index.tpl");
</programlisting>
</example>
</sect2>
<sect2 id="api.fetch">
<title>fetch</title>
<funcsynopsis>
<funcprototype>
<funcdef>string <function>fetch</function></funcdef>
<paramdef>string <parameter>template</parameter></paramdef>
<paramdef>[string <parameter>cache_id</parameter>]</paramdef>
<paramdef>[string <parameter>compile_id</parameter>]</paramdef>
</funcprototype>
</funcsynopsis>
<para>
This returns the template output instead of displaying it.
Supply a valid <link
linkend="section.template.resources">template resource</link>
type and path. As an optional second parameter, you can pass a
cache id. See the <link linkend="section.caching">caching
section</link> for more information.
</para>
<para>
As an optional third parameter, you can pass a compile id. This
is in the event that you want to compile different versions of
the same template, such as having separate templates compiled
for different languages. This was added to Smarty 1.4.5.
</para>
<example>
<title>fetch</title>
<programlisting>
include("Smarty.class.php");
$smarty = new Smarty;
// only do db calls if cache doesn't exist
if(!$smarty->is_cached("index.tpl"))
{
// dummy up some data
$address = "245 N 50th";
$db_data = array(
"City" => "Lincoln",
"State" => "Nebraska",
"Zip" = > "68502"
);
$smarty->assign("Name","Fred");
$smarty->assign("Address",$address);
$smarty->assign($db_data);
}
// capture the output
$output = $smarty->fetch("index.tpl");
// do something with $output here
echo $output;
</programlisting>
</example>
</sect2>
</sect1>
<sect1 id="section.template.resources">
<title>Template Resources</title>
<para>
Your templates may come from a variety of sources. When you display or
fetch a template, or when you include a template from within another
template, you supply a resource type, followed by the appropriate path
and template name. Template resources were added to Smarty 1.4.0.
</para>
<sect2>
<title>Templates from $template_dir</title>
<para>
Templates from the $template_dir do not require a template
resource, although you can use the file: resource for consistancy.
Just supply the path to the template you want to use relative to
the $template_dir root directory.
</para>
<example>
<title>using templates from $template_dir</title>
<programlisting>
// from PHP script
$smarty->display("index.tpl");
$smarty->display("admin/menu.tpl");
$smarty->display("file:admin/menu.tpl"); // same as one above
{* from within Smarty template *}
{include file="index.tpl"}
{include file="file:index.tpl"} {* same as one above *}
</programlisting>
</example>
</sect2>
<sect2>
<title>Templates from any directory</title>
<para>
Templates outside of the $template_dir require the file: template
resource type, followed by the absolute path and name of the
template.
</para>
<example>
<title>using templates from any directory</title>
<programlisting>
// from PHP script
$smarty->display("file:/export/templates/index.tpl");
$smarty->display("file:/path/to/my/templates/menu.tpl");
{* from within Smarty template *}
{include file="file:/usr/local/share/templates/navigation.tpl"}
</programlisting>
</example>
</sect2>
<sect2>
<title>Templates from a function call</title>
<para>
You can get templates from a custom function call, such as
retrieving templates from a database. You do this by first
registering your resource handler function, then creating your
function to get the template. Smarty expects your function to be of
this form: funcname($tpl_name,&amp;$tpl_source,
&amp;$tpl_timestamp[, boolean]) {} $tpl_name is passed into the
function, and your function should populate $tpl_source and
$tpl_timestamp with the template source and the last modified time
of the template respectively. The fourth parameter is a boolean
value, used for determining if the source should be returned or
not. Default this value to true in your function. If false gets
passed, you only need to return the timestamp parameter. This was
added to Smarty 1.4.6.
</para>
<example>
<title>using templates from a function call</title>
<programlisting>
// from PHP script
// put this function somewhere in your application
function get_db_template ($tpl_name, &$tpl_source, &$tpl_timestamp,
$get_source=true) {
if($get_source) {
// do database calls (or whatever) here to fetch your template, populating
// $tpl_source and $tpl_timestamp.
$tpl_source = "This is a simulation of a template fetched from a db.";
$tpl_timestamp = mktime();
} else {
// just populate $tpl_timestamp.
$tpl_timestamp = mktime();
}
return true;
}
// register the resource name "db"
$smarty->register_resource("db","get_db_template");
// using resource from php script
$smarty->display("db:index.tpl");
{* using resource from within Smarty template *}
{include file="db:/extras/navigation.tpl"}
</programlisting>
</example>
</sect2>
</sect1>
<sect1 id="section.template.prefilters">
<title>Template Prefilters</title>
<para>
Template prefilters are PHP functions that your templates are ran through
before they are compiled. This is good for preprocessing your templates
to remove unwanted comments, keeping an eye on what people are putting
in their templates, etc. Prefilters are processed in the order they are
<link linkend="api.register.prefilter">registered</link>.
</para>
<sect2>
<title>Example of a Template Prefilter</title>
<para>
Create a function in your application that Smarty will use as a
template prefilter. Smarty will pass the template source code as the
first argument, an expect the function to return the resulting
template source code.
</para>
<para>
NOTE: As of Smarty 1.4.5, the Smarty object is passed as the second
argument. This way you can reference and modify information in the
Smarty object from within the prefilter function.
</para>
<example>
<title>using a template prefilter</title>
<programlisting>
// put this in your application, or in Smarty.addons.php
function remove_dw_comments($tpl_source) {
return preg_replace("/&lt;!--#.*--&gt;/U","",$tpl_source);
}
// register the prefilter
$smarty->register_prefilter("remove_dw_comments");
$smarty->display("index.tpl");
{* from within Smarty template *}
&lt;!--# this line will get removed by the prefilter --&gt;
</programlisting>
</example>
</sect2>
</sect1>
<sect1 id="section.template.postfilters">
<title>Template Postfilters</title>
<para>
Template postfilters are PHP functions that your templates are ran through
after they are compiled. Postfilters are processed in the order they are
<link linkend="api.register.postfilter">registered</link>.
</para>
<sect2>
<title>Example of a Template Postfilter</title>
<para>
Create a function in your application that Smarty will use as a
template postfilter. Smarty will pass the template source code as the
first argument, an expect the function to return the resulting
template source code.
</para>
<para>
The Smarty object is passed as the second argument. This way you
can reference and modify information in the Smarty object from
within the prefilter function.
</para>
<example>
<title>using a template postfilter</title>
<programlisting>
// this program puts a
// put this in your application, or in Smarty.addons.php
function add_header_comment($tpl_source) {
return "<?php echo \"<!-- Created by Smarty! -->\n\" ?>\n".$tpl_source;
}
// register the postfilter
$smarty->register_postfilter("add_header_comment");
$smarty->display("index.tpl");
{* from within Smarty template *}
<!-- Created by Smarty! -->
{* rest of template content... *}
</programlisting>
</example>
</sect2>
</sect1>
<sect1 id="section.template.cache.handler.func">
<title>Template Cache Handling Function</title>
<para>
As an alternative to using the default file-based caching mechanism, you
can specify a custom cache handling function that will be used to read,
write and clear cached files.
</para>
<sect2>
<title>Example of a Template Cache Handling Function</title>
<para>
Create a function in your application that Smarty will use as a
cache handler. Set the name of it in the $cache_handler_func class
variable. Smarty will now use this to handle cached data. The first
argument is the action, which will be one of 'read', 'write' and
'clear'. The second parameter is the smarty object. The third
parameter is the cached content. Upon a write, Smarty passed th
cached content in this paramters. Upon a 'read', Smarty expects
your function to pass this by reference and populate it with the
cached data. Upon a 'clear', pass a dummy variable here since it is
not used. The fourth parameter is the name of the template file
(needed for read/write), the fifth parameter is the cache_id
(optional), and the sixth is the compile_id (optional)
</para>
<example>
<title>example using MySQL as a cache source</title>
<programlisting>
&lt;?php
/*
example usage:
include('Smarty.class.php');
include('mysql_cache_handler.php');
$smarty = new Smarty;
$smarty-&gt;cache_handler_func='mysql_cache_handler';
$smarty-&gt;display('index.tpl');
mysql database is expected in this format:
create database SMARTY_CACHE;
create table CACHE_PAGES(
CacheID char(32) PRIMARY KEY,
CacheContents MEDIUMTEXT NOT NULL
);
*/
function mysql_cache_handler($action, &$smarty_obj, &$cache_content, $tpl_file=null, $cache_id=null, $compile_id=null) {
// set db host, user and pass here
$db_host = 'localhost';
$db_user = 'myuser';
$db_pass = 'mypass';
$db_name = 'SMARTY_CACHE';
$use_gzip = false;
// create unique cache id
$CacheID = md5($tpl_file.$cache_id.$compile_id);
if(! $link = mysql_pconnect($db_host, $db_user, $db_pass)) {
$smarty_obj-&gt;_trigger_error_msg("cache_handler: could not connect to database");
return false;
}
mysql_select_db($db_name);
switch ($action) {
case 'read':
// save cache to database
$results = mysql_query("select CacheContents from CACHE_PAGES where CacheID='$CacheID'");
if(!$results) {
$smarty_obj-&gt;_trigger_error_msg("cache_handler: query failed.");
}
$row = mysql_fetch_array($results,MYSQL_ASSOC);
if($use_gzip && function_exists("gzuncompress")) {
$cache_contents = gzuncompress($row["CacheContents"]);
} else {
$cache_contents = $row["CacheContents"];
}
$return = $results;
break;
case 'write':
// save cache to database
if($use_gzip && function_exists("gzcompress")) {
// compress the contents for storage efficiency
$contents = gzcompress($cache_content);
} else {
$contents = $cache_content;
}
$results = mysql_query("replace into CACHE_PAGES values(
'$CacheID',
'".addslashes($contents)."')
");
if(!$results) {
$smarty_obj-&gt;_trigger_error_msg("cache_handler: query failed.");
}
$return = $results;
break;
case 'clear':
// clear cache info
if(empty($cache_id) && empty($compile_id) && empty($tpl_file)) {
// clear them all
$results = mysql_query("delete from CACHE_PAGES");
} else {
$results = mysql_query("delete from CACHE_PAGES where CacheID='$CacheID'");
}
if(!$results) {
$smarty_obj-&gt;_trigger_error_msg("cache_handler: query failed.");
}
$return = $results;
break;
default:
// error, unknown action
$smarty_obj-&gt;_trigger_error_msg("cache_handler: unknown action \"$action\"");
$return = false;
break;
}
mysql_close($link);
return $return;
}
?&gt;
</programlisting>
</example>
</sect2>
</sect1>
</chapter>
<chapter>
<title>Smarty Templates</title>
<para>
The templates are the heart of Smarty. These are the files that the designers
work with. They're basically pages made up of static content interspersed with
template markup tags. These tags are placeholders for variables or blocks of logic.
</para>
<sect1>
<title>Syntax</title>
<para>
For these examples, we will assume that you are using the default
template tag delimiters, which are "{" and "}". In Smarty, all content
outside of delimiter tags is displayed as static content, or unchanged.
When Smarty encounters template tags {}, it attempts to interpret what is
between the tags, and displays the appropriate output in place of them.
</para>
<sect2>
<title>Variables assigned from PHP</title>
<para>
Variables that are assigned from PHP are referenced by preceding
them with a dollar sign ($) and enclosing the variable in delimiters
like so: $varname
</para>
<example>
<title>displaying assigned variables</title>
<programlisting>
Hello {$firstname}, glad to see you could make it.
&lt;p&gt;
Your last login was on {$lastLoginDate}.
OUTPUT:
Hello Doug, glad to see you could make it.
&lt;p&gt;
Your last login was on January 11th, 2001.
</programlisting>
</example>
</sect2>
<sect2>
<title>Associative arrays</title>
<para>
You can also reference associative array variables that are
assigned from PHP by specifying the key after the '.' (period)
symbol.
</para>
<example>
<title>displaying assigned associative array variables</title>
<programlisting>
{$Contacts.fax}&lt;br&gt;
{$Contacts.email}&lt;br&gt;
{* you can print arrays of arrays as well *}
{$Contacts.phone.home}&lt;br&gt;
{$Contacts.phone.cell}&lt;br&gt;
OUTPUT:
555-222-9876&lt;br&gt;
zaphod@slartibartfast.com&lt;br&gt;
555-444-3333&lt;br&gt;
555-111-1234&lt;br&gt;
</programlisting>
</example>
</sect2>
<sect2>
<title>Array indexes</title>
<para>
You can reference arrays by their index, much like native PHP
syntax.
</para>
<example>
<title>displaying arrays by index</title>
<programlisting>
{$Contacts[0]}&lt;br&gt;
{$Contacts[1]}&lt;br&gt;
{* you can print arrays of arrays as well *}
{$Contacts[0][0]}&lt;br&gt;
{$Contacts[0][1]}&lt;br&gt;
</programlisting>
</example>
</sect2>
<sect2>
<title>Objects</title>
<para>
Properties of objects assigned from PHP can be referenced
by specifying the property name after the '-&gt;' symbol.
</para>
<example>
<title>displaying object properties</title>
<programlisting>
name: {$person-&gt;name}&lt;br&gt;
email: {$person-&gt;email}&lt;br&gt;
OUTPUT:
name: Zaphod Beeblebrox&lt;br&gt;
email: zaphod@slartibartfast.com&lt;br&gt;
</programlisting>
</example>
</sect2>
<sect2>
<title>Variables passed from config files</title>
<para>
Variables that are passed in from config files are displayed by enclosing
them with hash marks (#) and enclosing the variable in delimiters
like so: {#varname#}
</para>
<example>
<title>displaying config variables</title>
<programlisting>
&lt;html&gt;
&lt;title&gt;{#pageTitle#}&lt;/title&gt;
&lt;body bgcolor="{#bodyBgColor#}"&gt;
&lt;table border="{#tableBorderSize#}" bgcolor="{#tableBgColor#}"&gt;
&lt;tr bgcolor="{#rowBgColor#}"&gt;
&lt;td&gt;First&lt;/td&gt;
&lt;td&gt;Last&lt;/td&gt;
&lt;td&gt;Address&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
</programlisting>
</example>
<para>
Config file variables cannot be displayed until
after they are loaded in from a config file. This procedure is
explained later in this document under
<link linkend="builtin.functions.configload">config_load</link>.
</para>
</sect2>
<sect2>
<title>Variables internal to template</title>
<para>
Variables that are internal to the templates are displayed by using
the special variable {$smarty}. For instance, you can reference the
current date/time with {$smarty.now}, or <link
linkend="builtin.functions.section">section loops</link> have
properties that are internal variables.
</para>
</sect2>
<sect2>
<title>{$smarty} reserved variable</title>
<para>
You can access reserved variables in Smarty via the special
variable {$smarty}. You can access request variables such as get,
post, cookies, server, env and session variables with the syntax in
the following examples.
</para>
<para>
The special variable {$smarty} was added to Smarty 1.4.4.
</para>
<example>
<title>displaying request variables</title>
<programlisting>
{* display the variable "page" given in the URL, or from a form using the GET method *}
{$smarty.get.page}
{* display the variable "page" from a form using the POST method *}
{$smarty.post.page}
{* display the value of the cookie "username" *}
{$smarty.cookies.username}
{* display the server variable "SERVER_NAME" *}
{$smarty.server.SERVER_NAME}
{* display the system environment variable "PATH" *}
{$smarty.env.PATH}
{* display the php session variable "id" *}
{$smarty.session.id}
{* display the variable "username" from merged get/post/cookies/server/env *}
{$smarty.request.username}
</programlisting>
</example>
<para>
The current date can be displayed with {$smarty.now}. This is a unix
timestamp of the current date/time.
</para>
<example>
<title>displaying current date</title>
<programlisting>
{* use the date_formate modifier to format the date *}
{$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}
</programlisting>
</example>
</sect2>
<sect2>
<title>Functions</title>
<para>
Functions are processed and displayed by enclosing the function and its
attributes into delimiters like so: {funcname attr1="val" attr2="val"}
</para>
<example>
<title>function syntax</title>
<programlisting>
{config_load file="colors.conf"}
{include file="header.tpl"}
{if $name eq "Fred"}
You are not allowed here
{else}
Welcome, &lt;font color="{#fontColor#}"&gt;{$name}!&lt;/font&gt;
{/if}
{include file="footer.tpl"}
</programlisting>
</example>
<para>
Both built-in functions and custom functions have the same syntax
in the templates. Built-in functions are the inner workings of
Smarty, such as {if}, {section} and {strip}. They cannot be
modified. Custom functions are located in the Smarty.addons.class
file. They can be modified to your liking, or add new ones.
{html_options} and {html_select_date} are examples of custom
functions.
</para>
</sect2>
<sect2>
<title>Attributes</title>
<para>
Attributes to functions are much like HTML attributes. Static
values don't have to be enclosed in quotes, but it is recommended
for literal strings. If not quoted, you may use a syntax that Smarty may confuse
with another function, such as a boolean value. Variables may
also be used, and should not be in quotes.
</para>
<example>
<title>function attribute syntax</title>
<programlisting>
{include file="header.tpl"}
{include file=$includeFile}
{include file=#includeFile#}
&lt;SELECT name=company&gt;
{html_options values=$vals selected=$selected output=$output}
&lt;/SELECT&gt;
</programlisting>
</example>
</sect2>
<sect2>
<title>Comments</title>
<para>
Template comments are surrounded by asterisks, and that is surrounded
by the delimiter tags like so: {* this is a comment *}
Smarty comments are not displayed in the final output of the template.
They are used mainly for making the templates more understandable.
</para>
<example>
<title>Comments</title>
<programlisting>
{* Smarty *}
{* include the header file here *}
{include file="header.tpl"}
{include file=$includeFile}
{include file=#includeFile#}
{* display dropdown lists *}
&lt;SELECT name=company&gt;
{html_options values=$vals selected=$selected output=$output}
&lt;/SELECT&gt;
</programlisting>
</example>
</sect2>
</sect1>
<sect1 id="configfiles">
<title>Config Files</title>
<para>
Config files are handy for designers to manage global template
variables from one file. One example is template colors. Normally if
you wanted to change the color scheme of an application, you would have
to go through each and every template file and change the colors. With
a config file, the colors can be kept in one place, and only one file
needs to be updated. Note that to use config files, you must place the
Config_File.class.php in your PHP include path. Config_File.class.php
comes bundled with Smarty. Smarty will implicitly include the file if
you don't already include it in your application.
</para>
<example>
<title>Example of config file syntax</title>
<programlisting>
# global variables
pageTitle = "Main Menu"
bodyBgColor = #000000
tableBgColor = #000000
rowBgColor = #00ff00
[Customer]
pageTitle = "Customer Info"
[Login]
pageTitle = "Login"
focus = "username"
Intro = """This is a value that spans more
than one line. you must enclose
it in triple quotes."""
# hidden section
[.Database]
host=my.domain.com
db=ADDRESSBOOK
user=php-user
pass=foobar
</programlisting>
</example>
<para>
Values of config file variables can be in quotes, but not necessary.
You can use either single or double quotes. If you have a value that
spans more than one line, enclose the entire value with triple quotes
("""). You can put comments into config files by any syntax that is
not a valid config file syntax. We recommend using a hashmark (#) at the
beginning of the line.
</para>
<para>
This config file example has two sections. Section names are enclosed
in brackets []. The four variables at the top are global
variables, or variables not within a section. These variables are
always loaded from the config file.
If a particular section is loaded, then the global variables and the
variables from that section are loaded. If a variable exists both as
a global and in a section, the section variable is used. If you name two
variables the same within a section, the last one will be used.
</para>
<para>
Config files are loaded into templates with the built-in function
called <link linkend="builtin.functions.configload">config_load</link>.
</para>
<para>
You can hide variables or entire sections by prepending the variable
name or section name with a period. This is useful if your
application reads the config files and gets sensitive data from them
that the template engine does not need. If you have third parties
doing template editing, you can be certain that they cannot read
sensitive data from the config file by loading it into the template.
This is new in Smarty 1.4.6.
</para>
</sect1>
<sect1 id="builtin.functions">
<title>Built-in Functions</title>
<para>
Smarty comes with several built-in functions. Built-in functions
are integral to the template language. You cannot create custom
functions with the same names, nor can you modify built-in functions.
</para>
<sect2 id="builtin.functions.capture">
<title>capture</title>
<para>
capture is used to collect the output of the template into a
variable instead of displaying it. Any content between {capture
name="foo"} and {/capture} is collected into the variable specified
in the name attribute. The captured content can be used in the
template from the special variable $smarty.capture.foo where foo is
the value passed in the name attribute. If you do not supply a name
attribute, then "default" will be used. All {capture} commands must
be paired with {/capture}. You can nest capture commands. capture
was added to Smarty 1.4.0. The "name" attribute was added to Smarty
1.4.5.
</para>
<para>
NOTE: Smarty 1.4.0 - 1.4.4 placed the captured content into the
variable named $return. As of 1.4.5, this behavior was changed to use
the name attribute, so update your templates accordingly.
</para>
<para>
TECHNICAL NOTE: Be careful when capturing {insert} output. If you
have caching turned on and you have {insert} commands that you
expect to run within cached content, do not capture this content.
</para>
<example>
<title>capturing template content</title>
<programlisting>
{* we don't want to print a table row unless content is displayed *}
{capture name=banner}
{include file="get_banner.tpl"}
{/capture}
{if $smarty.capture.banner ne ""}
&lt;tr&gt;
&lt;td&gt;
{$return}
&lt;/td&gt;
&lt;/tr&gt;
{/if}
</programlisting>
</example>
</sect2>
<sect2 id="builtin.functions.configload">
<title>config_load</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>file</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the config file to include</entry>
</row>
<row>
<entry>section</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the section to load</entry>
</row>
<row>
<entry>scope</entry>
<entry>string</entry>
<entry>no</entry>
<entry><emphasis>local</emphasis></entry>
<entry>
How the scope of the loaded variables are treated,
which must be one of local, parent or global. local
means variables are loaded into the local template
context. parent means variables are loaded into both
the local context and the parent template that called
it. global means variables are available to all
templates. NOTE: This was added to Smarty 1.4.3.
</entry>
</row>
<row>
<entry>global</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>No</emphasis></entry>
<entry>
Whether or not variables are visible to the parent
template, same as scope=parent. NOTE: This attribute is
deprecated by the scope attribute, but still supported.
If scope is supplied, this value is ignored.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
This function is used for loading in variables from a
configuration file into the template. You must have the Config_file.class.php
file somewhere in your PHP include path for config_load to work properly.
See <link linkend="configfiles">Config Files</link> for more info.
</para>
<example>
<title>function config_load</title>
<programlisting>
{config_load file="colors.conf"}
&lt;html&gt;
&lt;title&gt;{#pageTitle#}&lt;/title&gt;
&lt;body bgcolor="{#bodyBgColor#}"&gt;
&lt;table border="{#tableBorderSize#}" bgcolor="{#tableBgColor#}"&gt;
&lt;tr bgcolor="{#rowBgColor#}"&gt;
&lt;td&gt;First&lt;/td&gt;
&lt;td&gt;Last&lt;/td&gt;
&lt;td&gt;Address&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
</programlisting>
</example>
<para>
Config files may also contain sections. You can load variables from
within a section with the added attribute
<emphasis>section</emphasis>.
</para>
<para>
NOTE: <emphasis>Config file sections</emphasis> and the built-in
template function called <emphasis>section</emphasis> have nothing
to do with each other, they just happen to share a common naming
convention.
</para>
<example>
<title>function config_load with section</title>
<programlisting>
{config_load file="colors.conf" section="Customer"}
&lt;html&gt;
&lt;title&gt;{#pageTitle#}&lt;/title&gt;
&lt;body bgcolor="{#bodyBgColor#}"&gt;
&lt;table border="{#tableBorderSize#}" bgcolor="{#tableBgColor#}"&gt;
&lt;tr bgcolor="{#rowBgColor#}"&gt;
&lt;td&gt;First&lt;/td&gt;
&lt;td&gt;Last&lt;/td&gt;
&lt;td&gt;Address&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
</programlisting>
</example>
</sect2>
<sect2 id="builtin.functions.include">
<title>include</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>file</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the template file to include</entry>
</row>
<row>
<entry>assign</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the variable that the output of
include will be assigned to</entry>
</row>
<row>
<entry>[var ...]</entry>
<entry>[var type]</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>variable to pass local to template</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
Include tags are used for including other templates in the current
template. Any variables available in the current template are also
available within the included template. The include tag must have
the attribute "file", which contains the template resource path.
</para>
<para>
You an optionally pass the <emphasis>assign</emphasis> attribute,
which will specify a template variable name that the output of
<emphasis>include</emphasis> will be assigned to instead of
displayed. This was added to Smarty 1.5.0.
</para>
<example>
<title>function include</title>
<programlisting>
{include file="header.tpl"}
{* body of template goes here *}
{include file="footer.tpl"}
</programlisting>
</example>
<para>
You can also pass variables to included templates as attributes.
Any variables explicitly passed to an included template as
attributes are only available within the scope of the included
file. Attribute variables override current template variables, in
the case they are named alike.
</para>
<example>
<title>function include passing variables</title>
<programlisting>
{include file="header.tpl" title="Main Menu" table_bgcolor="#c0c0c0"}
{* body of template goes here *}
{include file="footer.tpl" logo="http://my.domain.com/logo.gif"}
</programlisting>
</example>
</sect2>
<sect2 id="builtin.functions.include.php">
<title>include_php</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>file</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the php file to include</entry>
</row>
<row>
<entry>assign</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the variable that the output of
include_php will be assigned to</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
include_php tags are used to include a php script in your template.
If security is enabled, then the php script must be located in the
$trusted_dir path. The include_php tag must have the attribute
"file", which contains the path to the included php file, either
relative to $trusted_dir, or an absolute path.
</para>
<para>
include_php is a nice way to handle componentized templates, and
keep PHP code separate from the template files. Lets say you have a
template that shows your site navigation, which is pulled
dynamically from a database. You can keep your PHP logic that grabs
database content in a separate directory, and include it at the top
of the template. Now you can include this template anywhere without
worrying if the database information was assigned by the application
before hand.
</para>
<para>
You an optionally pass the <emphasis>assign</emphasis> attribute,
which will specify a template variable name that the output of
<emphasis>include</emphasis> will be assigned to instead of
displayed.
</para>
<para>
include_php was added to Smarty 1.5.0.
</para>
<example>
<title>function include_php</title>
<programlisting>
load_nav.php
-------------
&lt;?php
// load in variables from a mysql db and assign them to the template
require_once("MySQL.class.php");
$sql = new MySQL;
$sql->query("select * from site_nav_sections order by name",SQL_ALL);
$this->assign($sections,$sql->record);
?&gt;
index.tpl
---------
{* absolute path, or relative to $trusted_dir *}
{include_php file="/path/to/load_nav.php"}
{foreach item=$curr_section from=$sections}
&lt;a href="{$curr_section.url}"&gt;{$curr_section.name}&lt;/a&gt;&lt;br&gt;
{/foreach}
</programlisting>
</example>
</sect2>
<sect2 id="builtin.functions.insert">
<title>insert</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>name</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the insert function (insert_name)</entry>
</row>
<row>
<entry>assign</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the template variable the output will
be assigned to</entry>
</row>
<row>
<entry>[var ...]</entry>
<entry>[var type]</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>variable to pass to insert function</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
The insert tag in Smarty serves a special purpose. You may
run into the situation where it is impossible to pass data to a template
before the template is executed because there is info in the template
needed to aquire the data, kind of a catch 22. The insert tag is a way
to callback a function in PHP during runtime of the template. The
difference between insert tags and custom functions is that insert
tags are not cached when you have template <link
linkend="section.caching">caching</link> enabled. They
will be executed on every invocation of the template.
</para>
<para>
Let's say you have a template with a banner slot at the top of the page. The
banner can contain any mixture of HTML, images, flash, etc. so we can't just
use a static link here. In comes the insert tag: the template
knows #banner_location_id# and #site_id# values (gathered from a config file),
and needs to call a function to get the banner's contents.
</para>
<example>
<title>function insert</title>
<programlisting>
{* example of fetching a banner *}
{insert name="getBanner" lid=#banner_location_id# sid=#site_id#}
</programlisting>
</example>
<para>
In this example, we are using the name "getBanner" and passing the
parameters #banner_location_id# and #site_id#. Smarty will look
for a function named insert_getBanner() in your PHP application, passing
the values of #banner_location_id# and #site_id# as the first argument
in an associative array. All insert function names in
your application must be prepended with "insert_" to remedy possible
function name-space conflicts. Your insert_getBanner() function should
do something with the passed values and return the results. These results
are then displayed in the template in place of the insert tag.
In this example, Smarty would call this function:
insert_getBanner(array("lid" => "12345","sid" => "67890"));
and display the returned results in place of the insert tag.
</para>
<para>
If you supply the special "assign" attribute, the output of the
insert tag will be assigned to this template variable instead of
being output to the template. NOTE: assiging the output to a template
variable isn't too useful with caching enabled. (added to Smarty
1.5.0)
</para>
<para>
The Smarty object is passed as the second argument. This way you
can reference and modify information in the Smarty object from
within the insert function. (added in 1.4.5)
</para>
<para>
TECHNICAL NOTE: It is possible to have portions of the template not
cached. If you have <link linkend="section.caching">caching</link>
turned on, insert tags will not be cached. They will run
dynamically every time the page is created, even within cached
pages. This works good for things like banners, polls, live
weather, search results, user feedback areas, etc.
</para>
</sect2>
<sect2>
<title>if,elseif,else</title>
<para>
if statements in Smarty have much the same flexibility as php if
statements, with a few added features for the template engine.
Every <emphasis>if</emphasis> must be paired with an
<emphasis>/if</emphasis>. <emphasis>else</emphasis> and
<emphasis>elseif</emphasis> are also permitted. "eq", "ne","neq",
"gt", "lt", "lte", "le", "gte" "ge","is even","is odd", "is not
even","is not odd","not","mod","div by","even by","odd
by","==","!=",">", "<","<=",">=" are all valid conditional
qualifiers, and must be separated from surrounding elements by
spaces.
</para>
<example>
<title>if statements</title>
<programlisting>
{if $name eq "Fred"}
Welcome Sir.
{elseif $name eq "Wilma"}
Welcome Ma'am.
{else}
Welcome, whatever you are.
{/if}
{* an example with "or" logic *}
{if $name eq "Fred" or $name eq "Wilma"}
...
{/if}
{* same as above *}
{if $name == "Fred" || $name == "Wilma"}
...
{/if}
{* the following syntax will NOT work, conditional qualifiers
must be separated from surrounding elements by spaces *}
{if $name=="Fred" || $name=="Wilma"}
...
{/if}
{* parenthesis are allowed *}
{if ( $amount < 0 or $amount > 1000 ) and $volume >= #minVolAmt#}
...
{/if}
{* you can also embed php function calls *}
{if count($var) gt 0}
...
{/if}
{* test if values are even or odd *}
{if $var is even}
...
{/if}
{if $var is odd}
...
{/if}
{if $var is not odd}
...
{/if}
{* test if var is divisible by 4 *}
{if $var is div by 4}
...
{/if}
{* test if var is even, grouped by two. i.e.,
0=even, 1=even, 2=odd, 3=odd, 4=even, 5=even, etc. *}
{if $var is even by 2}
...
{/if}
{* 0=even, 1=even, 2=even, 3=odd, 4=odd, 5=odd, etc. *}
{if $var is even by 3}
...
{/if}
</programlisting>
</example>
</sect2>
<sect2>
<title>ldelim,rdelim</title>
<para>
ldelim and rdelim are used for displaying the literal delimiter, in
our case "{" or "}". The template engine always tries to interpret
delimiters, so this is the way around that.
</para>
<example>
<title>ldelim, rdelim</title>
<programlisting>
{* this will print literal delimiters out of the template *}
{ldelim}funcname{rdelim} is how functions look in Smarty!
OUTPUT:
{funcname} is how functions look in Smarty!
</programlisting>
</example>
</sect2>
<sect2 id="builtin.functions.literal">
<title>literal</title>
<para>
Literal tags allow a block of data to be taken literally,
not being interpreted by the Smarty engine. This is handy
for things like javascript sections, where there maybe
curly braces and such things that would confuse the template
parser. Anything within {literal}{/literal} tags is not
interpreted, but displayed as-is.
</para>
<example>
<title>literal tags</title>
<programlisting>
{literal}
&lt;script language=javascript&gt;
&lt;!--
function isblank(field) {
if (field.value == '')
{ return false; }
else
{
document.loginform.submit();
return true;
}
}
// --&gt;
&lt;/script&gt;
{/literal}
</programlisting>
</example>
</sect2>
<sect2 id="builtin.functions.php">
<title>php</title>
<para>
php tags allow php to be embedded directly into the template. They
will not be escaped, regardless of the <link
linkend="setting.php.handling">$php_handling</link> setting. This
is for advanced users only, not normally needed. This was added to
1.4.0.
</para>
<example>
<title>php tags</title>
<programlisting>
{php}
// including a php script directly
// from the template.
include("/path/to/display_weather.php");
{/php}
</programlisting>
</example>
</sect2>
<sect2 id="builtin.functions.section">
<title>section,sectionelse</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>name</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the section</entry>
</row>
<row>
<entry>loop</entry>
<entry>[$variable_name]</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the variable to determine # of loop
iterations</entry>
</row>
<row>
<entry>start</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>0</emphasis></entry> <entry>The index
position that the section will begin looping. If the
value is negative, the start position is calculated
from the end of the array. For example, if there are
seven values in the loop array and start is -2, the
start index is 5. Invalid values (values outside of the
length of the loop array) are automatically truncated
to the closest valid value. (Added to Smarty 1.4.4.)</entry>
</row>
<row>
<entry>step</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>1</emphasis></entry>
<entry>The step value that will be used to traverse the
loop array. For example, step=2 will loop on index
0,2,4, etc. If step is negative, it will step through
the array backwards. (Added to Smarty 1.4.4.)</entry>
</row>
<row>
<entry>max</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>1</emphasis></entry>
<entry>Sets the maximum number of times the section
will loop. (Added to Smarty 1.4.4.)</entry>
</row>
<row>
<entry>show</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>true</emphasis></entry>
<entry>determines whether or not to show this section</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
Template sections are used for looping over arrays of data. All
<emphasis>section</emphasis> tags must be paired with
<emphasis>/section</emphasis> tags. Required parameters are
<emphasis>name</emphasis> and <emphasis>loop</emphasis>. The name
of the section can be anything you like, made up of letters,
numbers and underscores. Sections can be nested, and the nested
section names must be unique from each other. The loop variable
(usually an array of values) determines the number of times the
section will loop. When printing a variable within a section, the
section name must be given next to variable name within brackets
[]. <emphasis>sectionelse</emphasis> is
executed when there are no values in the loop variable.
</para>
<example>
<title>section</title>
<programlisting>
{* this example will print out all the values of the $custid array *}
{section name=customer loop=$custid}
id: {$custid[customer]}&lt;br&gt;
{/section}
OUTPUT:
id: 1000&lt;br&gt;
id: 1001&lt;br&gt;
id: 1002&lt;br&gt;
</programlisting>
</example>
<example>
<title>section loop variable</title>
<programlisting>
{* the loop variable only determines the number of times to loop.
you can access any variable from the template within the section.
This example assumes that $custid, $name and $address are all
arrays containing the same number of values *}
{section name=customer loop=$custid}
id: {$custid[customer]}&lt;br&gt;
name: {$name[customer]}&lt;br&gt;
address: {$address[customer]}&lt;br&gt;
&lt;p&gt;
{/section}
OUTPUT:
id: 1000&lt;br&gt;
name: John Smith&lt;br&gt;
address: 253 N 45th&lt;br&gt;
&lt;p&gt;
id: 1001&lt;br&gt;
name: Jack Jones&lt;br&gt;
address: 417 Mulberry ln&lt;br&gt;
&lt;p&gt;
id: 1002&lt;br&gt;
name: Jane Munson&lt;br&gt;
address: 5605 apple st&lt;br&gt;
&lt;p&gt;
</programlisting>
</example>
<example>
<title>section names</title>
<programlisting>
{* the name of the section can be anything you like,
and it is used to reference the data within the section *}
{section name=mydata loop=$custid}
id: {$custid[mydata]}&lt;br&gt;
name: {$name[mydata]}&lt;br&gt;
address: {$address[mydata]}&lt;br&gt;
&lt;p&gt;
{/section}
</programlisting>
</example>
<example>
<title>nested sections</title>
<programlisting>
{* sections can be nested as deep as you like. With nested sections,
you can access complex data structures, such as multi-dimensional
arrays. In this example, $contact_type[customer] is an array of
contact types for the current customer. *}
{section name=customer loop=$custid}
id: {$custid[customer]}&lt;br&gt;
name: {$name[customer]}&lt;br&gt;
address: {$address[customer]}&lt;br&gt;
{section name=contact loop=$contact_type[customer]}
{$contact_type[customer][contact]}: {$contact_info[customer][contact]}&lt;br&gt;
{/section}
&lt;p&gt;
{/section}
OUTPUT:
id: 1000&lt;br&gt;
name: John Smith&lt;br&gt;
address: 253 N 45th&lt;br&gt;
home phone: 555-555-5555&lt;br&gt;
cell phone: 555-555-5555&lt;br&gt;
e-mail: john@mydomain.com&lt;br&gt;
&lt;p&gt;
id: 1001&lt;br&gt;
name: Jack Jones&lt;br&gt;
address: 417 Mulberry ln&lt;br&gt;
home phone: 555-555-5555&lt;br&gt;
cell phone: 555-555-5555&lt;br&gt;
e-mail: jack@mydomain.com&lt;br&gt;
&lt;p&gt;
id: 1002&lt;br&gt;
name: Jane Munson&lt;br&gt;
address: 5605 apple st&lt;br&gt;
home phone: 555-555-5555&lt;br&gt;
cell phone: 555-555-5555&lt;br&gt;
e-mail: jane@mydomain.com&lt;br&gt;
&lt;p&gt;
</programlisting>
</example>
<example>
<title>sections and associative arrays</title>
<programlisting>
{* This is an example of printing an associative array
of data within a section *}
{section name=customer loop=$contacts}
name: {$contacts[customer].name}&lt;br&gt;
home: {$contacts[customer].home}&lt;br&gt;
cell: {$contacts[customer].cell}&lt;br&gt;
e-mail: {$contacts[customer].email}&lt;p&gt;
{/section}
OUTPUT:
name: John Smith&lt;br&gt;
home: 555-555-5555&lt;br&gt;
cell: 555-555-5555&lt;br&gt;
e-mail: john@mydomain.com&lt;p&gt;
name: Jack Jones&lt;br&gt;
home phone: 555-555-5555&lt;br&gt;
cell phone: 555-555-5555&lt;br&gt;
e-mail: jack@mydomain.com&lt;p&gt;
name: Jane Munson&lt;br&gt;
home phone: 555-555-5555&lt;br&gt;
cell phone: 555-555-5555&lt;br&gt;
e-mail: jane@mydomain.com&lt;p&gt;
</programlisting>
</example>
<example>
<title>sectionelse</title>
<programlisting>
{* sectionelse will execute if there are no $custid values *}
{section name=customer loop=$custid}
id: {$custid[customer]}&lt;br&gt;
{sectionelse}
there are no values in $custid.
{/section}
</programlisting>
</example>
<para>
Sections also have their own variables that handle section properties.
These are indicated like so: {$smarty.section.sectionname.varname}
</para>
<para>
NOTE: As of Smarty 1.5.0, the syntax for section property variables has
been changed from {%sectionname.varname%} to
{$smarty.section.sectionname.varname}. The old syntax is still
supported, but you will only see reference to the new syntax in the
manual examples.
</para>
<sect3>
<title>index</title>
<para>
index is used to display the current loop index, starting with zero
(or the start attribute if given), and incrementing by one (or by
the step attribute if given.)
</para>
<para>
TECHNICAL NOTE: If the step and start section properties are not
modified, then this works the same as the iteration section
property.
</para>
<example>
<title>section property index</title>
<programlisting>
{section name=customer loop=$custid}
{$smarty.section.customer.index} id: {$custid[customer]}&lt;br&gt;
{/section}
OUTPUT:
0 id: 1000&lt;br&gt;
1 id: 1001&lt;br&gt;
2 id: 1002&lt;br&gt;
</programlisting>
</example>
</sect3>
<sect3>
<title>index_prev</title>
<para>
index_prev is used to display the previous loop index.
on the first loop, this is set to -1.
</para>
<example>
<title>section property index_prev</title>
<programlisting>
{section name=customer loop=$custid}
{$smarty.section.customer.index} id: {$custid[customer]}&lt;br&gt;
{* FYI, $custid[customer.index] and $custid[customer] are identical in meaning *}
{if $custid[customer.index_prev] ne $custid[customer.index]}
The customer id changed&lt;br&gt;
{/if}
{/section}
OUTPUT:
0 id: 1000&lt;br&gt;
The customer id changed&lt;br&gt;
1 id: 1001&lt;br&gt;
The customer id changed&lt;br&gt;
2 id: 1002&lt;br&gt;
The customer id changed&lt;br&gt;
</programlisting>
</example>
</sect3>
<sect3>
<title>index_next</title>
<para>
index_next is used to display the next loop index. On the last
loop, this is still one more than the current index (respecting the
setting of the step attribute, if given.)
</para>
<example>
<title>section property index_next</title>
<programlisting>
{section name=customer loop=$custid}
{$smarty.section.customer.index} id: {$custid[customer]}&lt;br&gt;
{* FYI, $custid[customer.index] and $custid[customer] are identical in meaning *}
{if $custid[customer.index_next] ne $custid[customer.index]}
The customer id will change&lt;br&gt;
{/if}
{/section}
OUTPUT:
0 id: 1000&lt;br&gt;
The customer id will change&lt;br&gt;
1 id: 1001&lt;br&gt;
The customer id will change&lt;br&gt;
2 id: 1002&lt;br&gt;
The customer id will change&lt;br&gt;
</programlisting>
</example>
</sect3>
<sect3>
<title>iteration</title>
<para>
iteration is used to display the current loop iteration.
</para>
<para>
NOTE: This is not affected by the section properties start, step and
max, unlike the index property.
</para>
<para>
This was added to Smarty 1.4.4.
</para>
<example>
<title>section property iteration</title>
<programlisting>
{section name=customer loop=$custid start=5 step=2}
current loop iteration: {$smarty.section.customer.iteration}&lt;br&gt;
{$smarty.section.customer.index} id: {$custid[customer]}&lt;br&gt;
{* FYI, $custid[customer.index] and $custid[customer] are identical in meaning *}
{if $custid[customer.index_next] ne $custid[customer.index]}
The customer id will change&lt;br&gt;
{/if}
{/section}
OUTPUT:
current loop iteration: 1
5 id: 1000&lt;br&gt;
The customer id will change&lt;br&gt;
current loop iteration: 2
7 id: 1001&lt;br&gt;
The customer id will change&lt;br&gt;
current loop iteration: 3
9 id: 1002&lt;br&gt;
The customer id will change&lt;br&gt;
</programlisting>
</example>
</sect3>
<sect3>
<title>first</title>
<para>
first is set to true if the current section iteration is the first
one.
</para>
<example>
<title>section property first</title>
<programlisting>
{section name=customer loop=$custid}
{if $smarty.section.customer.first}
&lt;table&gt;
{/if}
&lt;tr&gt;&lt;td&gt;{$smarty.section.customer.index} id:
{$custid[customer]}&lt;/td&gt;&lt;/tr&gt;
{if $smarty.section.customer.last}
&lt;/table&gt;
{/if}
{/section}
OUTPUT:
&lt;table&gt;
&lt;tr&gt;&lt;td&gt;0 id: 1000&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;1 id: 1001&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;2 id: 1002&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
</programlisting>
</example>
</sect3>
<sect3>
<title>last</title>
<para>
last is set to true if the current section iteration is the last
one.
</para>
<example>
<title>section property last</title>
<programlisting>
{section name=customer loop=$custid}
{if $smarty.section.customer.first}
&lt;table&gt;
{/if}
&lt;tr&gt;&lt;td&gt;{$smarty.section.customer.index} id:
{$custid[customer]}&lt;/td&gt;&lt;/tr&gt;
{if $smarty.section.customer.last}
&lt;/table&gt;
{/if}
{/section}
OUTPUT:
&lt;table&gt;
&lt;tr&gt;&lt;td&gt;0 id: 1000&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;1 id: 1001&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;2 id: 1002&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
</programlisting>
</example>
</sect3>
<sect3>
<title>rownum</title>
<para>
rownum is used to display the current loop iteration,
starting with one.
</para>
<example>
<title>section property rownum</title>
<programlisting>
{section name=customer loop=$custid}
{$smarty.section.customer.rownum} id: {$custid[customer]}&lt;br&gt;
{/section}
OUTPUT:
1 id: 1000&lt;br&gt;
2 id: 1001&lt;br&gt;
3 id: 1002&lt;br&gt;
</programlisting>
</example>
</sect3>
<sect3>
<title>loop</title>
<para>
loop is used to display the last index number that this section
looped. This can be used inside or after the section.
</para>
<example>
<title>section property index</title>
<programlisting>
{section name=customer loop=$custid}
{$smarty.section.customer.index} id: {$custid[customer]}&lt;br&gt;
{/section}
There were {$smarty.section.customer.loop} customers shown above.
OUTPUT:
0 id: 1000&lt;br&gt;
1 id: 1001&lt;br&gt;
2 id: 1002&lt;br&gt;
There were 3 customers shown above.
</programlisting>
</example>
</sect3>
<sect3>
<title>show</title>
<para>
<emphasis>show</emphasis> is used as a parameter to section.
<emphasis>show</emphasis> is a boolean value, true or false. If
false, the section will not be displayed. If there is a sectionelse
present, that will be alternately displayed.
</para>
<example>
<title>section attribute show</title>
<programlisting>
{* $show_customer_info may have been passed from the PHP
application, to regulate whether or not this section shows *}
{section name=customer loop=$custid show=$show_customer_info}
{$smarty.section.customer.rownum} id: {$custid[customer]}&lt;br&gt;
{/section}
{if $smarty.section.customer.show}
the section was shown.
{else}
the section was not shown.
{/if}
OUTPUT:
1 id: 1000&lt;br&gt;
2 id: 1001&lt;br&gt;
3 id: 1002&lt;br&gt;
the section was shown.
</programlisting>
</example>
</sect3>
<sect3>
<title>total</title>
<para>
total is used to display the number of iterations that this section
will loop. This can be used inside or after the section.
</para>
<para>
This was added to Smarty 1.4.4.
</para>
<example>
<title>section property total</title>
<programlisting>
{section name=customer loop=$custid step=2}
{$smarty.section.customer.index} id: {$custid[customer]}&lt;br&gt;
{/section}
There were {$smarty.section.customer.total} customers shown above.
OUTPUT:
0 id: 1000&lt;br&gt;
2 id: 1001&lt;br&gt;
4 id: 1002&lt;br&gt;
There were 3 customers shown above.
</programlisting>
</example>
</sect3>
</sect2>
<sect2 id="builtin.functions.foreach">
<title>foreach,foreachelse</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>from</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the array you are looping through</entry>
</row>
<row>
<entry>item</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the variable that is the current
element</entry>
</row>
<row>
<entry>key</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the variable that is the current key</entry>
</row>
<row>
<entry>name</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the foreach loop for accessing
foreach properties</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
<emphasis>foreach</emphasis> loops are an alternative to
<emphasis>section</emphasis> loops. <emphasis>foreach</emphasis> is
used to loop over a single associative array. The syntax for
<emphasis>foreach</emphasis> is much easier than
<emphasis>section</emphasis>, but as a tradeoff it can only be used
for a single array. <emphasis>foreach</emphasis> tags must be
paired with <emphasis>/foreach</emphasis> tags. Required parameters
are <emphasis>from</emphasis> and <emphasis>item</emphasis>. The
name of the foreach loop can be anything you like, made up of
letters, numbers and underscores. <emphasis>foreach</emphasis>
loops can be nested, and the nested foreach names must be unique
from each other. The <emphasis>from</emphasis> variable (usually an
array of values) determines the number of times
<emphasis>foreach</emphasis> will loop.
<emphasis>foreachelse</emphasis> is executed when there are no
values in the <emphasis>from</emphasis> variable.
</para>
<example>
<title>foreach</title>
<programlisting>
{* this example will print out all the values of the $custid array *}
{foreach from=$custid item=curr_id}
id: {$curr_id}&lt;br&gt;
{/foreach}
OUTPUT:
id: 1000&lt;br&gt;
id: 1001&lt;br&gt;
id: 1002&lt;br&gt;
</programlisting>
</example>
<example>
<title>foreach key</title>
<programlisting>
{* The key contains the key for each looped value
assignment looks like this:
$smarty->assign("contacts", array(array("phone" =&gt; "1", "fax" =&gt; "2", "cell" =&gt; "3"),
array("phone" =&gt; "555-4444", "fax" =&gt; "555-3333", "cell" =&gt; "760-1234")));
*}
{foreach name=outer item=contact from=$contacts}
{foreach key=key item=item from=$smarty.foreach.outer}
{$key}: {$item}&lt;br&gt;
{/foreach}
{/foreach}
OUTPUT:
phone: 1&lt;br&gt;
fax: 2&lt;br&gt;
cell: 3&lt;br&gt;
phone: 555-4444&lt;br&gt;
fax: 555-3333&lt;br&gt;
cell: 760-1234&lt;br&gt;
</programlisting>
</example>
</sect2>
<sect2>
<title>strip</title>
<para>
Many times web designers
run into the issue where white space and carriage returns
affect the output of the rendered HTML (browser "features"), so you
must run all your tags together in the template to get the
desired results. This usually ends up in unreadable or
unmanagable templates.
</para>
<para>
Anything within {strip}{/strip} tags in Smarty are stripped of
the extra spaces or carriage returns at the beginnings and
ends of the lines before they are displayed.
This way you can keep your templates readable, and not worry
about extra white space causing problems.
</para>
<example>
<title>strip tags</title>
<programlisting>
{* the following will be all run into one line upon output *}
{strip}
&lt;table border=0&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;A HREF="{$url}"&gt;
&lt;font color="red"&gt;This is a test&lt;/font&gt;
&lt;/A&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
{/strip}
OUTPUT:
&lt;table border=0&gt;&lt;tr&gt;&lt;td&gt;&lt;A HREF="http://my.domain.com"&gt;&lt;font color="red"&gt;This is a test&lt;/font&gt;&lt;/A&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
</programlisting>
</example>
<para>
Notice that in the above example, all the lines begin and end
with HTML tags. Be aware that all the lines are run together.
If you have plain text at the beginning or end of any line,
they will be run together, and may not be desired results.
</para>
</sect2>
</sect1>
<sect1 id="custom.functions">
<title>Custom Functions</title>
<para>
Custom functions in Smarty work much the same as the built-in functions,
except that built-in functions cannot be modified. Custom functions are
located in Smarty.addons.php, built-in functions are not.
</para>
<sect2 id="custom.functions.assign">
<title>assign</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>val</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the variable being assigned</entry>
</row>
<row>
<entry>value</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The value being assigned</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
assign is used for assigning template variables during the execution
of the template.
</para>
<para>
NOTE: This was added to Smarty 1.4.3.
</para>
<example>
<title>assign</title>
<programlisting>
{assign var="name" value="Bob"}
The value of $name is {$name}.
OUTPUT:
The value of $name is Bob.
</programlisting>
</example>
</sect2>
<sect2>
<title>counter</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>id</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>default</emphasis></entry>
<entry>The id of the counter</entry>
</row>
<row>
<entry>start</entry>
<entry>number</entry>
<entry>No</entry>
<entry><emphasis>1</emphasis></entry>
<entry>The initial number to start counting from</entry>
</row>
<row>
<entry>skip</entry>
<entry>number</entry>
<entry>No</entry>
<entry><emphasis>1</emphasis></entry>
<entry>The interval to count by</entry>
</row>
<row>
<entry>direction</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>up</emphasis></entry>
<entry>the direction to count (up/down)</entry>
</row>
<row>
<entry>print</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>true</emphasis></entry>
<entry>Whether or not to print the value</entry>
</row>
<row>
<entry>assign</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>the template variable the output will be assigned
to</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
counter is used to print out a count. counter will remember the
count on each iteration. You can adjust the number, the interval
and the direction of the count, as well as determine whether or not
to print the value. You can run multiple counters concurrently by
supplying a unique id for each one. If you do not supply an id, the
default id will be used. counter was added to Smarty 1.4.0.
</para>
<para>
If you supply the special "assign" attribute, the output of the
counter function will be assigned to this template variable instead of
being output to the template. (new in Smarty 1.5.0)
</para>
<example>
<title>counter</title>
<programlisting>
{* initialize the count *}
{counter start=0 skip=2 print=false}
{counter}&lt;br&gt;
{counter}&lt;br&gt;
{counter}&lt;br&gt;
{counter}&lt;br&gt;
OUTPUT:
2&lt;br&gt;
4&lt;br&gt;
6&lt;br&gt;
8&lt;br&gt;
</programlisting>
</example>
</sect2>
<sect2>
<title>fetch</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>file</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>the file, http or ftp site to fetch</entry>
</row>
<row>
<entry>assign</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>the template variable the output will be assigned
to</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
fetch is used to fetch files from the local file system, http, or
ftp and display the contents. If the file name begins with
"http://", the web site page will be fetched and displayed. If the
file name begins with "ftp://", the file will be fetched from the
ftp server and displayed. For local files, the full system file
path must be given, or a path relative to the executed php script.
</para>
<para>
If you supply the special "assign" attribute, the output of the
fetch function will be assigned to this template variable instead of
being output to the template. (new in Smarty 1.5.0)
</para>
<para>
TECHNICAL NOTE: This will not support http redirects, be sure to
include a trailing slash on your web page fetches where necessary.
</para>
<para>
TECHNICAL NOTE: If template security is turned on and you are
fetching a file from the local file system, this will only allow
files from within one of the defined secure directories.
($secure_dir)
</para>
<example>
<title>fetch</title>
<programlisting>
{* include some javascript in your template *}
{fetch file="/export/httpd/www.domain.com/docs/navbar.js"}
{* embed some weather text in your template from another web site *}
{fetch file="http://www.myweather.com/68502/"}
{* fetch a news headline file via ftp *}
{fetch file="ftp://user:password@ftp.domain.com/path/to/currentheadlines.txt"}
{* assign the fetched contents to a template variable *}
{fetch file="http://www.myweather.com/68502/" assign="weather"}
{if $weather ne ""}
&lt;b&gt;{$weather}&lt;/b&gt;
{/if}
</programlisting>
</example>
</sect2>
<sect2 id="custom.functions.html.options">
<title>html_options</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>values</entry>
<entry>array</entry>
<entry>Yes, unless using options attribute</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>an array of values for dropdown</entry>
</row>
<row>
<entry>output</entry>
<entry>array</entry>
<entry>Yes, unless using options attribute</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>an array of output for dropdown</entry>
</row>
<row>
<entry>selected</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>empty</emphasis></entry>
<entry>the selected array element</entry>
</row>
<row>
<entry>options</entry>
<entry>associative array</entry>
<entry>Yes, unless using values and output</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>an associative array of values and output</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
html_options is a custom function that creates html option
lists with provided data. It takes care of which item is
selected by default as well. Required attributes are values
and output, unless you use options instead.
</para>
<para>
NOTE: As of Smarty 1.4.5, html_options now outputs xhtml compatible
code.
</para>
<example>
<title>html_options</title>
<programlisting>
{* assume that $cust_ids, and $cust_names are arrays of values,
and $customer_id may or may not be set to a value *}
&lt;select name=customer_id&gt;
{html_options values=$cust_ids selected=$customer_id output=$cust_names}
&lt;/select&gt;
{* an alternative method is to pass the values & output as an associative array into
options. $customer_options is an associative array in this example. This
functionality was added to Smarty 1.3.0 *}
&lt;select name=customer_id&gt;
{html_options options=$customer_options selected=$customer_id}
&lt;/select&gt;
OUTPUT:
&lt;select name=customer_id&gt;
&lt;option value="1000">Joe Schmoe&lt;option&gt;
&lt;option value="1001" selected>Jack Smith&lt;option&gt;
&lt;option value="1002">Jane Johnson&lt;option&gt;
&lt;option value="1003">Charlie Brown&lt;option&gt;
&lt;/select&gt;
</programlisting>
</example>
</sect2>
<sect2 id="custom.functions.html.select.date">
<title>html_select_date</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>prefix</entry>
<entry>string</entry>
<entry>No</entry>
<entry>Date_</entry>
<entry>what to prefix the var name with</entry>
</row>
<row>
<entry>time</entry>
<entry>timestamp</entry>
<entry>No</entry>
<entry>current time</entry>
<entry>what date/time to use</entry>
</row>
<row>
<entry>start_year</entry>
<entry>string</entry>
<entry>No</entry>
<entry>current year</entry>
<entry>the first year in the dropdown</entry>
</row>
<row>
<entry>end_year</entry>
<entry>string</entry>
<entry>No</entry>
<entry>same as start_year</entry>
<entry>the last year in the dropdown</entry>
</row>
<row>
<entry>display_days</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry>true</entry>
<entry>whether to display days or not</entry>
</row>
<row>
<entry>display_months</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry>true</entry>
<entry>whether to display months or not</entry>
</row>
<row>
<entry>display_years</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry>true</entry>
<entry>whether to display years or not</entry>
</row>
<row>
<entry>month_format</entry>
<entry>string</entry>
<entry>No</entry>
<entry>%B</entry>
<entry>what format the month should be in (strftime)</entry>
</row>
<row>
<entry>day_format</entry>
<entry>string</entry>
<entry>No</entry>
<entry>%02d</entry>
<entry>what format the day should be in (sprintf)</entry>
</row>
<row>
<entry>year_as_text</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry>false</entry>
<entry>whether or not to display the year as text</entry>
</row>
<row>
<entry>reverse_years</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry>false</entry>
<entry>display years in reverse order</entry>
</row>
<row>
<entry>field_array</entry>
<entry>string</entry>
<entry>No</entry>
<entry>null</entry>
<entry>
if a name is given, the select boxes will be drawn
such that the results will be returned to PHP in the
form of name[Day], name[Year], name[Month].
</entry>
</row>
<row>
<entry>day_size</entry>
<entry>string</entry>
<entry>No</entry>
<entry>null</entry>
<entry>adds size attribute to select tag if given</entry>
</row>
<row>
<entry>month_size</entry>
<entry>string</entry>
<entry>No</entry>
<entry>null</entry>
<entry>adds size attribute to select tag if given</entry>
</row>
<row>
<entry>year_size</entry>
<entry>string</entry>
<entry>No</entry>
<entry>null</entry>
<entry>adds size attribute to select tag if given</entry>
</row>
<row>
<entry>all_extra</entry>
<entry>string</entry>
<entry>No</entry>
<entry>null</entry>
<entry>adds extra attributes to all select/input tags if
given</entry>
</row>
<row>
<entry>day_extra</entry>
<entry>string</entry>
<entry>No</entry>
<entry>null</entry>
<entry>adds extra attributes to select/input tags if
given</entry>
</row>
<row>
<entry>month_extra</entry>
<entry>string</entry>
<entry>No</entry>
<entry>null</entry>
<entry>adds extra attributes to select/input tags if
given</entry>
</row>
<row>
<entry>year_extra</entry>
<entry>string</entry>
<entry>No</entry>
<entry>null</entry>
<entry>adds extra attributes to select/input tags if
given</entry>
</row>
<row>
<entry>field_order</entry>
<entry>string</entry>
<entry>No</entry>
<entry>MDY</entry>
<entry>the order in which to display the fields</entry>
</row>
<row>
<entry>field_separator</entry>
<entry>string</entry>
<entry>No</entry>
<entry>\n</entry>
<entry>string printed between different fields</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
html_select_date is a custom function that creates date dropdowns
for you. It can display any or all of year, month, and day.
</para>
<para>
NOTE: reverse_years, field_array, day_size, month_size, year_size,
all_extra, day_extra, month_extra, year_extra, field_order,
field_separator added in Smarty 1.4.5.
</para>
<example>
<title>html_select_date</title>
<programlisting>
{html_select_date}
OUTPUT:
&lt;select name="Date_Month"&gt;
&lt;option value="1"&gt;January&lt;/option&gt;
&lt;option value="2"&gt;February&lt;/option&gt;
&lt;option value="3"&gt;March&lt;/option&gt;
&lt;option value="4"&gt;April&lt;/option&gt;
&lt;option value="5"&gt;May&lt;/option&gt;
&lt;option value="6"&gt;June&lt;/option&gt;
&lt;option value="7"&gt;July&lt;/option&gt;
&lt;option value="8"&gt;August&lt;/option&gt;
&lt;option value="9"&gt;September&lt;/option&gt;
&lt;option value="10"&gt;October&lt;/option&gt;
&lt;option value="11"&gt;November&lt;/option&gt;
&lt;option value="12" selected&gt;December&lt;/option&gt;
&lt;/select&gt;
&lt;select name="Date_Day"&gt;
&lt;option value="1"&gt;01&lt;/option&gt;
&lt;option value="2"&gt;02&lt;/option&gt;
&lt;option value="3"&gt;03&lt;/option&gt;
&lt;option value="4"&gt;04&lt;/option&gt;
&lt;option value="5"&gt;05&lt;/option&gt;
&lt;option value="6"&gt;06&lt;/option&gt;
&lt;option value="7"&gt;07&lt;/option&gt;
&lt;option value="8"&gt;08&lt;/option&gt;
&lt;option value="9"&gt;09&lt;/option&gt;
&lt;option value="10"&gt;10&lt;/option&gt;
&lt;option value="11"&gt;11&lt;/option&gt;
&lt;option value="12"&gt;12&lt;/option&gt;
&lt;option value="13" selected&gt;13&lt;/option&gt;
&lt;option value="14"&gt;14&lt;/option&gt;
&lt;option value="15"&gt;15&lt;/option&gt;
&lt;option value="16"&gt;16&lt;/option&gt;
&lt;option value="17"&gt;17&lt;/option&gt;
&lt;option value="18"&gt;18&lt;/option&gt;
&lt;option value="19"&gt;19&lt;/option&gt;
&lt;option value="20"&gt;20&lt;/option&gt;
&lt;option value="21"&gt;21&lt;/option&gt;
&lt;option value="22"&gt;22&lt;/option&gt;
&lt;option value="23"&gt;23&lt;/option&gt;
&lt;option value="24"&gt;24&lt;/option&gt;
&lt;option value="25"&gt;25&lt;/option&gt;
&lt;option value="26"&gt;26&lt;/option&gt;
&lt;option value="27"&gt;27&lt;/option&gt;
&lt;option value="28"&gt;28&lt;/option&gt;
&lt;option value="29"&gt;29&lt;/option&gt;
&lt;option value="30"&gt;30&lt;/option&gt;
&lt;option value="31"&gt;31&lt;/option&gt;
&lt;/select&gt;
&lt;select name="Date_Year"&gt;
&lt;option value="2001" selected&gt;2001&lt;/option&gt;
&lt;/select&gt;
</programlisting>
</example>
<example>
<title>html_select_date</title>
<programlisting>
{html_select_date prefix="StartDate" time=$time start_year=1995 end_year=2001 display_days=false}
OUTPUT:
&lt;select name="StartDateMonth"&gt;
&lt;option value="1"&gt;January&lt;/option&gt;
&lt;option value="2"&gt;February&lt;/option&gt;
&lt;option value="3"&gt;March&lt;/option&gt;
&lt;option value="4"&gt;April&lt;/option&gt;
&lt;option value="5"&gt;May&lt;/option&gt;
&lt;option value="6"&gt;June&lt;/option&gt;
&lt;option value="7"&gt;July&lt;/option&gt;
&lt;option value="8"&gt;August&lt;/option&gt;
&lt;option value="9"&gt;September&lt;/option&gt;
&lt;option value="10"&gt;October&lt;/option&gt;
&lt;option value="11"&gt;November&lt;/option&gt;
&lt;option value="12" selected&gt;December&lt;/option&gt;
&lt;/select&gt;
&lt;select name="StartDateYear"&gt;
&lt;option value="1999"&gt;1995&lt;/option&gt;
&lt;option value="1999"&gt;1996&lt;/option&gt;
&lt;option value="1999"&gt;1997&lt;/option&gt;
&lt;option value="1999"&gt;1998&lt;/option&gt;
&lt;option value="1999"&gt;1999&lt;/option&gt;
&lt;option value="2000" selected&gt;2000&lt;/option&gt;
&lt;option value="2001"&gt;2001&lt;/option&gt;
&lt;/select&gt;
</programlisting>
</example>
</sect2>
<sect2 id="custom.functions.html.select.time">
<title>html_select_time</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>prefix</entry>
<entry>string</entry>
<entry>No</entry>
<entry>Time_</entry>
<entry>what to prefix the var name with</entry>
</row>
<row>
<entry>time</entry>
<entry>timestamp</entry>
<entry>No</entry>
<entry>current time</entry>
<entry>what date/time to use</entry>
</row>
<row>
<entry>display_hours</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry>true</entry>
<entry>whether or not to display hours</entry>
</row>
<row>
<entry>display_minutes</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry>true</entry>
<entry>whether or not to display minutes</entry>
</row>
<row>
<entry>display_seconds</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry>true</entry>
<entry>whether or not to display seconds</entry>
</row>
<row>
<entry>display_meridian</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry>true</entry>
<entry>whether or not to display meridian (am/pm)</entry>
</row>
<row>
<entry>use_24_hours</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry>true</entry>
<entry>whether or not to use 24 hour clock</entry>
</row>
<row>
<entry>minute_interval</entry>
<entry>integer</entry>
<entry>No</entry>
<entry>1</entry>
<entry>number interval in minute dropdown</entry>
</row>
<row>
<entry>second_interval</entry>
<entry>integer</entry>
<entry>No</entry>
<entry>1</entry>
<entry>number interval in second dropdown</entry>
</row>
<row>
<entry>field_array</entry>
<entry>string</entry>
<entry>No</entry>
<entry>n/a</entry>
<entry>outputs values to array of this name</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
html_select_time is a custom function that creates time dropdowns
for you. It can display any or all of hour, minute, second and
meridian.
</para>
<example>
<title>html_select_time</title>
<programlisting>
{html_select_time use_24_hours=true}
OUTPUT:
&lt;select name="Time_Hour"&gt;
&lt;option value="00"&gt;00&lt;/option&gt;
&lt;option value="01"&gt;01&lt;/option&gt;
&lt;option value="02"&gt;02&lt;/option&gt;
&lt;option value="03"&gt;03&lt;/option&gt;
&lt;option value="04"&gt;04&lt;/option&gt;
&lt;option value="05"&gt;05&lt;/option&gt;
&lt;option value="06"&gt;06&lt;/option&gt;
&lt;option value="07"&gt;07&lt;/option&gt;
&lt;option value="08"&gt;08&lt;/option&gt;
&lt;option value="09" selected&gt;09&lt;/option&gt;
&lt;option value="10"&gt;10&lt;/option&gt;
&lt;option value="11"&gt;11&lt;/option&gt;
&lt;option value="12"&gt;12&lt;/option&gt;
&lt;option value="13"&gt;13&lt;/option&gt;
&lt;option value="14"&gt;14&lt;/option&gt;
&lt;option value="15"&gt;15&lt;/option&gt;
&lt;option value="16"&gt;16&lt;/option&gt;
&lt;option value="17"&gt;17&lt;/option&gt;
&lt;option value="18"&gt;18&lt;/option&gt;
&lt;option value="19"&gt;19&lt;/option&gt;
&lt;option value="20"&gt;20&lt;/option&gt;
&lt;option value="21"&gt;21&lt;/option&gt;
&lt;option value="22"&gt;22&lt;/option&gt;
&lt;option value="23"&gt;23&lt;/option&gt;
&lt;/select&gt;
&lt;select name="Time_Minute"&gt;
&lt;option value="00"&gt;00&lt;/option&gt;
&lt;option value="01"&gt;01&lt;/option&gt;
&lt;option value="02"&gt;02&lt;/option&gt;
&lt;option value="03"&gt;03&lt;/option&gt;
&lt;option value="04"&gt;04&lt;/option&gt;
&lt;option value="05"&gt;05&lt;/option&gt;
&lt;option value="06"&gt;06&lt;/option&gt;
&lt;option value="07"&gt;07&lt;/option&gt;
&lt;option value="08"&gt;08&lt;/option&gt;
&lt;option value="09"&gt;09&lt;/option&gt;
&lt;option value="10"&gt;10&lt;/option&gt;
&lt;option value="11"&gt;11&lt;/option&gt;
&lt;option value="12"&gt;12&lt;/option&gt;
&lt;option value="13"&gt;13&lt;/option&gt;
&lt;option value="14"&gt;14&lt;/option&gt;
&lt;option value="15"&gt;15&lt;/option&gt;
&lt;option value="16"&gt;16&lt;/option&gt;
&lt;option value="17"&gt;17&lt;/option&gt;
&lt;option value="18"&gt;18&lt;/option&gt;
&lt;option value="19"&gt;19&lt;/option&gt;
&lt;option value="20" selected&gt;20&lt;/option&gt;
&lt;option value="21"&gt;21&lt;/option&gt;
&lt;option value="22"&gt;22&lt;/option&gt;
&lt;option value="23"&gt;23&lt;/option&gt;
&lt;option value="24"&gt;24&lt;/option&gt;
&lt;option value="25"&gt;25&lt;/option&gt;
&lt;option value="26"&gt;26&lt;/option&gt;
&lt;option value="27"&gt;27&lt;/option&gt;
&lt;option value="28"&gt;28&lt;/option&gt;
&lt;option value="29"&gt;29&lt;/option&gt;
&lt;option value="30"&gt;30&lt;/option&gt;
&lt;option value="31"&gt;31&lt;/option&gt;
&lt;option value="32"&gt;32&lt;/option&gt;
&lt;option value="33"&gt;33&lt;/option&gt;
&lt;option value="34"&gt;34&lt;/option&gt;
&lt;option value="35"&gt;35&lt;/option&gt;
&lt;option value="36"&gt;36&lt;/option&gt;
&lt;option value="37"&gt;37&lt;/option&gt;
&lt;option value="38"&gt;38&lt;/option&gt;
&lt;option value="39"&gt;39&lt;/option&gt;
&lt;option value="40"&gt;40&lt;/option&gt;
&lt;option value="41"&gt;41&lt;/option&gt;
&lt;option value="42"&gt;42&lt;/option&gt;
&lt;option value="43"&gt;43&lt;/option&gt;
&lt;option value="44"&gt;44&lt;/option&gt;
&lt;option value="45"&gt;45&lt;/option&gt;
&lt;option value="46"&gt;46&lt;/option&gt;
&lt;option value="47"&gt;47&lt;/option&gt;
&lt;option value="48"&gt;48&lt;/option&gt;
&lt;option value="49"&gt;49&lt;/option&gt;
&lt;option value="50"&gt;50&lt;/option&gt;
&lt;option value="51"&gt;51&lt;/option&gt;
&lt;option value="52"&gt;52&lt;/option&gt;
&lt;option value="53"&gt;53&lt;/option&gt;
&lt;option value="54"&gt;54&lt;/option&gt;
&lt;option value="55"&gt;55&lt;/option&gt;
&lt;option value="56"&gt;56&lt;/option&gt;
&lt;option value="57"&gt;57&lt;/option&gt;
&lt;option value="58"&gt;58&lt;/option&gt;
&lt;option value="59"&gt;59&lt;/option&gt;
&lt;/select&gt;
&lt;select name="Time_Second"&gt;
&lt;option value="00"&gt;00&lt;/option&gt;
&lt;option value="01"&gt;01&lt;/option&gt;
&lt;option value="02"&gt;02&lt;/option&gt;
&lt;option value="03"&gt;03&lt;/option&gt;
&lt;option value="04"&gt;04&lt;/option&gt;
&lt;option value="05"&gt;05&lt;/option&gt;
&lt;option value="06"&gt;06&lt;/option&gt;
&lt;option value="07"&gt;07&lt;/option&gt;
&lt;option value="08"&gt;08&lt;/option&gt;
&lt;option value="09"&gt;09&lt;/option&gt;
&lt;option value="10"&gt;10&lt;/option&gt;
&lt;option value="11"&gt;11&lt;/option&gt;
&lt;option value="12"&gt;12&lt;/option&gt;
&lt;option value="13"&gt;13&lt;/option&gt;
&lt;option value="14"&gt;14&lt;/option&gt;
&lt;option value="15"&gt;15&lt;/option&gt;
&lt;option value="16"&gt;16&lt;/option&gt;
&lt;option value="17"&gt;17&lt;/option&gt;
&lt;option value="18"&gt;18&lt;/option&gt;
&lt;option value="19"&gt;19&lt;/option&gt;
&lt;option value="20"&gt;20&lt;/option&gt;
&lt;option value="21"&gt;21&lt;/option&gt;
&lt;option value="22"&gt;22&lt;/option&gt;
&lt;option value="23" selected&gt;23&lt;/option&gt;
&lt;option value="24"&gt;24&lt;/option&gt;
&lt;option value="25"&gt;25&lt;/option&gt;
&lt;option value="26"&gt;26&lt;/option&gt;
&lt;option value="27"&gt;27&lt;/option&gt;
&lt;option value="28"&gt;28&lt;/option&gt;
&lt;option value="29"&gt;29&lt;/option&gt;
&lt;option value="30"&gt;30&lt;/option&gt;
&lt;option value="31"&gt;31&lt;/option&gt;
&lt;option value="32"&gt;32&lt;/option&gt;
&lt;option value="33"&gt;33&lt;/option&gt;
&lt;option value="34"&gt;34&lt;/option&gt;
&lt;option value="35"&gt;35&lt;/option&gt;
&lt;option value="36"&gt;36&lt;/option&gt;
&lt;option value="37"&gt;37&lt;/option&gt;
&lt;option value="38"&gt;38&lt;/option&gt;
&lt;option value="39"&gt;39&lt;/option&gt;
&lt;option value="40"&gt;40&lt;/option&gt;
&lt;option value="41"&gt;41&lt;/option&gt;
&lt;option value="42"&gt;42&lt;/option&gt;
&lt;option value="43"&gt;43&lt;/option&gt;
&lt;option value="44"&gt;44&lt;/option&gt;
&lt;option value="45"&gt;45&lt;/option&gt;
&lt;option value="46"&gt;46&lt;/option&gt;
&lt;option value="47"&gt;47&lt;/option&gt;
&lt;option value="48"&gt;48&lt;/option&gt;
&lt;option value="49"&gt;49&lt;/option&gt;
&lt;option value="50"&gt;50&lt;/option&gt;
&lt;option value="51"&gt;51&lt;/option&gt;
&lt;option value="52"&gt;52&lt;/option&gt;
&lt;option value="53"&gt;53&lt;/option&gt;
&lt;option value="54"&gt;54&lt;/option&gt;
&lt;option value="55"&gt;55&lt;/option&gt;
&lt;option value="56"&gt;56&lt;/option&gt;
&lt;option value="57"&gt;57&lt;/option&gt;
&lt;option value="58"&gt;58&lt;/option&gt;
&lt;option value="59"&gt;59&lt;/option&gt;
&lt;/select&gt;
&lt;select name="Time_Meridian"&gt;
&lt;option value="am" selected&gt;AM&lt;/option&gt;
&lt;option value="pm"&gt;PM&lt;/option&gt;
&lt;/select&gt;
</programlisting>
</example>
</sect2>
<sect2 id="custom.functions.math">
<title>math</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>equation</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>the equation to execute</entry>
</row>
<row>
<entry>format</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>the format of the result (sprintf)</entry>
</row>
<row>
<entry>var</entry>
<entry>numeric</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>equation variable value</entry>
</row>
<row>
<entry>assign</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>template variable the output will be assigned to</entry>
</row>
<row>
<entry>[var ...]</entry>
<entry>numeric</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>equation variable value</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
math allows the template designer to do math equations in the
template. Any numeric template variables may be used in the
equations, and the result is printed in place of the tag. The
variables used in the equation are passed as parameters, which can
be template variables or static values. +, -, /, *, abs, ceil, cos,
exp, floor, log, log10, max, min, pi, pow, rand, round, sin, sqrt,
srans and tan are all valid operators. Check the PHP documenation
for further information on these math functions.
</para>
<para>
If you supply the special "assign" attribute, the output of the
math function will be assigned to this template variable instead of
being output to the template.
</para>
<example>
<title>math</title>
<programlisting>
{* $height=4, $width=5 *}
{math equation="x + y" x=$height y=$width}
OUTPUT:
9
{* $row_height = 10, $row_width = 20, #col_div# = 2, assigned in template *}
{math equation="height * width / division"
height=$row_height
width=$row_width
division=#col_div#}
OUTPUT:
100
{* you can use parenthesis *}
{math equation="(( x + y ) / z )" x=2 y=10 z=2}
OUTPUT:
6
{* you can supply a format paramter in sprintf format *}
{math equation="x + y" x=4.4444 y=5.0000 format="%.2f"}
OUTPUT:
9.44
</programlisting>
</example>
</sect2>
<sect2 id="custom.functions.popup.init">
<title>popup_init</title>
<para>
popup is an integration of overLib, a library used for popup
windows. These are used for context sensitive information, such as
help windows or tooltips. popup_init must be called once at the
top of any page you plan on using the <link
linkend="custom.functions.popup">popup</link> function. overLib
was written by Erik Bosrup, and the homepage is located at
http://www.bosrup.com/web/overlib/.
</para>
<para>
This was added to Smarty 1.4.4.
</para>
</sect2>
<sect2 id="custom.functions.popup">
<title>popup</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Attribute Name</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>text</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>the text/html to display in the popup window</entry>
</row>
<row>
<entry>trigger</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>onMouseOver</emphasis></entry>
<entry>What is used to trigger the popup window. Can be
one of onMouseOver or onClick</entry>
</row>
<row>
<entry>sticky</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>false</emphasis></entry>
<entry>Makes the popup stick around until closed</entry>
</row>
<row>
<entry>caption</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the caption to title</entry>
</row>
<row>
<entry>fgcolor</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>color of the inside of the popup box</entry>
</row>
<row>
<entry>bgcolor</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>color of the border of the popup box</entry>
</row>
<row>
<entry>textcolor</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the color of the text inside the box</entry>
</row>
<row>
<entry>capcolor</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets color of the box's caption</entry>
</row>
<row>
<entry>closecolor</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the color of the close text</entry>
</row>
<row>
<entry>textfont</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the font to be used by the main text</entry>
</row>
<row>
<entry>captionfont</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the font of the caption</entry>
</row>
<row>
<entry>closefont</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the font for the "Close" text</entry>
</row>
<row>
<entry>textsize</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the size of the main text's font</entry>
</row>
<row>
<entry>captionsize</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the size of the caption's font</entry>
</row>
<row>
<entry>closesize</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the size of the "Close" text's font</entry>
</row>
<row>
<entry>width</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the width of the box</entry>
</row>
<row>
<entry>height</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the height of the box</entry>
</row>
<row>
<entry>left</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>false</emphasis></entry>
<entry>makes the popups go to the left of the mouse</entry>
</row>
<row>
<entry>right</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>false</emphasis></entry>
<entry>makes the popups go to the right of the mouse</entry>
</row>
<row>
<entry>center</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>false</emphasis></entry>
<entry>makes the popups go to the center of the mouse</entry>
</row>
<row>
<entry>above</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>false</emphasis></entry>
<entry>makes the popups go above the mouse. NOTE: only
possible when height has been set</entry>
</row>
<row>
<entry>below</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>false</emphasis></entry>
<entry>makes the popups go below the mouse</entry>
</row>
<row>
<entry>border</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>makes the border of the popups thicker or thinner</entry>
</row>
<row>
<entry>offsetx</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>how far away from the pointer the popup will show
up, horizontally</entry>
</row>
<row>
<entry>offsety</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>how far away from the pointer the popup will show
up, vertically</entry>
</row>
<row>
<entry>fgbackground</entry>
<entry>url to image</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>defines a picture to use instead of color for the
inside of the popup.</entry>
</row>
<row>
<entry>bgbackground</entry>
<entry>url to image</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>defines a picture to use instead of color for the
border of the popup. NOTE: You will want to set bgcolor
to "" or the color will show as well. NOTE: When having
a Close link, Netscape will re-render the table cells,
making things look incorrect</entry>
</row>
<row>
<entry>closetext</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the "Close" text to something else</entry>
</row>
<row>
<entry>noclose</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>does not display the "Close" text on stickies
with a caption</entry>
</row>
<row>
<entry>status</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the text in the browsers status bar</entry>
</row>
<row>
<entry>autostatus</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the status bar's text to the popup's text.
NOTE: overrides status setting</entry>
</row>
<row>
<entry>autostatuscap</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets the status bar's text to the caption's text.
NOTE: overrides status and autostatus settings</entry>
</row>
<row>
<entry>inarray</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>tells overLib to read text from this index in
the ol_text array, located in overlib.js. This
parameter can be used instead of text</entry>
</row>
<row>
<entry>caparray</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>tells overLib to read the caption from this index
in the ol_caps array</entry>
</row>
<row>
<entry>capicon</entry>
<entry>url</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>displays the image given before the popup caption</entry>
</row>
<row>
<entry>snapx</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>snaps the popup to an even position in a
horizontal grid</entry>
</row>
<row>
<entry>snapy</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>snaps the popup to an even position in a
vertical grid</entry>
</row>
<row>
<entry>fixx</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>locks the popups horizontal position Note:
overrides all other horizontal placement</entry>
</row>
<row>
<entry>fixy</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>locks the popups vertical position Note:
overrides all other vertical placement</entry>
</row>
<row>
<entry>background</entry>
<entry>url</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>sets image to be used instead of table box
background</entry>
</row>
<row>
<entry>padx</entry>
<entry>integer,integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>pads the background image with horizontal
whitespace for text placement. Note: this is a two
parameter command</entry>
</row>
<row>
<entry>pady</entry>
<entry>integer,integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>pads the background image with vertical
whitespace for text placement. Note: this is a two
parameter command</entry>
</row>
<row>
<entry>fullhtml</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>allows you to control the html over a background
picture completely. The html code is expected in the "text"
attribute</entry>
</row>
<row>
<entry>frame</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>controls popups in a different frame. See the
overlib page for more info on this function</entry>
</row>
<row>
<entry>timeout</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>calls the specified javascript function and takes
the return value as the text that should be displayed in
the popup window</entry>
</row>
<row>
<entry>delay</entry>
<entry>integer</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>makes that popup behave like a tooltip. It will
popup only after this delay in milliseconds</entry>
</row>
<row>
<entry>hauto</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>automatically determine if the popup should be to
the left or right of the mouse.</entry>
</row>
<row>
<entry>vauto</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>automatically determine if the popup should be
above or below the mouse.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
popup is used to create javascript popup windows.
</para>
<example>
<title>popup</title>
<programlisting>
{* popup_init must be called once at the top of the page *}
{popup_init}
{* create a link with a popup window when you move your mouse over *}
&lt;A href="mypage.html" {popup text="This link takes you to my page!"}&gt;mypage&lt;/A&gt;
{* you can use html, links, etc in your popup text *}
&lt;A href="mypage.html" {popup sticky=true caption="mypage contents"
text="&lt;UL&gt;&lt;LI&gt;links&lt;LI&gt;pages&lt;LI&gt;images&lt;/UL&gt;" snapx=10 snapy=10}&gt;mypage&lt;/A&gt;
OUTPUT:
(See the Smarty official web site for working examples.)
</programlisting>
</example>
</sect2>
<sect2>
<title>Creating your own Custom Functions</title>
<para>
Creating your own functions is a fairly straight forward process.
The best way is to look at the ones that come with Smarty as
examples. The function names begin with smarty_func_ and they are
located in the Smarty.addons.php file.
</para>
<itemizedlist>
<listitem><para>add your function to the Smarty.addons.php file.
It is recommended that you prepend your function name
with smarty_func_</para></listitem>
<listitem><para>map a template function name to your PHP function.
This is done at the top of the Smarty.class.php file
in the $custom_funcs array.</para></listitem>
<listitem><para>Thats it! you can now call that function
from within Smarty.</para></listitem>
</itemizedlist>
<para>
All attributes passed to custom functions are passed into the
first argument as an associative array. One way to get to those
values is to call extract(func_get_arg(0)); at the top of your
function. Anything that the function returns gets displayed
in place of the tag in the template.
</para>
<para>
Since version 1.4.0, custom functions are also passed Smarty object
as the second parameter. If the custom function declares the second
parameter passed by reference, it can then use Smarty object's
variable assignment and clearing functions to manipulate template
variables dynamically.
</para>
<para>
You can also add custom functions programatically with the <link
linkend="api.register.function">register_function API</link>.
</para>
</sect2>
</sect1>
<sect1 id="variable.modifiers">
<title>Variable Modifiers</title>
<para>
Variable modifiers are a bit different than <link
linkend="custom.functions">custom functions</link>. Variable modifiers
alter variable contents before they are displayed to the template. All
modifiers will get the value of the variable as the first argument, and
must return a single value. Modifier parameters are separated by
colons. Any additional parameters passed to a modifier are passed as-is
positionally, much like calling a PHP function. You can also use native
PHP functions as modifiers, but only if they expect the correct
arguments. If they do not, you can always write a wrapper function in
Smarty to get what you want. You can chain as many modifiers together
on a variable as you like, separating each with a vertical pipe "|".
</para>
<para>
NOTE: if you apply a modifier to an array instead of a single value
variable, the modifier will be applied to every value in that array. If
you really want the entire array passed to the modifier, you must
prepend it with an "@" sign like so: {$articleTitle|@count} (this will
print out the number of elements in the $articleTitle array.)
</para>
<sect2>
<title>capitalize</title>
<para>
This is used to capitalize the first letter of all words in a variable.
</para>
<example>
<title>capitalize</title>
<programlisting>
{$articleTitle}
{$articleTitle|capitalize}
OUTPUT:
Police begin campaign to rundown jaywalkers.
Police Begin Campaign To Rundown Jaywalkers.
</programlisting>
</example>
</sect2>
<sect2>
<title>count_characters</title>
<para>
This is used to count the number of characters in a variable.
</para>
<example>
<title>count_characters</title>
<programlisting>
{$articleTitle}
{$articleTitle|count_characters}
OUTPUT:
Cold Wave Linked to Temperatures
32
</programlisting>
</example>
</sect2>
<sect2>
<title>count_paragraphs</title>
<para>
This is used to count the number of paragraphs in a variable.
</para>
<example>
<title>count_paragraphs</title>
<programlisting>
{$articleTitle}
{$articleTitle|count_paragraphs}
OUTPUT:
War Dims Hope for Peace. Child's Death Ruins Couple's Holiday.
Man is Fatally Slain. Death Causes Loneliness, Feeling of Isolation.
2
</programlisting>
</example>
</sect2>
<sect2>
<title>count_sentences</title>
<para>
This is used to count the number of sentences in a variable.
</para>
<example>
<title>count_sentences</title>
<programlisting>
{$articleTitle}
{$articleTitle|count_sentences}
OUTPUT:
Two Soviet Ships Collide - One Dies. Enraged Cow Injures Farmer with Axe.
2
</programlisting>
</example>
</sect2>
<sect2>
<title>count_words</title>
<para>
This is used to count the number of words in a variable.
</para>
<example>
<title>count_words</title>
<programlisting>
{$articleTitle}
{$articleTitle|count_words}
OUTPUT:
Dealers Will Hear Car Talk at Noon.
7
</programlisting>
</example>
</sect2>
<sect2 id="date.format">
<title>date_format</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Parameter Position</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>1</entry>
<entry>string</entry>
<entry>No</entry>
<entry>%b %e, %Y</entry>
<entry>This is the format for the outputted date.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
This formats a date and time into the given strftime() format.
Dates can be passed to Smarty as unix timestamps, mysql timestamps
or any string made up of month day year (parsable by strtotime).
Designers can then use date_format to have complete control of the
formatting of the date.
</para>
<example>
<title>date_format</title>
<programlisting>
{$currentDate}
{$currentDate|date_format:"%A, %B %e, %Y"}
{$currentDate|date_format:"%H:%M:%S"}
OUTPUT:
Feb 6, 2001
Tuesday, February 6, 2001
14:33:00
</programlisting>
</example>
<example>
<title>date_format conversion specifiers</title>
<programlisting>
%a - abbreviated weekday name according to the current locale
%A - full weekday name according to the current locale
%b - abbreviated month name according to the current locale
%B - full month name according to the current locale
%c - preferred date and time representation for the current locale
%C - century number (the year divided by 100 and truncated to an integer, range 00 to 99)
%d - day of the month as a decimal number (range 00 to 31)
%D - same as %m/%d/%y
%e - day of the month as a decimal number, a single digit is preceded by a
space (range 1 to 31)
%g - Week-based year within century [00,99]
%G - Week-based year, including the century [0000,9999]
%h - same as %b
%H - hour as a decimal number using a 24-hour clock (range 00 to 23)
%I - hour as a decimal number using a 12-hour clock (range 01 to 12)
%j - day of the year as a decimal number (range 001 to 366)
%k - Hour (24-hour clock) single digits are preceded by a blank. (range 0 to 23)
%l - hour as a decimal number using a 12-hour clock, single digits preceeded by
a space (range 1 to 12)
%m - month as a decimal number (range 01 to 12)
%M - minute as a decimal number
%n - newline character
%p - either `am' or `pm' according to the given time value, or the corresponding strings for the current locale
%r - time in a.m. and p.m. notation
%R - time in 24 hour notation
%S - second as a decimal number
%t - tab character
%T - current time, equal to %H:%M:%S
%u - weekday as a decimal number [1,7], with 1 representing Monday
%U - week number of the current year as a decimal number, starting with the first Sunday as the first day of the first week
%V - The ISO 8601:1988 week number of the current year as a decimal number, range 01 to 53, where week 1
is the first week that has at least 4 days in the current year, and with Monday as the first day of the week.
%w - day of the week as a decimal, Sunday being 0
%W - week number of the current year as a decimal number, starting with the first Monday as the first day of the first week
%x - preferred date representation for the current locale without the time
%X - preferred time representation for the current locale without the date
%y - year as a decimal number without a century (range 00 to 99)
%Y - year as a decimal number including the century
%Z - time zone or name or abbreviation
%% - a literal `%' character
PROGRAMMERS NOTE: date_format is essentially a wrapper to PHP's strftime()
function. You may have more or less conversion specifiers available depending
on your system's strftime() function where PHP was compiled. Check your
system's manpage for a full list of valid specifiers.
</programlisting>
</example>
</sect2>
<sect2>
<title>default</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Parameter Position</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>1</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>empty</emphasis></entry>
<entry>This is the default value to output if the
variable is empty.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
This is used to set a default value for a variable. If the variable
is empty or unset, the given default value is printed instead.
Default takes one argument.
</para>
<example>
<title>default</title>
<programlisting>
{* this will display "no title" (without the quotes) if $articleTitle is empty *}
{$articleTitle|default:"no title"}
OUTPUT:
no title
</programlisting>
</example>
</sect2>
<sect2>
<title>escape</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=posvals>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Parameter Position</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Possible Values</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>1</entry>
<entry>string</entry>
<entry>No</entry>
<entry>html,url,quotes</entry>
<entry>html</entry>
<entry>This is the escape format to use.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
This is used to html escape, url escape, or escape single quotes on
a variable not already escaped. By default, the variable is html
escaped.
</para>
<example>
<title>escape</title>
<programlisting>
{$articleTitle}
{$articleTitle|escape}
{$articleTitle|escape:"html"}
{$articleTitle|escape:"url"}
{$articleTitle|escape:"quotes"}
OUTPUT:
'Stiff Opposition Expected to Casketless Funeral Plan'
'Stiff%20Opposition%20Expected%20to%20Casketless%20Funeral%20Plan'
'Stiff%20Opposition%20Expected%20to%20Casketless%20Funeral%20Plan'
'Stiff+Opposition+Expected+to+Casketless+Funeral+Plan'
\'Stiff Opposition Expected to Casketless Funeral Plan\'
</programlisting>
</example>
</sect2>
<sect2>
<title>lower</title>
<para>
This is used to lowercase a variable.
</para>
<example>
<title>lower</title>
<programlisting>
{$articleTitle}
{$articleTitle|lower}
OUTPUT:
Two Convicts Evade Noose, Jury Hung.
two convicts evade noose, jury hung.
</programlisting>
</example>
</sect2>
<sect2>
<title>regex_replace</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Parameter Position</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>1</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>This is the regular expression to be replaced.</entry>
</row>
<row>
<entry>2</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>This is the string of text to replace with.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
A regular expression search and replace on a variable. Use the
syntax for preg_replace() from the PHP manual.
</para>
<para>
NOTE: This function was added to Smarty 1.4.3.
</para>
<example>
<title>regex_replace</title>
<programlisting>
{* replace each carriage return, tab &amp; new line with a space *}
{$articleTitle}
{$articleTitle|regex_replace:"/[\r\t\n]/":" "}
OUTPUT:
Infertility unlikely to
be passed on, experts say
Infertility unlikely to be passed on, experts say
</programlisting>
</example>
</sect2>
<sect2>
<title>replace</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Parameter Position</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>1</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>This is the string of text to be replaced.</entry>
</row>
<row>
<entry>2</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>This is the string of text to replace with.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
A simple search and replace on a variable.
</para>
<example>
<title>replace</title>
<programlisting>
{$articleTitle}
{$articleTitle|replace:"Garden":"Vineyard"}
{$articleTitle|replace:" ":" "}
OUTPUT:
Child's Stool Great for Use in Garden.
Child's Stool Great for Use in Vineyard.
Child's Stool Great for Use in Garden.
</programlisting>
</example>
</sect2>
<sect2>
<title>spacify</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Parameter Position</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>1</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>one space</emphasis></entry>
<entry>This what gets inserted between each character of
the variable.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
spacify is a way to insert a space between every character of a variable.
You can optionally pass a different character (or string) to insert.
</para>
<example>
<title>spacify</title>
<programlisting>
{$articleTitle}
{$articleTitle|spacify}
{$articleTitle|spacify:"^^"}
OUTPUT:
Something Went Wrong in Jet Crash, Experts Say.
S o m e t h i n g W e n t W r o n g i n J e t C r a s h , E x p e r t s S a y .
S^^o^^m^^e^^t^^h^^i^^n^^g^^ ^^W^^e^^n^^t^^ ^^W^^r^^o^^n^^g^^ ^^i^^n^^ ^^J^^e^^t^^ ^^C^^r^^a^^s^^h^^,^^ ^^E^^x^^p^^e^^r^^t^^s^^ ^^S^^a^^y^^.
</programlisting>
</example>
</sect2>
<sect2>
<title>string_format</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Parameter Position</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>1</entry>
<entry>string</entry>
<entry>Yes</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>This is what format to use. (sprintf)</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
This is a way to format strings, such as decimal numbers and such.
Use the syntax for sprintf for the formatting.
</para>
<example>
<title>string_format</title>
<programlisting>
{$number}
{$number|string_format:"%.2f"}
{$number|string_format:"%d"}
OUTPUT:
23.5787446
23.58
24
</programlisting>
</example>
</sect2>
<sect2>
<title>strip_tags</title>
<para>
This strips out markup tags, basically anything between &lt; and &gt;.
</para>
<example>
<title>strip_tags</title>
<programlisting>
{$articleTitle}
{$articleTitle|strip_tags}
OUTPUT:
Blind Woman Gets &lt;font face="helvetica"&gt;New Kidney&lt;/font&gt; from Dad she Hasn't Seen in &lt;b&gt;years&lt;/b&gt;.
Blind Woman Gets New Kidney from Dad she Hasn't Seen in years.
</programlisting>
</example>
</sect2>
<sect2>
<title>truncate</title>
<informaltable frame=all>
<tgroup cols=3>
<colspec colname=param>
<colspec colname=type>
<colspec colname=required>
<colspec colname=default>
<colspec colname=desc>
<thead>
<row>
<entry>Parameter Position</entry>
<entry>Type</entry>
<entry>Required</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>1</entry>
<entry>integer</entry>
<entry>No</entry>
<entry>80</entry>
<entry>This determines how many characters to truncate
to.</entry>
</row>
<row>
<entry>2</entry>
<entry>string</entry>
<entry>No</entry>
<entry>...</entry>
<entry>This is the text to append if truncation occurs.</entry>
</row>
<row>
<entry>3</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry>false</entry>
<entry>This determines whether or not to truncate at a
word boundary (false), or at the exact character (true).</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
This truncates a variable to a character length, default is 80. As
an optional second parameter, you can specify a string of text
to display at the end if the variable was truncated. The
characters in the string are included with the original truncation length.
By default, truncate will attempt to cut off at a word boundary. If
you want to cut off at the exact character length, pass the optional
third parameter of true.
</para>
<example>
<title>truncate</title>
<programlisting>
{$articleTitle}
{$articleTitle|truncate}
{$articleTitle|truncate:30}
{$articleTitle|truncate:30:""}
{$articleTitle|truncate:30:"---"}
{$articleTitle|truncate:30:"":true}
{$articleTitle|truncate:30:"...":true}
OUTPUT:
Two Sisters Reunite after Eighteen Years at Checkout Counter.
Two Sisters Reunite after Eighteen Years at Checkout Counter.
Two Sisters Reunite after...
Two Sisters Reunite after
Two Sisters Reunite after---
Two Sisters Reunite after Eigh
Two Sisters Reunite after E...
</programlisting>
</example>
</sect2>
<sect2>
<title>upper</title>
<para>
This is used to uppercase a variable.
</para>
<example>
<title>upper</title>
<programlisting>
{$articleTitle}
{$articleTitle|upper}
OUTPUT:
If Strike isn't Settled Quickly it may Last a While.
IF STRIKE ISN'T SETTLED QUICKLY IT MAY LAST A WHILE.
</programlisting>
</example>
</sect2>
<sect2>
<title>Combining Modifiers</title>
<para>
You can combine as many modifiers as you like on a single variable.
This allows the ability to combine the application of different
modifiers to a single variable. The modifiers will be applied to
the variable in the order they are combined, from left to right.
</para>
<example>
<title>combining modifiers</title>
<programlisting>
{$articleTitle}
{$articleTitle|upper|spacify}
{$articleTitle|lower|spacify|truncate}
{$articleTitle|lower|truncate:30|spacify}
{$articleTitle|lower|spacify|truncate:30:". . ."}
OUTPUT:
Smokers are Productive, but Death Cuts Efficiency.
S M O K E R S A R E P R O D U C T I V E , B U T D E A T H C U T S E F F I C I E N C Y .
s m o k e r s a r e p r o d u c t i v e , b u t d e a t h c u t s...
s m o k e r s a r e p r o d u c t i v e , b u t . . .
s m o k e r s a r e p. . .
</programlisting>
</example>
</sect2>
<sect2>
<title>Creating your own Variable Modifiers</title>
<para>
Creating your own modifiers is a fairly straight forward process.
The best way is to look at the ones that come with Smarty as
examples. The function names begin with smarty_mod_ and they are
located in the Smarty.addons.php file.
</para>
<itemizedlist>
<listitem><para>add your modifier to the Smarty.addons.php file.
It is recommended that you prepend your function name
with smarty_mod_</para></listitem>
<listitem><para>map a template modifier name to your PHP function.
This is done at the top of the Smarty.class.php file
in the $custom_mods array.</para></listitem>
<listitem><para>Thats it! you can now use that modifier
from within Smarty.</para></listitem>
</itemizedlist>
<para>
You can also add modifiers programatically with the <link
linkend="api.register.modifier">register_modifier API</link>.
</para>
</sect2>
</sect1>
</chapter>
<chapter id="chapter.debugging.console">
<title>Debugging Console</title>
<para>
There is a dubugging console included with Smarty. The console informs you
of all the included templates, assigned variables and config file variables
for the current invocation of the template. A template named "debug.tpl" is
included with the distribution of Smarty which controls the formatting of
the console. Set $debugging to true in Smarty, and if needed set $debug_tpl
to the template resource path for debug.tpl (this is in $template_dir by
default.) When you load the page, a javascript console window should pop up
and give you the names of all the included templates and assigned variables
for the current page. To disable the debugging console, set $debugging to
false. You can also temporarily turn on the debugging console by putting
SMARTY_DEBUG in the URL if you enable this option with <link
linkend="setting.debugging.ctrl">$debugging_ctrl</link>.
</para>
<para>
TECHNICAL NOTE: The debugging console does not work when you use the fetch()
API, only when using display(). It also does not work when the template
content is pulled from the cache. The debugging console should be completely
transparent to your application. It is a set of javascript statements added
to the very bottom of the generated template. If you do not like javascript,
you can edit the debug.tpl template to format the output however you like.
Debug data is not cached and debug.tpl info is not included in the output of
the debug console.
</para>
<para>
NOTE: This feature was added to Smarty 1.4.3.
</para>
<para>
NOTE: The load times of each template file and config file have been added to
the debug output in Smarty 1.4.6. This output is in seconds, or fractions
thereof.
</para>
</chapter>
<chapter>
<title>Troubleshooting</title>
<para></para>
<sect1>
<title>Smarty/PHP errors</title>
<para>
Smarty can catch many errors such as missing tag attributes
or malformed variable names. If this happens, you will see an error
similar to the following:
</para>
<example>
<title>Smarty errors</title>
<programlisting>
Warning: Smarty: [in index.tpl line 4]: syntax error: unknown tag - '%blah'
in /path/to/smarty/Smarty.class.php on line 1041
Fatal error: Smarty: [in index.tpl line 28]: syntax error: missing section name
in /path/to/smarty/Smarty.class.php on line 1041
</programlisting>
</example>
<para>
Smarty shows you the template name, the line number and the error.
After that, the error consists of the actual line number in the Smarty
class that the error occured.
</para>
<para>
There are certain errors that Smarty cannot catch, such as missing
close tags. These types of errors usually end up in PHP compile-time
parsing errors.
</para>
<example>
<title>PHP parsing errors</title>
<programlisting>
Parse error: parse error in /path/to/smarty/templates_c/index.tpl.php on line 75
</programlisting>
</example>
<para>
When you encounter a PHP parsing error, the error line number will
correspond to the compiled PHP script, not the template itself. Usually
you can look at the template and spot the syntax error. Here are some
common things to look for: missing close tags for {if}{/if} or
{section}{/section}, or syntax of logic within an {if} tag. If you
can't find the error, you might have to open the compiled PHP file and
go to the line number to figure out where the corresponding error is in
the template.
</para>
</sect1>
</chapter>
<chapter id="tips">
<title>Tips & Tricks</title>
<para>
</para>
<sect1>
<title>Blank Variable Handling</title>
<para>
There may be times when you want to print a default value for an empty
variable instead of printing nothing, such as printing "&amp;nbsp;" so that
table backgrounds work properly. Many would use an {if} statement to
handle this, but there is a shorthand way with Smarty, using the
<emphasis>default</emphasis> variable modifier.
</para>
<example>
<title>Printing &amp;nbsp; when a variable is empty</title>
<programlisting>
{* the long way *}
{if $title eq ""}
&amp;nbsp;
{else}
{$title}
{/if}
{* the short way *}
{$title|default:"&amp;nbsp;"}
</programlisting>
</example>
</sect1>
<sect1>
<title>Default Variable Handling</title>
<para>
If a variable is used frequently throughout your templates, applying
the default modifier every time it is mentioned can get a bit ugly. You
can remedy this by assigning the variable its default value with the
<link linkend="custom.functions.assign">assign</link> function.
</para>
<example>
<title>Assigning a template variable its default value</title>
<programlisting>
{* do this somewhere at the top of your template *}
{assign var="title" value=$title|default:"no title"}
{* if $title was empty, it now contains the value "no title" when you print it *}
{$title}
</programlisting>
</example>
</sect1>
<sect1>
<title>Passing variable title to header template</title>
<para>
When the majority of your templates use the same headers and footers, it
is common to split those out into their own templates and include them.
But what if the header needs to have a different title, depending on
what page you are coming from? You can pass the title to the header when
it is included.
</para>
<example>
<title>Passing the title variable to the header template</title>
<programlisting>
mainpage.tpl
------------
{include file="header.tpl" title="Main Page"}
{* template body goes here *}
{include file="footer.tpl"}
archives.tpl
------------
{config_load file="archive_page.conf"}
{include file="header.tpl" title=#archivePageTitle#}
{* template body goes here *}
{include file="footer.tpl"}
header.tpl
----------
&lt;HTML&gt;
&lt;HEAD&gt;
&lt;TITLE&gt;{$title|default:"BC News"}&lt;/TITLE&gt;
&lt;/HEAD&gt;
&lt;BODY&gt;
footer.tpl
----------
&lt;/BODY&gt;
&lt;/HTML&gt;
</programlisting>
</example>
<para>
When the main page is drawn, the title of "Main Page" is passed to the
header.tpl, and will subsequently be used as the title. When the
archives page is drawn, the title will be "Archives". Notice in the
archive example, we are using a variable from the archives_page.conf
file instead of a hard coded variable. Also notice that "BC News" is
printed if the $title variable is not set, using the
<emphasis>default</emphasis> variable modifier.
</para>
</sect1>
<sect1>
<title>Dates</title>
<para>
As a rule of thumb, always pass dates to Smarty as timestamps.
This allows template designers to use <link
linkend="date.format">date_format</link> for full control over date
formatting, and also makes it easy to compare dates if necessary.
</para>
<para>
NOTE: As of Smarty 1.4.0, you can pass dates to Smarty as unix
timestamps, mysql timestamps, or any date parsable by strtotime().
</para>
<example>
<title>using date_format</title>
<programlisting>
{$startDate|date_format}
OUTPUT:
Jan 4, 2001
{$startDate|date_format:"%Y/%m/%d"}
OUTPUT:
2001/01/04
{if $date1 < $date2}
...
{/if}
</programlisting>
</example>
<para>
When using {html_select_date} in a template, The programmer will most
likely want to convert the output from the form back into timestamp
format. Here is a function to help you with that.
</para>
<example>
<title>converting form date elements back to a timestamp</title>
<programlisting>
// this assumes your form elements are named
// startDate_Day, startDate_Month, startDate_Year
$startDate = makeTimeStamp($startDate_Year,$startDate_Month,$startDate_day);
function makeTimeStamp($year="",$month="",$day="")
{
if(empty($year))
$year = strftime("%Y");
if(empty($month))
$month = strftime("%m");
if(empty($day))
$day = strftime("%d");
return mktime(0,0,0,$month,$day,$year);
}
</programlisting>
</example>
</sect1>
<sect1>
<title>WAP/WML</title>
<para>
WAP/WML templates require a php Content-Type header to be passed along
with the template. The easist way to do this would be to write a custom
function that prints the header. If you are using caching, that won't
work so we'll do it using the insert tag (remember insert tags are not
cached!) Be sure that there is nothing output to the browser before the
template, or else the header may fail.
</para>
<example>
<title>using insert to write a WML Content-Type header</title>
<programlisting>
// be sure apache is configure for the .wml extensions!
// put this function somewhere in your application, or in Smarty.addons.php
function insert_header() {
// this function expects $content argument
extract(func_get_arg(0));
if(empty($content))
return;
header($content);
return;
}
// your Smarty template _must_ begin with the insert tag example:
{insert name=header content="Content-Type: text/vnd.wap.wml"}
&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml"&gt;
&lt;!-- begin new wml deck --&gt;
&lt;wml&gt;
&lt;!-- begin first card --&gt;
&lt;card&gt;
&lt;do type="accept"&gt;
&lt;go href="#two"/&gt;
&lt;/do&gt;
&lt;p&gt;
Welcome to WAP with Smarty!
Press OK to continue...
&lt;/p&gt;
&lt;/card&gt;
&lt;!-- begin second card --&gt;
&lt;card id="two"&gt;
&lt;p&gt;
Pretty easy isn't it?
&lt;/p&gt;
&lt;/card&gt;
&lt;/wml&gt;
</programlisting>
</example>
</sect1>
<sect1 id="tips.componentized.templates">
<title>Componentized Templates</title>
<para>
This tip is a bit of a hack, but still a neat idea. Use at your own
risk. ;-)
</para>
<para>
Traditionally, programming templates into your applications goes as
follows: First, you accumulate your variables within your PHP
application, (maybe with database queries.) Then, you instantiate your
Smarty object, assign the variables and display the template. So lets
say for example we have a stock ticker on our template. We would
collect the stock data in our application, then assign these variables
in the template and display it. Now wouldn't it be nice if you could
add this stock ticker to any application by merely including the
template, and not worry about fetching the data up front?
</para>
<para>
As of Smarty 1.4.0, you can embed php into your templates with the
{php}{/php} tags. With this, you can setup self contained templates
with their own data structures for assigning their own variables. With
the logic embedded like this, you can keep the template & logic
together. This way no matter where the template source is coming from,
it is always together as one component.
</para>
<example>
<title>componentized template</title>
<programlisting>
{* Smarty *}
{php}
// setup our function for fetching stock data
function fetch_ticker($symbol,&$ticker_name,&$ticker_price) {
// put logic here that fetches $ticker_name
// and $ticker_price from some resource
}
// call the function
fetch_ticker("YHOO",$ticker_name,$ticker_price);
// assign template variables
$this->assign("ticker_name",$ticker_name);
$this->assign("ticker_price",$ticker_price);
{/php}
Stock Name: {$ticker_name} Stock Price: {$ticker_price}
</programlisting>
</example>
<para>
As of Smarty 1.5.0, there is even a cleaner way. You can include php in
your templates with the {include_php ...} tag. This way you can keep
your PHP logic separated from the template logic. See the <link
linkend="builtin.functions.include.php">include_php</link> function for
more information.
</para>
<example>
<title>componentized template with include_php</title>
<programlisting>
load_ticker.php
---------------
&lt;?php
// setup our function for fetching stock data
function fetch_ticker($symbol,&$ticker_name,&$ticker_price) {
// put logic here that fetches $ticker_name
// and $ticker_price from some resource
}
// call the function
fetch_ticker("YHOO",$ticker_name,$ticker_price);
// assign template variables
$this->assign("ticker_name",$ticker_name);
$this->assign("ticker_price",$ticker_price);
?&gt;
index.tpl
---------
{* Smarty *}
{include_php file="load_ticker.php"}
Stock Name: {$ticker_name} Stock Price: {$ticker_price}
</programlisting>
</example>
</sect1>
</chapter>
<chapter id="resources">
<title>Resources</title>
<para>
Smarty's homepage is located at http://www.phpinsider.com/php/code/Smarty/.
You can join the mailing list by sending an e-mail to
subscribe-smarty@lists.ispi.net. An archive of the mailing list can be
viewed at http://marc.theaimsgroup.com/?l=smarty&amp;r=1&amp;w=2
</para>
</chapter>
<chapter id="bugs">
<title>BUGS</title>
<para>
Check the BUGS file that comes with the latest distribution of Smarty, or
check the website.
</para>
</chapter>
<chapter id="pear">
<title>PEAR</title>
<para>
Smarty uses the PEAR libraries for some of its error handling routines.
PEAR libraries come with the distribution of PHP. Be sure that the path to
these libraries is included in your php include_path. un*x users check
/usr/local/lib/php. Windows users check C:/php/pear.
</para>
</chapter>
</book>