This document provides a complete reference for all PAD tag options.
Options are specified on PAD tags, separated by commas:
{tagName option="value", anotherOption="value"}
A space does not separate two options: {staff sort="name" first=1} gives sort the value
"name" first=1, and first is never read. Only a bare option name - one without a value -
directly after a single parameter may leave its comma out - {data 'x' ignore}; with a value,
{pad 'x' toContent='c'} loses the option silently. Multiple options can be combined:
{staff print, toContent="list", quote="'", glue=", ", open="[", close="]"}
Options are processed at different phases during tag execution:
| Phase | When | Options |
|---|---|---|
| Data | Before the tag runs | data |
| Flags | When the tag has answered | notOk / error, null, else, demand, then dump and content |
| Handling | Then, in the order written | sort, where, group, first, page, rows, dedup, … - see HANDLING.md |
| Start | Before the occurrences render | application _options/, then ignore, print |
| Callback | Around the occurrences | callback, before |
| End | After the occurrences rendered | application _options/end/, then toBool, toContent, toData, tidy |
| Special | Handled at specific points | bool (read by {if}), optional, noError (an unknown tag), cache |
Options that specify where to get data from.
Retrieves data from a named source.
{tagName data="sourceName"}
Resolution order:
$padDataStore[$sourceName] - Data store$pqStore[$sourceName] - Sequence storepadData($sourceName) - Load from data providerAn address - https://..., SELF://... - a visitor chose is refused: a request value (GET,
POST, a JSON body, a cookie, a clean-URL segment) that is the whole address or its start, or
names its host (with or without the port), and a template that does not write that scheme and
host; so is a range of more than 10000 values whose end or whole text a request value gives.
A request value merely holding the host’s text chooses nothing, and the page’s own values -
data=$url with $url from its PHP or configuration - are fetched. The {curl} tag’s address
is judged the same way.
The guard has a limit: a template that builds the host from pieces of a request value is not
caught - data='http://{$h}/x' with h = x@127.0.0.1:9, or a host with a path tail behind
it. Never splice a visitor’s value into the scheme or host of an address. Nor is a range whose
end a pipe made from a request value - data='0..{$n | - 1}': never let a visitor’s value set
the end of a range.
Example:
{users data="cachedUsers"}
{pad data="queryResults"}...{/pad}
Retrieves content from the content store.
{tagName content="contentName"}
Returns: Content from $padContentStore[$contentName]
Example:
{pad content="savedHeader"}
How the content content= brings joins the tag’s own content.
{tagName content="contentName", merge="bottom"}
Values:
top - the merged content above the tag’s own (the default)bottom - below itreplace - instead of itAn @content@ in either one decides the place instead. Any other value is an error under the
strict check.
Example:
{content 'h'}H{/content}
{pad content='h', merge='top'}X{/pad} → HX
{pad content='h', merge='bottom'}X{/pad} → XH
{pad content='h', merge='replace'}X{/pad} → H
Options that store results for later use.
Stores the processed data array to a named variable.
{tagName toData="variableName"}
Stores to: $padDataStore[$variableName]
Behavior:
Example:
{users where='$active eq 1', toData="activeUsers"}
{pad data="activeUsers"}...{/pad}
Stores the generated content/output to a named variable.
{tagName toContent="variableName"}
Stores to: $padContentStore[$variableName]
Behavior:
$padResult[$pad] to the content storeExample:
{pad toContent="pageHeader"}<h1>...</h1>{/pad}
{pad content="pageHeader"}
Stores a boolean result based on the output state.
{tagName toBool="flagName"}
Stores to: $padBoolStore[$flagName]
Boolean logic:
TRUE if result has non-empty trimmed contentFALSE if null, else condition, or empty resultExample:
{users where='$admin eq 1', toBool="hasAdmins"}{$name}{/users}
{if bool="hasAdmins"}...{/if}
Makes the stored boolean flag the condition of an {if}.
{if bool="flagName"}
Behavior:
$padBoolStore, returns its valueFALSE, as an unset flag reads everywhere{if} only; on any other tag it does nothingExample:
{checkPermission toBool="canEdit"}
{if bool="canEdit"}Edit{/if}
Marks a tag as optional - suppresses “not found” errors.
{$maybeUndefined | optional}
{tagName optional}
Behavior:
padLevel('') - returns empty string on failureExample:
{$user.middleName | optional}
Marks a tag as required: it must produce something.
{tagName demand}
Behavior:
'' or an empty array, or whose rows the handling options
all took away - after notOk, null and else had their turn - is a PAD error: “Tag ‘x’
carries demand and produced nothing”Options that show other content based on what the tag itself answered. The value of each is
the name of that content - a {content 'name'} block, or else an _include/ snippet or a
page of that name a request could ask for, no segment starting with _ or .
(get/content.php) - never a tag, a PHP function or a path (a name with .., a backslash or
a leading / is refused), and never literal text: under the strict check a name written in
the template that names none of them - else="Nothing here" - is an error; a value naming
nothing shows nothing.
Shows the named content when the tag answers NULL.
{tagName null="contentName"}
Triggers when:
NULLNaNINF, a float past the range, is a value: it prints, as -INF does.
Behavior:
Example:
{content 'noAvatar'}<img src="anonymous.png" alt="">{/content}
{avatar null="noAvatar"}...{/avatar}
Shows the named content when the tag answers an empty or false result.
{tagName else="contentName"}
Triggers when:
[]FALSE''Rows that the handling options take away count too: when the tag found rows and where= or
first= left none, else= stands in as for an empty answer, and without it the level shows its
@else@ branch (HANDLING.md).
Example:
{content 'noPremium'}<p>No premium users yet.</p>{/content}
{premiumUsers else="noPremium"}...{/premiumUsers}
Shows the named content when the tag produced nothing - NULL, FALSE, '' or an empty array,
or the handling options left no row - taking precedence over null and else, or when the
tag’s handler or PHP threw an exception (a php: call, an application’s _tags/ file). A PAD
error is still reported.
{tagName notOk="contentName"}
Alias for notOk.
{tagName error="contentName"}
The formatting options - quote, open, close, glue - work on what the print option prints,
each row’s first field, and run only through it: written without print they do nothing.
With $staff rows named joe, jim and john:
Wraps each printed value in the specified quote characters.
{tagName print, quote="'"}
{tagName print, quote='"'}
Result: 'content' or "content"
Example:
{staff print, quote="'"} → 'joe''jim''john'
Prepends content at the start of the first occurrence only.
{tagName print, open="prefix"}
Implementation: Wraps in {first}prefix{/first}
Example:
{staff print, open="["} → [joejimjohn
Appends content at the end of the last occurrence only.
{tagName print, close="suffix"}
Implementation: Wraps in {last}suffix{/last}
Example:
{staff print, close="]"} → joejimjohn]
Adds a separator between items (not after the last one).
{tagName print, glue=", "}
Implementation: Wraps in {notLast}separator{/notLast}
Example:
{staff print, glue=", "} → joe, jim, john
Options can be combined for complex formatting:
{staff print, quote="'", glue=", ", open="[", close="]"}
Result: ['joe', 'jim', 'john']
Wraps content in ignore tags to skip PAD processing.
{tagName ignore}
Implementation: Wraps content as {ignore}content{/ignore}
Use case: Output literal PAD syntax without evaluation.
Cleans up whitespace and formatting in the output.
{tagName tidy}
Implementation: Calls padTidy($padContent, TRUE)
Example:
{template tidy} → Cleaned output with normalized whitespace
The same as optional: a tag whose name resolves to no tag renders nothing instead of an error.
{tagName noError}
Behavior: Read by level/no.php, the fallback for an unknown tag. A tag that exists and
fails still reports its error.
Invokes an application callback for custom processing.
{tagName callback="callbackName"}
Calls: APP/_callbacks/callbackName.php
Example:
{users callback="processUsers"}
Processes callback in “before” mode - runs before content generation.
{tagName before, callback="initData"}
Behavior:
padCallbackBeforeXxx('init')padCallbackBeforeRow()padCallbackBeforeXxx('exit')The handling options are processed after the tag has answered, in the order written - see HANDLING.md.
Enables deduplication of data.
{tagName dedup}
Keeps the rows for which a quoted PAD expression holds, evaluated per row with the row’s fields first. See HANDLING.md.
{staff where='$salary gt 2500'}
Folds the rows into one occurrence per distinct value of a field, each with the value,
count, the aggregates sum, avg, min and max ask for, and its own rows as rows.
See HANDLING.md.
{orders group='customer', sum='total'}
{$customer}: {$count} orders, {$total}
{rows}{$number}: {$total}{/rows}
{/orders}
Keeps one page of the rows - page counted from 1, rows per page (default 10). A
{pager} after the tag writes the links to the other pages. See
HANDLING.md.
{products page=$pg ?? 1, rows=12}...{/products}
{pager 'products'}
Enables sorting.
{tagName sort}
For tracing a page, see {trace} in TAGS.md and $padInfo = 'trace'.
Keeps the tag’s rendering in the fragment cache for so many seconds; on a hit the tag’s
handler does not run and the stored rendering stands in. See {cache} in
TAGS.md.
{expensive_query cache=3600, vary=$country}
...
{/expensive_query}
ttl= may say the seconds instead; vary= adds what else the rendering depends on.
Writes a state dump under DATA/dumps/<app>/<page>/ - nothing appears in the page - once
the tag has answered and again after its handling options.
{tagName dump}
Calls: padDumpToDir()
Use case: Debugging template processing
Enables direct output printing with formatting options.
{tagName print}
Behavior:
{&firstFieldValue}quote, open, glue, closeExample:
{staff print, quote="'", glue=", "} → 'joe', 'jim', 'john'
| Option | Direction | Description |
|——–|———–|————-|
| data | Input | Get data from source |
| content | Input | Get content from store |
| merge | Input | Where content joins the tag’s own: top, bottom, replace |
| toData | Output | Store data to variable |
| toContent | Output | Store content to variable |
| toBool | Output | Store boolean flag |
| Option | Description |
|——–|————-|
| bool | {if bool='name'}: the stored flag is the condition |
| optional | Suppress not-found errors |
| demand | An error when the tag produced nothing |
| null | Named content for NULL |
| else | Named content for empty/false |
| notOk | Named content for any miss, or when the tag’s handler or PHP throws |
| error | Alias for notOk |
| Option | Description |
|——–|————-|
| quote | Wrap in quotes - with print |
| open | Prefix on first item - with print |
| close | Suffix on last item - with print |
| glue | Separator between items - with print |
| tidy | Clean whitespace |
| Option | Description |
|——–|————-|
| ignore | Skip PAD processing |
| noError | An unknown tag renders nothing (as optional) |
| callback | Run application callback |
| before | Callback before content |
| print | Direct output mode |
| dump | A state dump under DATA/dumps/ |
| Option | Description |
|——–|————-|
| where | Keep the rows an expression holds for |
| group | One occurrence per value of a field, with count, rows and aggregates |
| sum, avg, min, max | The aggregates of group |
| dedup | Deduplicate data |
| page | Enable pagination |
| sort | Enable sorting |
Applications can define custom options by placing PHP files in:
APP/_options/optionName.php start phase - works on the template
APP/_options/end/optionName.php end phase - works on the rendered result
_options/optionName.php is processed during the app phase, before the tag renders:
$padContent is the template between the tags. _options/end/optionName.php is processed
as the level closes, after every occurrence has rendered: $padContent is the result, with
the fields filled in - the place for options such as {report minify} or {price highlight}.
An option may have both files; each runs in its own phase.
Both have access to:
$padContent - the template (start) or the rendered result (end); change it to change it$padGetName - Option parameter value (TRUE for the bare form)The end-phase handlers run before the built-in end options (toBool, toContent, toData,
tidy), so those store or tidy what the application option made, and before the closing
tag’s pipe. Both are looked up from the page’s directory up to the application root, and
count as readers for the strict unread-option check.
<?php // _options/end/words.php
$padContent .= '(' . str_word_count ( strip_tags ( $padContent ) ) . ' words)';
?>
{staff words}{$name} {/staff} → joe jim john jack jerry (5 words)
datanotOk / error, null, else, demanddump, then content mergedsort, where, group, first, page, dedup, … in the order written (dump again after them)_options/)ignore, printcallback (with before)_options/end/)toBool, toContent, toData, tidy