This document provides a complete reference for all PAD tag properties.
Tag properties provide contextual information during template execution. They are accessed using the property@tag syntax:
{property@tagname}
Where tagname is the name of the iteration/loop context and property is the information you want to access.
{first@users}
{count@items}
{current@rows}
A boolean property written as a tag pair renders its content only when the property is true:
{first@users}<ul>{/first@users}
{last@users}</ul>{/last@users}
A property that is a data set - fields, keys, parameters, options, variables - is
iterated as a pair, which is closed by its full name: {fields@user}...{/fields@user}.
Without a target, {fields}...{/fields} reads the enclosing level.
An {if} or a {case} is no loop of its own: a property written inside one - {¤t},
{current@}, {property:first}, {first@}...{/first@} - belongs to the loop around it, as
an option {#name} inside one belongs to the tag around it:
{items}
{if $price gt 100}<b>{¤t}</b>{/if} the row number of items, not of the if
{/items}
A property reads as a value inside an expression, so it stands in a condition - alone for the boolean ones, with an operator for the counting ones, and combined freely:
{if first@users}<ul>{/if}
{if notFirst@items}, {/if}
{if current@rows eq 2}the second row{/if}
{if first@items or last@items}an end{/if}
{if option.sort@items eq 'name'}sorted by name{/if}
The property name is what makes this read as one reference: only the names on this page do
(the files in pad/properties/), and the target names an iterating tag. Without a target -
{if current@ eq 2}, {echo current@ * 10} - it is the loop the expression stands in, past
an {if}, a {case} and any other level that renders once for the row - an {ifchanged}, a
{guest}, a {spaceless}, a snippet. Elsewhere in an expression @ is still the current-value
placeholder, and so is an @ after a space: count @.
The sigil decides what a colliding name means. When a row carries a field named like a
property - a first column, say - the bare spelling is still the property and the
$-spelling is the field:
{if first@orders} the iteration state - is this the first row
{$first@orders} the row's 'first' field
{if $first@orders eq 'Dave'} comparing that field
The tag form resolves fields first, as it always has - the pair
{first@orders}...{/first@orders} over such rows prints the field and renders its content on
every row, and a single {name@users} over rows with a name field prints that field. From inside the level
the property: prefix reaches the property whatever the row carries:
{if property:first}.
{even@rows ? 'class="even"' : 'class="odd"'}
A side that is more than one bare word is quoted: unquoted, class="even" is read as an
expression and comes out empty.
Properties that indicate position within a loop iteration.
Returns TRUE if this is the first iteration.
{first@tagname}
Logic: $padOccur[$padIdx] == 1
Example:
{users}
{first@users}<table><tr><th>Name</th></tr>{/first@users}
<tr><td>{$name}</td></tr>
{/users}
Returns TRUE if this is the last iteration.
{last@tagname}
Logic: $padKey[$padIdx] === array_key_last($padData[$padIdx])
Example:
{users}
<tr><td>{$name}</td></tr>
{last@users}</table>{/last@users}
{/users}
Returns TRUE if this is NOT the first iteration.
{notFirst@tagname}
Logic: ! first@tagname
Example:
{items}
{notFirst@items}, {/notFirst@items}{$name}
{/items}
Output: item1, item2, item3
Returns TRUE if this is NOT the last iteration.
{notLast@tagname}
Logic: ! last@tagname
Example:
{items}
{$name}{notLast@items}|{/notLast@items}
{/items}
Output: item1|item2|item3
Returns TRUE if this is either the first OR last iteration.
{border@tagname}
Logic: first@tagname OR last@tagname
Example:
{items}
<div {border@items}class="highlight"{/border@items}>{$name}</div>
{/items}
Returns TRUE if this is neither first nor last (middle items only).
{middle@tagname}
Logic: NOT border@tagname (neither first nor last)
Example:
{items}
{middle@items}<div class="middle">{$name}</div>{/middle@items}
{/items}
Returns TRUE if the current occurrence number is even.
{even@tagname}
Logic: $padOccur[$padIdx] % 2 == 0
Example:
{rows}
<tr class="{even@rows ? even : odd}">{$data}</tr>
{/rows}
Returns TRUE if the current occurrence number is odd.
{odd@tagname}
Logic: NOT even@tagname
Example:
{rows}
<tr class="{odd@rows ? odd : even}">{$data}</tr>
{/rows}
Properties that provide numeric information about the iteration.
Returns the current occurrence number (1-based index).
{current@tagname}
Returns: $padOccur[$padIdx]
Example:
{users}
{current@users}. {$name}
{/users}
Output:
1. Alice
2. Bob
3. Charlie
Returns the total number of items.
{count@tagname}
Returns: max(count($padData[$padIdx]), $padOccur[$padIdx])
Example:
{users}
User {current@users} of {count@users}
{/users}
Returns the number of iterations remaining.
{remaining@tagname}
Returns: count($padData[$padIdx]) - $padOccur[$padIdx] (minimum 0)
Example:
{users}
{$name} ({remaining@users} more to go)
{/users}
Returns the number of completed iterations (current - 1).
{done@tagname}
Returns: $padOccur[$padIdx] - 1
Example:
{users}
Processed: {done@users}, Current: {$name}
{/users}
Properties that provide access to the current data context.
Returns the complete data array for the current level.
{data@tagname}
Returns: $padData[$padIdx]
Example:
{users}
{data@users toData="allUsers"}
{/users}
Returns the current array key.
{key@tagname}
Returns: $padKey[$padIdx]
Example:
{config}
{key@config}: {$value}
{/config}
Output:
host: localhost
port: 3306
user: admin
Returns an array of all keys with their values as iterable data.
{keys@tagname}
Returns: Array where each item has name (the key) and value
Example:
{myArray}
{first@myArray}
{keys@myArray}Key: {$name} {/keys@myArray}
{/first@myArray}
{/myArray}
Returns an array of field name/value pairs from the current record.
{fields@tagname}
Returns: Array where each item has name and value
Example:
{user}
<table>
{fields@user}
<tr><td>{$name}</td><td>{$value}</td></tr>
{/fields@user}
</table>
{/user}
Output:
<table>
<tr><td>id</td><td>1</td></tr>
<tr><td>name</td><td>Alice</td></tr>
<tr><td>email</td><td>alice@example.com</td></tr>
</table>
Returns the name of the first field in the current record.
{firstFieldName@tagname}
Returns: First key from $padCurrent[$padIdx]
Example:
{user}
Primary field: {firstFieldName@user}
{/user}
Returns the value of the first field in the current record.
{firstFieldValue@tagname}
Returns: First value from $padCurrent[$padIdx]
Example:
{user}
Primary value: {firstFieldValue@user}
{/user}
Properties that provide information about the current tag.
Returns the name of the current tag/level.
{name@tagname}
Returns: $padName[$padIdx]
Example:
{users}
Processing tag: {echo name@users}
{/users}
Output: Processing tag: users - written as a tag, {name@users}, a name field of the rows
would win
How deep the level stands in a recursion: for a {tree}, 1 for its own rows and one more
per {recurse} - for indenting a tree. Any other level counts the levels of its own name
from the top down to itself, so a tag that calls itself has a depth too, and a level that
does not is at depth 1.
{depth@tree}
Example:
{tree 'menu', children='items'}
<p style="margin-left: {echo depth@tree | * 20}px">{$title}</p>
{branch}{recurse}{/branch}
{/tree}
Properties for accessing tag parameters and options.
Returns one positional parameter - the values after the tag name - numbered from 1.
{parameter.1@tagname}
Returns: $padOpt[$padIdx][$parm] or NULL
Example:
{myTag 'first', 'second'}
First: {parameter.1@myTag}
Second: {parameter.2@myTag}
{/myTag}
Returns all positional parameters as an iterable array.
{parameters@tagname}
Returns: All parameters from $padOpt[$padIdx] (excluding index 0, the raw tag text)
Example:
{myTag 'first', 'second'}
{parameters@myTag}
Parameter: {$value}
{/parameters@myTag}
{/myTag}
Returns one named option.
{option.sort@tagname}
Returns: $padPrm[$padIdx][$parm] or NULL
Example:
{myTag sort='name', limit=10}
Sort by: {option.sort@myTag}
Limit: {option.limit@myTag}
{/myTag}
Returns all named options as an iterable array.
{options@tagname}
Returns: All options from $padPrm[$padIdx]
Example:
{myTag foo=1, bar=2}
{options@myTag}
{$name} = {$value}
{/options@myTag}
{/myTag}
Properties for accessing level-scoped variables.
Returns one level variable - a $name = value written on the tag.
{variable.varName@tagname}
Returns: $padSetLvl[$padIdx][$parm] or NULL
Example:
{users $myVar = 'test'}
Variable: {variable.myVar@users}
{/users}
Returns all level variables as an iterable array.
{variables@tagname}
Returns: All variables from $padSetLvl[$padIdx]
Example:
{users $a = 1, $b = 2}
{variables@users}
{$name}: {$value}
{/variables@users}
{/users}
| Property | Type | Description |
|---|---|---|
first@tag |
Boolean | Is first iteration |
last@tag |
Boolean | Is last iteration |
notFirst@tag |
Boolean | Is NOT first iteration |
notLast@tag |
Boolean | Is NOT last iteration |
border@tag |
Boolean | Is first OR last |
middle@tag |
Boolean | Is neither first nor last |
even@tag |
Boolean | Is even occurrence |
odd@tag |
Boolean | Is odd occurrence |
current@tag |
Number | Current occurrence (1-based) |
count@tag |
Number | Total item count |
remaining@tag |
Number | Items remaining |
done@tag |
Number | Items completed |
data@tag |
Array | Full data array |
key@tag |
Mixed | Current array key |
keys@tag |
Array | All keys with values |
fields@tag |
Array | Field name/value pairs |
firstFieldName@tag |
String | First field’s name |
firstFieldValue@tag |
Mixed | First field’s value |
name@tag |
String | Tag name |
depth@tag |
Number | Depth in a recursion - a {tree}’s rows at 1 |
parameter.n@tag |
Mixed | Positional parameter n, numbered from 1 |
parameters@tag |
Array | All parameters |
option.name@tag |
Mixed | The named option’s value |
options@tag |
Array | All options |
variable.x@tag |
Mixed | Level variable |
variables@tag |
Array | All variables |
{rows}
<tr class="{even@rows ? row-even : row-odd}">{$data}</tr>
{/rows}
{items}
{first@items}<ul>{/first@items}
<li>{$name}</li>
{last@items}</ul>{/last@items}
{/items}
{tags}
{$name}{notLast@tags}, {/notLast@tags}
{/tags}
{users}
<div>
{current@users} of {count@users}: {$name}
{notLast@users}({remaining@users} remaining){/notLast@users}
</div>
{/users}
{record "* from users where id=5"}
<dl>
{fields@record}
<dt>{$name}</dt>
<dd>{$value}</dd>
{/fields@record}
</dl>
{/record}
{customTag 'fast', mode='advanced'}
Speed: {parameter.1@customTag}
Mode: {option.mode@customTag}
{/customTag}