Files
smarty/docs/en/designers/language-builtin-functions.xml
2004-03-28 15:15:38 +00:00

1602 lines
54 KiB
XML

<?xml version="1.0" encoding="iso-8859-1"?>
<!-- $Revision$ -->
<chapter id="language.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>
<sect1 id="language.function.capture">
<title>capture</title>
<informaltable frame="all">
<tgroup cols="5">
<colspec colname="param" align="center" />
<colspec colname="type" align="center" />
<colspec colname="required" align="center" />
<colspec colname="default" align="center" />
<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>no</entry>
<entry><emphasis>default</emphasis></entry>
<entry>The name of the captured block</entry>
</row>
<row>
<entry>assign</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The variable name where to assign the captured output to</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<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.
</para>
<note>
<title>Technical Note</title>
<para>
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>
</note>
<caution>
<para>
Be careful when capturing <command>insert</command> output. If
you have caching turned on and you have <command>insert</command>
commands that you expect to run within cached content, do not
capture this content.
</para>
</caution>
<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;
{$smarty.capture.banner}
&lt;/td&gt;
&lt;/tr&gt;
{/if}</programlisting>
</example>
</para>
</sect1>
<sect1 id="language.function.config.load">
<title>config_load</title>
<informaltable frame="all">
<tgroup cols="5">
<colspec colname="param" align="center" />
<colspec colname="type" align="center" />
<colspec colname="required" align="center" />
<colspec colname="default" align="center" />
<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.
</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.
See <link linkend="config.files">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>
</sect1>
<sect1 id="language.function.foreach">
<title>foreach,foreachelse</title>
<informaltable frame="all">
<tgroup cols="5">
<colspec colname="param" align="center" />
<colspec colname="type" align="center" />
<colspec colname="required" align="center" />
<colspec colname="default" align="center" />
<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=$contact}
{$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>
<para>
Foreach-loops also have their own variables that handle foreach properties.
These are indicated like so: {$smarty.foreach.foreachname.varname} with
foreachname being the name specified as the <emphasis>name</emphasis>
attribute of foreach
</para>
<sect2 id="foreach.property.iteration">
<title>iteration</title>
<para>
iteration is used to display the current loop iteration.
</para>
<para>
Iteration always starts with 1 and is incremented by one
one each iteration.
</para>
</sect2>
<sect2 id="foreach.property.first">
<title>first</title>
<para>
<emphasis>first</emphasis> is set to true if the current foreach iteration is the first
one.
</para>
</sect2>
<sect2 id="foreach.property.last">
<title>last</title>
<para>
<emphasis>last</emphasis> is set to true if the current foreach iteration is the last
one.
</para>
</sect2>
<sect2 id="foreach.property.show">
<title>show</title>
<para>
<emphasis>show</emphasis> is used as a parameter to foreach.
<emphasis>show</emphasis> is a boolean value, true or false. If
false, the foreach will not be displayed. If there is a foreachelse
present, that will be alternately displayed.
</para>
</sect2>
<sect2 id="foreach.property.total">
<title>total</title>
<para>
<emphasis>total</emphasis> is used to display the number of iterations that this foreach
will loop. This can be used inside or after the foreach.
</para>
</sect2>
</sect1>
<sect1 id="language.function.include">
<title>include</title>
<informaltable frame="all">
<tgroup cols="5">
<colspec colname="param" align="center" />
<colspec colname="type" align="center" />
<colspec colname="required" align="center" />
<colspec colname="default" align="center" />
<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 can 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>
<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>
<para>
Use the syntax for <link
linkend="template.resources">template resources</link> to
include files outside of the $template_dir directory.
</para>
<example>
<title>function include template resource examples</title>
<programlisting>
{* absolute filepath *}
{include file="/usr/local/include/templates/header.tpl"}
{* absolute filepath (same thing) *}
{include file="file:/usr/local/include/templates/header.tpl"}
{* windows absolute filepath (MUST use "file:" prefix) *}
{include file="file:C:/www/pub/templates/header.tpl"}
{* include from template resource named "db" *}
{include file="db:header.tpl"}</programlisting>
</example>
</sect1>
<sect1 id="language.function.include.php">
<title>include_php</title>
<informaltable frame="all">
<tgroup cols="5">
<colspec colname="param" align="center" />
<colspec colname="type" align="center" />
<colspec colname="required" align="center" />
<colspec colname="default" align="center" />
<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>once</entry>
<entry>boolean</entry>
<entry>No</entry>
<entry><emphasis>true</emphasis></entry>
<entry>whether or not to include the php file more than
once if included multiple times</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>
<note>
<title>Technical Note</title>
<para>
include_php is pretty much deprecated from Smarty, you can
accomplish the same functionality via a custom template function.
The only reason to use include_php is if you really have a need to
quarantine the php function away from the plugin directory or your
application code. See the <link
linkend="tips.componentized.templates">componentized template
example</link> for details.
</para>
</note>
<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>
By default, php files are only included once even if called
multiple times in the template. You can specify that it should be
included every time with the <emphasis>once</emphasis> attribute.
Setting once to false will include the php script each time it is
included in the template.
</para>
<para>
You can optionally pass the <emphasis>assign</emphasis> attribute,
which will specify a template variable name that the output of
<emphasis>include_php</emphasis> will be assigned to instead of
displayed.
</para>
<para>
The smarty object is available as $this within the PHP script that you
include.
</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>
</sect1>
<sect1 id="language.function.insert">
<title>insert</title>
<informaltable frame="all">
<tgroup cols="5">
<colspec colname="param" align="center" />
<colspec colname="type" align="center" />
<colspec colname="required" align="center" />
<colspec colname="default" align="center" />
<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>script</entry>
<entry>string</entry>
<entry>No</entry>
<entry><emphasis>n/a</emphasis></entry>
<entry>The name of the php script that is included before
the insert function is called</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>
Insert tags work much like include tags, except that insert tags
are not cached when you have template <link
linkend="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, and we
don't want this contents cached with the page. 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 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 "assign" attribute, the output of the insert tag
will be assigned to this template variable instead of being output
to the template. NOTE: assigning the output to a template variable
isn't too useful with caching enabled.
</para>
<para>
If you supply the "script" attribute, this php script will be
included (only once) before the insert function is executed. This
is the case where the insert function may not exist yet, and a php
script must be included first to make it work. The path can be
either absolute, or relative to $trusted_dir. When security is
enabled, the script must reside in $trusted_dir.
</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.
</para>
<note>
<title>Technical Note</title>
<para>
It is possible to have portions of the template not
cached. If you have <link linkend="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>
</note>
</sect1>
<sect1 id="language.function.if">
<title>if,elseif,else</title>
<para>
<emphasis>{if}</emphasis> 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. All PHP conditionals
are recognized, such as <emphasis>||</emphasis>, <emphasis>or</emphasis>,
<emphasis>&amp;&amp;</emphasis>, <emphasis>and</emphasis>, etc.
</para>
<para>
The following is a list of recognized qualifiers, which must be
separated from surrounding elements by spaces. Note that items listed
in [brackets] are optional. PHP equivalents are shown where applicable.
</para>
<informaltable frame="all">
<tgroup cols="4">
<colspec colname="qualifier" align="center" />
<colspec colname="alternates" align="center" />
<colspec colname="meaning" />
<colspec colname="example" />
<colspec colname="php" />
<thead>
<row>
<entry>Qualifier</entry>
<entry>Alternates</entry>
<entry>Syntax Example</entry>
<entry>Meaning</entry>
<entry>PHP Equivalent</entry>
</row>
</thead>
<tbody>
<row>
<entry>==</entry>
<entry>eq</entry>
<entry>$a eq $b</entry>
<entry>equals</entry>
<entry>==</entry>
</row>
<row>
<entry>!=</entry>
<entry>ne, neq</entry>
<entry>$a neq $b</entry>
<entry>not equals</entry>
<entry>!=</entry>
</row>
<row>
<entry>&gt;</entry>
<entry>gt</entry>
<entry>$a gt $b</entry>
<entry>greater than</entry>
<entry>&gt;</entry>
</row>
<row>
<entry>&lt;</entry>
<entry>lt</entry>
<entry>$a lt $b</entry>
<entry>less than</entry>
<entry>&lt;</entry>
</row>
<row>
<entry>&gt;=</entry>
<entry>gte, ge</entry>
<entry>$a ge $b</entry>
<entry>greater than or equal</entry>
<entry>&gt;=</entry>
</row>
<row>
<entry>&lt;=</entry>
<entry>lte, le</entry>
<entry>$a le $b</entry>
<entry>less than or equal</entry>
<entry>&lt;=</entry>
</row>
<row>
<entry>!</entry>
<entry>not</entry>
<entry>not $a</entry>
<entry>negation (unary)</entry>
<entry>!</entry>
</row>
<row>
<entry>%</entry>
<entry>mod</entry>
<entry>$a mod $b</entry>
<entry>modulous</entry>
<entry>%</entry>
</row>
<row>
<entry>is [not] div by</entry>
<entry></entry>
<entry>$a is not div by 4</entry>
<entry>divisible by</entry>
<entry>$a % $b == 0</entry>
</row>
<row>
<entry>is [not] even</entry>
<entry></entry>
<entry>$a is not even</entry>
<entry>[not] an even number (unary)</entry>
<entry>$a % 2 == 0</entry>
</row>
<row>
<entry>is [not] even by</entry>
<entry></entry>
<entry>$a is not even by $b</entry>
<entry>grouping level [not] even</entry>
<entry>($a / $b) % 2 == 0</entry>
</row>
<row>
<entry>is [not] odd</entry>
<entry></entry>
<entry>$a is not odd</entry>
<entry>[not] an odd number (unary)</entry>
<entry>$a % 2 != 0</entry>
</row>
<row>
<entry>is [not] odd by</entry>
<entry></entry>
<entry>$a is not odd by $b</entry>
<entry>[not] an odd grouping</entry>
<entry>($a / $b) % 2 != 0</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<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 &lt; 0 or $amount &gt; 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>
</sect1>
<sect1 id="language.function.ldelim">
<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>
</sect1>
<sect1 id="language.function.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>
</sect1>
<sect1 id="language.function.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="variable.php.handling">$php_handling</link> setting. This
is for advanced users only, not normally needed.
</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>
</sect1>
<sect1 id="language.function.section">
<title>section,sectionelse</title>
<informaltable frame="all">
<tgroup cols="5">
<colspec colname="param" align="center" />
<colspec colname="type" align="center" />
<colspec colname="required" align="center" />
<colspec colname="default" align="center" />
<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.</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.</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.</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>
<sect2 id="section.property.index">
<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>
<note>
<title>Technical Note</title>
<para>
If the step and start section properties are not
modified, then this works the same as the iteration section
property, except it starts on 0 instead of 1.
</para>
</note>
<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>
</sect2>
<sect2 id="section.property.index.prev">
<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>
</sect2>
<sect2 id="section.property.index.next">
<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>
</sect2>
<sect2 id="section.property.iteration">
<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. Iteration also starts with 1
instead of 0 like index. rownum is an alias to iteration, they work
identical.
</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>
</sect2>
<sect2 id="section.property.first">
<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>
</sect2>
<sect2 id="section.property.last">
<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>
</sect2>
<sect2 id="section.property.rownum">
<title>rownum</title>
<para>
rownum is used to display the current loop iteration,
starting with one. It is an alias to iteration, they work
identically.
</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>
</sect2>
<sect2 id="section.property.loop">
<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>
</sect2>
<sect2 id="section.property.show">
<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>
</sect2>
<sect2 id="section.property.total">
<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>
<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>
</sect2>
</sect1>
<sect1 id="language.function.strip">
<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
unmanageable 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>
<note>
<title>Technical Note</title>
<para>
{strip}{/strip} does not affect the contents of template variables.
See the <link linkend="language.modifier.strip">strip modifier
function</link>.
</para>
</note>
<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>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"../../../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->