pad

PAD Data Handling Functions Reference

This document provides a complete reference for all PAD data handling functions.

Overview

Data handling functions transform data arrays before they are rendered in templates. They are applied as options on PAD tags:

{tagName sort="field", first="5", reverse}

Multiple handlers can be combined and are applied in sequence.


Sorting Functions

sort

Sorts data by one or more fields with configurable direction and sort type.

{items sort}
{items sort="fieldName"}
{items sort="fieldName ASC"}
{items sort="fieldName DESC"}
{items sort="field1 ASC; field2 DESC"}

Parameters:

Sort Type Flags:

Examples:

{users sort="name"}
{users sort="age DESC"}
{users sort="department ASC; name ASC"}
{products sort="price NUMERIC DESC"}
{files sort="name NATURAL ASC"}

Implementation: Uses array_multisort() for efficient multi-column sorting.


reverse

Reverses the order of data array.

{items reverse}

Parameters: None (boolean flag)

Example:

{users sort="date", reverse}
{-- Sort by date then reverse for newest first --}

Implementation: Uses array_reverse().


shuffle

Randomly shuffles all elements.

{items shuffle}

Parameters: None (boolean flag)

Example:

{quotes shuffle, first="1"}
{-- Get one random quote --}

Implementation: Uses PHP shuffle().


random

Selects random elements with advanced options.

{items random}
{items random="5"}
{items random="3", orderly, duplicates}

Parameters:

atLeastOnce, the third companion in handling/types/, is read by the sequence randomize action only; on a data tag it has no effect.

Examples:

{products random="4"}
{-- Select 4 random products --}

{users random="3", orderly}
{-- Select 3 random users, maintain their original order --}

{colors random="10", duplicates}
{-- Select 10 colors, allowing repeats --}

Implementation: Uses pqRandom() function.


Selection Functions

where

Keeps the rows for which an expression holds - on any data, not only on Select tables.

{staff where='$salary gt 2500'}
{orders where='$status eq "open" and $total gt $minimum'}

Parameters:

Examples:

{staff where='$salary gt 1500', first=2}
{-- The first two of the rows that pass --}

{staff where='$salary gt 2500', negative}
{-- Every row that does not pass --}

A Select table ({select:users}, or a declared table by its name) has a where of its own - SQL, applied by the query - and is left alone by this handler.


first

Gets the first N elements.

{items first}
{items first="5"}

Parameters:

Examples:

{news first="3"}
{-- Show first 3 news items --}

{users sort="score DESC", first="10"}
{-- Top 10 users by score --}

Implementation: Uses array_slice($data, 0, $count).


last

Gets the last N elements.

{items last}
{items last="5"}

Parameters:

Examples:

{logs last="20"}
{-- Show last 20 log entries --}

{orders sort="date", last="5"}
{-- Last 5 orders --}

Implementation: Uses array_slice($data, -$count).


row

Gets a specific row by number.

{items row="3"}

Parameters:

Example:

{users row="1"}
{-- Get first user --}

Implementation: Uses padHandGo() with start=end.


Pagination Functions

page

Paginates data into pages.

{items page="1", rows="10"}
{items page="2", rows="25"}

Parameters:

Calculation:

Examples:

{users page="1", rows="20"}
{-- First 20 users --}

{products page="3", rows="12"}
{-- Products 25-36 (page 3 with 12 per page) --}

Page links: a tag written with page books its page, rows and total - the rows the options written before page left - under its name, and {pager 'products'} after it writes the links to the other pages (see TAGS.md). Write the page as a request variable, page=$pg ?? 1, and the links set pg.


rows

Gets a specific number of rows (shorthand for pagination).

{items rows="10"}

Parameters:

Behavior:

Example:

{users rows="5"}
{-- First 5 users --}

{logs end="-1", rows="10"}
{-- The 10 log entries before the last one --}

start

Sets the starting position for data selection.

{items start="5"}
{items start="-3"}

Parameters:

Examples:

{users start="11", rows="10"}
{-- Users 11-20 --}

{items start="-5"}
{-- Last 5 items --}

end

Sets the ending position for data selection.

{items end="10"}
{items end="-1"}

Parameters:

Examples:

{users start="1", end="10"}
{-- Users 1-10 --}

{items end="-1"}
{-- All items except the last one --}

Slicing Functions

slice

Extracts a portion of the array (keeps selected elements).

{items slice="5"}
{items slice="3|7"}

Parameters:

Examples:

{items slice="10"}
{-- Keep first 10 items --}

{items slice="-5"}
{-- Keep last 5 items --}

{items slice="5|3"}
{-- Keep 3 items starting at offset 5, the sixth --}

Implementation: Uses array_slice().


splice

Removes a portion of the array (removes selected elements).

{items splice="5"}
{items splice="3|2"}

Parameters:

Examples:

{items splice="2"}
{-- Remove first 2 items --}

{items splice="-3"}
{-- Remove last 3 items --}

{items splice="5|2"}
{-- Remove 2 items starting at offset 5, the sixth --}

Implementation: Uses array_splice().


