pad

PAD Tag Properties Reference

This document provides a complete reference for all PAD tag properties.

Overview

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.


Syntax

Basic Property Access

{first@users}
{count@items}
{current@rows}

As a Tag Pair

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.

Inside {if} and {case}

An {if} or a {case} is no loop of its own: a property written inside one - {&current}, {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>{&current}</b>{/if}      the row number of items, not of the if
{/items}

In Conditionals

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}.

Ternary Conditionals

{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.


Iteration State Properties

Properties that indicate position within a loop iteration.

first

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}

last

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}

notFirst

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


notLast

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


border

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}

middle

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}

even

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}

odd

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}

Counter Properties

Properties that provide numeric information about the iteration.

current

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

count

Returns the total number of items.

{count@tagname}

Returns: max(count($padData[$padIdx]), $padOccur[$padIdx])

Example:

{users}
  User {current@users} of {count@users}
{/users}

remaining

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}

done

Returns the number of completed iterations (current - 1).

{done@tagname}

Returns: $padOccur[$padIdx] - 1

Example:

{users}
  Processed: {done@users}, Current: {$name}
{/users}

Data Access Properties

Properties that provide access to the current data context.

data

Returns the complete data array for the current level.

{data@tagname}

Returns: $padData[$padIdx]

Example:

{users}
  {data@users toData="allUsers"}
{/users}

key

Returns the current array key.

{key@tagname}

Returns: $padKey[$padIdx]

Example:

{config}
  {key@config}: {$value}
{/config}

Output:

host: localhost
port: 3306
user: admin

keys

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}

fields

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>

firstFieldName

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}

firstFieldValue

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}

Tag Metadata Properties

Properties that provide information about the current tag.

name

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


depth

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}

Parameter & Option Properties

Properties for accessing tag parameters and options.

parameter

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}

parameters

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}

option

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}

options

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}

Variable Properties

Properties for accessing level-scoped variables.

variable

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}

variables

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 Summary Table

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

Common Usage Patterns

Zebra Striping

{rows}
  <tr class="{even@rows ? row-even : row-odd}">{$data}</tr>
{/rows}

First/Last Handling

{items}
  {first@items}<ul>{/first@items}
  <li>{$name}</li>
  {last@items}</ul>{/last@items}
{/items}

Item Separators

{tags}
  {$name}{notLast@tags}, {/notLast@tags}
{/tags}

Counter Display

{users}
  <div>
    {current@users} of {count@users}: {$name}
    {notLast@users}({remaining@users} remaining){/notLast@users}
  </div>
{/users}

Dynamic Field Display

{record "* from users where id=5"}
  <dl>
  {fields@record}
    <dt>{$name}</dt>
    <dd>{$value}</dd>
  {/fields@record}
  </dl>
{/record}

Accessing Parameters

{customTag 'fast', mode='advanced'}
  Speed: {parameter.1@customTag}
  Mode: {option.mode@customTag}
{/customTag}