Data Cleaning Functions

dedup

Removes duplicate entries from single-field arrays.

{items dedup}

Parameters: None (boolean flag)

Behavior:

Example:

{tags dedup}
{-- Remove duplicate tags --}

trim

Trims elements from the beginning and/or end of the array.

{items trim}
{items trim="2"}
{items trim="3", left}
{items trim="3", right}
{items trim="2", both}

Parameters:

Examples:

{items trim="1"}
{-- Remove first and last item --}

{items trim="2", left}
{-- Remove first 2 items --}

{items trim="3", right}
{-- Remove last 3 items --}

Implementation: Uses pqTruncate() function.


Grouping

group

Folds the rows into one occurrence per distinct value of a field, with a count, aggregated fields and the group’s own rows as nested data.

{orders group='customer', sum='total'}
  <h2>{$customer}: {$count} orders, {$total}</h2>
  {rows}
    <p>{$number}: {$total}</p>
  {/rows}
{/orders}

Each group occurrence holds:

Parameters:

Aggregates - options read by group, each naming one or more fields:

Option Gives
sum The numeric values added - other values are left out; rounded to the most decimals among them, so 10.10 + 20.20 is 30.3
avg That sum divided by the number of numeric values, '' when there were none
min The lowest value - numbers compared as numbers, other text as text; missing and empty values left out
max The highest value, the same way

The aggregate is stored under the field’s own name - {$total} - and under the aggregate joined to it - {$sum_total}, {$avg_total}, {$min_total}, {$max_total} - so one field can be summed and averaged at once; the own name holds the aggregate written first. A field named count or rows keeps only the joined name - {$sum_rows} - as those two names are the group’s own; grouping on such a field is an error under the strict check.

Examples:

{orders sort='customer', group='customer'}
{-- Groups in customer order, the rows inside them too --}

{orders group='customer', sum='total', sort='total DESC', first=3}
{-- The three customers with the highest total --}

{orders group='customer', where='$count gt 1'}
{-- The customers with more than one order --}

{orders group='year'}{$year}{rows group='month', sum='total'}{$month}: {$total}{/rows}{/orders}
{-- Grouped again inside a group --}

Groups come in the order their first row appears; negative leaves a group alone. A Select table ({select:users}, or a declared table by its name) has a group of its own - SQL’s group by, applied by the query - and is left alone by this handler.


Emptied by Handling

When the tag found rows and the handling options left none - a where nothing passes, a first=0 - the level is treated as a tag that came back empty: a notOk=, error= or else= option stands in with its content, otherwise the level shows its @else@ branch, and demand is an error unless an option stood in:

{staff where='$salary gt 9999'}{$name}@else@Nobody earns that much{/staff}
{staff where='$salary gt 9999', else='nobody'}{$name}{/staff}

Negative Mode

The negative option inverts the selection - keeping items that would normally be removed. An option that selects nothing - sort, reverse, shuffle, group - is left alone by it, so {staff where='$salary gt 2500', sort='name', negative} is every row that does not pass, sorted.

{items first="3", negative}
{-- Gets all items EXCEPT the first 3 --}

How it works:

  1. Keys are prefixed with ‘x’ before operation
  2. Handler runs normally
  3. Items that remain are removed from original
  4. Original items NOT selected are kept

The handlers that select nothing are left alone: sort, reverse and shuffle only put the rows in another order, group folds them, and rows beside page, start or end (and end beside start) is read by that partner - {staff where='$salary gt 2500', sort='name', negative} is every row that does not pass, sorted by name.

Examples:

{users first="5", negative}
{-- All users except first 5 --}

{items random="3", negative}
{-- All items except 3 random ones --}

Function Summary Table

Function Purpose Parameters
sort Sort by field(s) field [ASC|DESC] [; …]
reverse Reverse order (none)
shuffle Random order (none)
random Random selection count, orderly, duplicates
where Rows an expression holds for quoted expression
group One occurrence per value, with count and rows field(s); sum, avg, min, max
first First N items count
last Last N items count
row Specific row row number
page Pagination page, rows
rows Row count count
start Start position position
end End position position
slice Keep portion start|count
splice Remove portion start|count
dedup Remove duplicates (none)
trim Trim ends count, left, right, both

Combining Functions

Functions can be combined and are applied in sequence:

{users sort="name", first="10"}
{-- Sort by name, then get first 10 --}

{products sort="price DESC", page="1", rows="20"}
{-- Sort by price descending, paginate --}

{items shuffle, first="5"}
{-- Shuffle then get first 5 (5 random items) --}

{tags sort, dedup, first="100"}
{-- Sort, drop repeated tags, limit to 100 --}

Processing Order

Handlers are processed in the order they appear in the tag parameters. Consider the order carefully:

{-- Different results: --}
{items first="10", shuffle}    {-- First 10, then shuffled --}
{items shuffle, first="10"}    {-- Shuffled, then first 10 --}

Recommended order:

  1. dedup - Remove duplicates first
  2. sort - Sort the clean data
  3. shuffle / random - Randomize if needed
  4. first / last / page - Limit results last