AA Expression Reference

Template expressions for ActionApps — search or browse by category.

279 expressions shown
No expressions match your search.
{#comment}Misc / Specialized
Template comment syntax: anything inside {# ... } is stripped from the output and always returns an empty string. Use it to annotate templates without affecting the rendered HTML. Comments may contain AA aliases (_#FIELD) or other expressions; they are all silently discarded. Example: {# this is a comment _#HEADLINE and more } produces nothing.
{(expression)}Misc / Specialized
Deferred evaluation — passes a nested AA expression as an opaque argument to an outer expression, preventing premature expansion. Essential when you need to pass a complex expression (containing colons or curly braces) as a parameter to another expression. Syntax: {outer_expression:{(inner expression with {nested:} calls)}} Without parentheses, AA expands all nested {} expressions before passing them as parameters, which can cause issues when the inner expression contains colons that would be misinterpreted as parameter separators. Wrapping in {(...)} defers the inner expression so it is passed literally as an argument and expanded inside the outer expression's context: {item:6625:{(some text {headline........} with {_#LINK_URL__})}} This is especially useful with {item:}, {view:}, {foreach:}, and other expressions that take template strings as parameters — allowing you to pass full AA template expressions as their content parameter. Example: display an item's title as a link: {item:{xid}:{(<a href="{_#LINK_URL__}">{headline........}</a>)}} The outer closing ) followed by } closes the deferred block. Status: Active — not deprecated (a fundamental part of AA expression syntax).
Loops through all values of a multivalue field and outputs each value using a template or the field's alias. A concise shorthand for iterating multivalue fields without needing a full {foreach:} loop. Syntax: {@field_id[:delimiter[:expression]]} The field_id is a dot-padded 16-character field identifier (e.g. category.......1, relation.......2). Without extra parameters, outputs all values separated by comma (the default delimiter): {@category.......1} With a custom delimiter: {@relation.......2:-} — values separated by dash {@category.......1:, } — values separated by comma-space With an expression template (replaces d3497e7abb9772d33c05daa0fe3fb7b9 with each value): {@category.......1:,:<em>d3497e7abb9772d33c05daa0fe3fb7b9</em>} — wraps each value in italics When used on a field with defined alias functions (alias1–alias3 in the Slice Admin), the alias transformation is applied to each value automatically. Note: {foreach:} is more powerful for complex templates; {@} is a clean shorthand for simple display of multivalue field contents. It is part of AA's alias/field processing and works within item templates. Status: Active — not deprecated.
{aabox}System & Utility
A probe that returns the literal text OK when the AA runtime session is active, and an empty string when it is not. The AA bootstrap (pageOpen in locsess.php) assigns a session object on every normal page render, so during template expansion on a live page this expression effectively always returns OK. It takes no parameters; use it as a quick liveness or context check.
Generates inline reference documentation for another stringexpand command, read from that command source PHPDoc comments. Pass the target command keyword as the single parameter. aadocumentation builds the class name (AA_Stringexpand_ followed by the keyword), reflects its class docblock and its expand-method docblock, and returns an XML fragment. The root element is cmd with a name attribute equal to the keyword you passed. Free text before the first at-tag becomes a text element; every at-tag (param, return, usage, and so on) becomes an element named after the tag carrying the rest of that line. If the keyword matches no class, the result is just the empty shell, cmd name=keyword closed immediately. This command is experimental and marked unfinished in the source: the parser is literal, so docblock punctuation can leak into the text, and the output only reflects whatever comments the target class happens to carry.
{aalang}System & Utility
Returns the two-letter code of the language the current page is being rendered in (for example cz, en, es) - lowercased, from the AA language state. It takes no parameters. When no page language is set it falls back to the first two letters of the install default language. Unlike xlang, aalang always returns a valid code, not only inside the Site module, which makes it the reliable way to branch templates, labels and URLs by language. The value is runtime state and changes with the rendering context, so the same call yields a different code on a page served in another language.
MK{item:d1a7ad7db8dbc8da6cc9c9cf78f39acc:expressions}EMK
Renders a field value as a clickable control that visitors with edit rights can change in place - clicking it opens a small inline editor that saves over AJAX, with no page reload. Give it the item id and the field id; the field id is the only required parameter and without it ajax outputs nothing. Leave the item id empty to edit the field on the current item (the alias _#ITEM_ID_ in a view or template). The read-only display, before anyone clicks, is the field value formatted for humans; pass a third parameter to supply your own display template, and put the alias _#AA_AJAX_ inside it to attach the click-to-edit handler to one element instead of the whole block. The fourth parameter is JavaScript run after a successful save, for example AA_Refresh(this) to reload the surrounding block. The last two parameters (widget type and widget properties) choose a specific editing widget but are still being wired up. To turn editing off and print only the value - the read-only fallback, also used when a visitor cannot edit - set the constant AA_FLAG_NOEDIT to 1. An empty field value shows as two dashes.
{alerts:module_id}UI Components & Interactive
Renders and processes the email-alerts subscription flow for an Alerts module on a public page. Pass the alerts module id (the same id as the module collection, also the reader slice). On a normal page load it returns an empty string. When the page URL carries an aw query parameter (sent in welcome e-mails), it confirms that subscriber e-mail and returns a localized confirmation notice; when it carries an au parameter (sent in alert e-mails, with c the collection id), it unsubscribes that reader and returns a localized notice. If the module id matches no alerts collection it returns empty. Because it reads live query parameters and module state it is never cached. The wiki notes it is an early implementation: at present it handles confirm and unsubscribe; the full subscribe and profile-management form is not yet emitted.
Applies an alias function to a field value, returning the transformed output. Alias functions are AA's field transformation pipeline — they format, filter, or convert field values before display. Syntax: {alias:field_id:alias_function:parameters} The field_id is a dot-padded 16-character field identifier (e.g. publish_date....). The alias_function is one of AA's built-in alias functions (f_d for date formatting, f_c for conditional output, f_h for HTML, etc.). Additional parameters depend on the alias function used. Common alias functions: - f_d — format a date/timestamp: {alias:publish_date....:f_d:j.n.Y} - f_c — conditional output (show text only if field is set): {alias:field_id:f_c:text} - f_h — HTML-safe output (escapes HTML entities) - f_t — trim whitespace - f_s — URL-safe (seoname) transformation Alias functions can be nested: {alias:switch.........1:f_c:text:{alias:publish_date....:f_d:j.n.Y}} Note: In most modern AA usage, field aliases defined in the Slice Admin (alias1–alias3) are preferred over using {alias:} directly, as they centralize the transformation logic. Use {alias:} when dynamic or inline alias application is needed. Implementation: part of AA's alias/field processing layer in stringexpand.php. Status: Active — not deprecated.
Experimental in-memory array (a key-value store) you build up across a template and read back. It keeps one named array per id for the whole page render. The first parameter is the array id, the second is the command, and the rest depend on that command. set writes a value at a key (an empty key appends), get reads one key, addmulti splits a string and appends each part, addset adds a number into a key (a numeric accumulator), joinset appends a value to a key with a delimiter, getall returns every value joined (optionally re-formatted and sorted), getfiltered returns only the values matching a substring. The build commands (set, addmulti, addset, joinset) print nothing, only get, getall and getfiltered produce output. Because the store is shared across the whole page by id, give each array a unique id and build it and read it in the same place.
{asciiname:string:encoding}String & Text Manipulation
Converts any text into a lowercase ASCII-only string suitable for a username, filename, or URL fragment. It transliterates accented and non-ASCII letters to their plain ASCII equivalents (for example e-acute becomes e, z-caron becomes z), lowercases everything, and replaces every character that is not a letter, digit, hyphen, or underscore with a hyphen. Runs of separators collapse to a single one and leading or trailing hyphens are trimmed. Letters, digits, hyphens and underscores survive; dots and all other punctuation are turned into hyphens. The optional second parameter names the SOURCE character set of the input (default utf-8); set it to windows-1250 or iso-8859-2 only when the input bytes are in that legacy encoding rather than UTF-8. For a slug that also keeps dots, enforces uniqueness, or trims length, use seoname instead.
{asis:text}Data Access & Item Display
Returns its argument exactly as-is, with no escaping or formatting. Two cases: if the argument is a field id of the current item (for example abstract........), asis returns that field as stored in the database; this differs from the named getter abstract........, which honours the field HTML/plaintext setting and may turn newlines into line-break tags. If the argument is not a field id, it is returned as literal text. asis is variadic, so any colons in the value are preserved: the colon-separated parts are simply rejoined with a colon. The result is never HTML-escaped.
{avatar:image:name:size}UI Components & Interactive
Renders a small square avatar for a person or organisation. Given an image URL it returns an img tag sized to a square thumbnail (width and height both equal to size, aspect ratio ignored). If the image is empty or cannot be loaded it falls back to a coloured div showing the initials taken from the name. The initials are the first letter of the name plus the first letter of the second word, or the second letter if there is only one word; a name containing an @ is treated as an e-mail and only the part before the @ is used for the title and initials. The fallback colour is derived from the name, one of eight CSS classes dis-color1 to dis-color8, so the same name always gets the same colour. Defined in AA_Stringexpand_Avatar in stringexpand.php. Typical use inside an item template is the avatar of an uploaded photo field with the headline as the name, feeding an image field and the _#HEADLINE alias.
{avg:val1:val2:...}Math & Numeric
Returns the arithmetic mean (average) of the values you give it. Values are passed colon-separated, as in avg:12:45:8, or as a single JSON array, as in avg:[12,45,8] - both average the same three numbers. With one value it returns that value; with no values it returns an empty string. The result is a true division and is never rounded - a repeating decimal prints with PHP default precision (for example avg:12:45:8 gives 21.666666666667); wrap it in round or number_format for fixed decimals. Each value is read as a number: comma decimal separators are normalized to dots, and non-numeric text is read as 0 but still counts toward the divisor. In the JSON-array form only, empty-string entries are dropped before averaging (zero is kept). Companion commands: max and min.
{backlinks:item_id:slice_ids:sort}Data Access & Item Display
Returns the dash-separated IDs of every active item that links to a given item. A backlink is an item somewhere in your site that points at the target through a relation field (or any other field that stores the target id), so backlinks answers the question "what references this item?" - the reverse of following a relation outward. Internally it is a wrapper around the ids command, searching all text fields of the chosen slices for the target id, so the result is a plain id list you can feed to count, view, foreach or item. With no second parameter it scans every slice that shares a site module with the target item, sorted by slice then publish date (newest first); pass a dash-separated list of slice IDs to restrict the search. The third parameter overrides the sort (for example category descending then headline ascending); pass a single dash to skip sorting entirely, which is the fastest way to just collect the ids. If the item id is missing or the item does not exist, backlinks returns an empty string.
{base64:string}String & Text Manipulation
Base64-encodes a string - the AA counterpart of PHP base64_encode(). It turns any text into the standard base64 alphabet (A-Z, a-z, 0-9, plus / and =), which is plain ASCII and safe to drop into a URL, an HTML attribute, a header or a filename. The output is padded with one or two = characters so its length is a multiple of four; an empty input gives an empty result. The input is not trimmed, so leading and trailing spaces are part of what gets encoded. This command only encodes; AA has no matching {base64decode} expression. A common pattern is to encode a hash or key and then cut it short with substr to make a compact opaque token.
{bin2url:data}Encoding & Formatting
Encodes text or binary data into the URL-safe Base64url alphabet (RFC 4648 section 5). It runs standard base64, then replaces + with - and / with _, and removes the trailing = padding, so the result can be dropped into a URL path, query string, or filename without further escaping. Decode it back with url2bin. The parameter is not trimmed, so leading and trailing spaces are encoded as part of the data.
{changed:item_id}Data Access & Item Display
Returns the list of field IDs that changed during an item's most recent edit, joined by dashes (for example category.......2-expiry_date.....). It reads the change-history record AA writes whenever an existing item is saved. Pass the long (32-character hex) item ID, usually the current item via the _#ITEM_ID_ alias. Returns empty when the ID is missing or not a valid item ID, when the item was only created and never edited (history is recorded on update, not on insert), or when the item's slice has history logging turned off. The last-edit diff always ignores the internal last_edit....... field. The typical use is inside item events and e-mail notification templates - test the result with ifin (one field) or intersect plus ifset (any of several fields) to act, or mail, only when the fields you care about changed. Related: changedate (when a field last changed) and history (a field's earlier values).
Returns the date of the last recorded change to one field of an item, formatted like the date command. It takes the item id, the field id (the selector of the field to inspect), and an optional date format. Internally it looks up the item edit history (the change log) for that field and passes the timestamp to the date command, so format accepts the same patterns as date - for example Y-m-d, j.n.Y, or a DATE_ constant such as DATE_ATOM. When format is empty the result is a raw Unix timestamp (the date default). If the item id is not a valid item id, the field id is empty, or that field has no recorded change, the time is zero and the command returns a fixed two-dash placeholder shown as a double dash; this placeholder is built in and cannot be overridden. History is only recorded when the slice has history logging enabled (the historylog slice property is not set to 0) and the field was actually changed by an update - inserts are not logged, and the last_edit field is ignored. The everyday use is showing when a field was last edited, passing the current item id alias _#ITEM_ID_ as the first argument, a field selector as the second, and a human date format as the third. Related commands: changed lists which fields changed in the last edit, history returns past values of a field, and lastedit gives the slice-wide last modification date.
Renders a complete self-service password-reset flow for front-end user (reader) accounts, driven entirely by request parameters. With no parameters it shows a form asking for the e-mail. When the reader submits it, changepwd looks them up by username or e-mail in the reader slice and mails a key link that is valid for two hours. Opening that link shows a new-password form; submitting it changes the password once the key is valid, the two entries match, and the password is at least six characters long. The first parameter is the reader slice ID and is required: if it is not a valid 32-character ID the expression prints nothing. The optional second parameter sets the From and Reply-To address of the reset e-mail; without it the install error-reporting address is used. To set a new password for one named user without rendering any form, use the sibling command changepwdsendmail, which mails the key link and returns 1 on success.
Sends a password-reset e-mail to one reader (member) account, identified by username, in a reader slice. This is the non-interactive companion to changepwd: where changepwd renders the self-service forms a visitor clicks through, changepwdsendmail fires the reset e-mail directly for a user you already know. The e-mail carries a time-limited link (valid about two hours) that lets the reader set a new password; if the reader slice has a password change e-mail template, that template is used, otherwise a built-in message is sent. Output is one of three literal strings: 1 when the e-mail was sent, err when the user could not be found or sending failed, and an empty string when the reader slice id is not a valid 32-character id. Because it actually dispatches mail, call it only in response to a real request (for example a form submission), never in a view that re-renders on every page load.
{colonescape:text}String & Text Manipulation
Replaces every colon in the given text with the escaped form #: , the marker AA uses for a literal colon. AA splits command parameters on the colon, so any colon inside a value would otherwise be read as a separator and break the call. colonescape protects such values - typically a time like 16:45, a URL, or any field or nested-command result that contains a colon - so the whole string is passed on as a single parameter. The text is not trimmed, and a literal colon written directly in the call is split off before it reaches colonescape, so feed the value from a field, an alias, or a nested command (or write the colon as #: yourself). This is a low-level helper; most often you let AA escape colons for you and reach for colonescape only when building a value to hand to another command.
{compare:val1:val2}Logic & Conditionals
Compares two values and returns a single letter: E if they are equal, G if the first value is greater, or L if the first value is less. Comparison is numeric when both values look like numbers, otherwise it is done as text (character by character). On its own compare prints only the letter; in practice you wrap it in ifeq or switch to turn E/G/L into readable words, markup, or a sort decision. Parameters are trimmed of surrounding spaces. The expression is never cached.
{conds:text:mode}Data Access & Item Display
Formats a value (or a list of values) into a search condition you can drop into an {ids} or {view} query. Given a field id of the current item, it reads that fields values; given literal text or a JSON array such as ["sky","ice"], it uses those values directly. Multiple values are joined with OR so the condition matches any of them. The mode controls the output form: empty (the default) URL-encodes the value for a view.php query-string parameter; 1 double-quotes it for an {ids} d-FIELD-=-VALUE condition; == returns the bare value for the {ids} == operator. Because {ids} conditions use a single dash as the field-operator-value separator, every literal dash in a value is doubled (- becomes --) so the value is not mis-split. An empty value yields the sentinel AAnoCONDITION in quoted/encoded mode (so an empty filter matches nothing rather than everything) and an empty string in == mode.
Looks up one constant in a constant group by its value and returns a chosen property of it - by default the constant name (its human-readable label). Constant groups are the shared lookup tables behind category and select fields; a stored field usually holds the constant value (a code like 2), and this expression turns that code into the label readers see. The first parameter is the group id, the second is the value to find. The optional third parameter what selects which property to return: name, value, short_id, description, pri, group, class, id or level - or any AA expression built from the constant aliases _#NAME###_, _#VALUE##_, _#DESCRIPT, _#PRIORITY and the rest. If you pass a value_delimiter (fourth parameter), the value is split on it and each part is looked up in turn, so one call can translate a whole multi-value field at once; the results are joined by output_delimiter (fifth parameter, default a comma and a space). A value that is not in the group returns an empty string. Use the singular constant for one lookup; use constants (plural) to list every entry in a group.
{constants:group:format:delimiter}Data Access & Item Display
Lists every constant in a constant group, in priority order. A constant group is a named, reusable lookup table (the same store behind AA categories and select-box options); each row has a value and a human-readable name. The group argument is the group id; format chooses what to print for each row - value (the default) or name, or a template using the row aliases _#VALUE##_ and _#NAME###_; delimiter joins the results. With an empty delimiter (the default) the rows are concatenated with nothing between them. Two special delimiters build structured output: json returns a JSON array, jsonasoc a JSON object. An unknown or empty group yields an empty string. To read a single constant by its value use the constant command; to emit ready-made HTML option tags use options.
{const_column:field_id}Misc / Specialized
Retrieves a column value from the AA Constants/Categories table for the constant identified by the given field's value. Used to look up metadata about a category option — for example, to get its name, value, or class. Syntax: {const_column:field_id} The column suffix determines which column is retrieved from the constants table. Valid suffixes: - {const_name:field_id} — returns the constant's display name - {const_value:field_id} — returns the constant's value - {const_short_id:field_id} — returns the short ID - {const_id:field_id} — returns the numeric ID - {const_pri:field_id} — returns the priority/order - {const_group:field_id} — returns the group - {const_class:field_id} — returns the CSS class - {const_description:field_id} — returns the description - {const_level:field_id} — returns the level in hierarchy Example: {const_name:category.......1} returns the name of the category constant stored in field category.......1. The field_id is a dot-padded 16-character identifier of a category/select field in the current item. The value of that field is used to look up the matching constant record. Useful when displaying the human-readable label of a select/category field instead of the raw constant ID. Implementation: class AA_Stringexpand_Const in stringexpand.php. Status: Active — not deprecated.
{convert2chars:text}String & Text Manipulation
Converts named HTML entities into the actual accented characters they stand for. For example the e-acute entity becomes an accented e, and the c-caron entity becomes an accented c (see the examples below for the literal entity syntax). Use it when content was stored or imported with accented letters written as HTML entities (for example from an RSS feed or a legacy import) and you want the real characters on output. The conversion uses a fixed lookup table covering Western European (Latin-1) accents plus Czech and Slovak carons and acutes. Entities that are not in that table are left untouched: numeric entities (the ampersand-hash-number form) are not converted, and named entities outside the set (such as the euro or copyright entity) pass through unchanged. The text is otherwise returned as-is.
{convert:text:from:to}String & Text Manipulation
Converts a string from one character encoding to another, transliterating any character the target encoding cannot represent. Internally it calls iconv with the TRANSLIT flag, so accented letters degrade to their closest plain-ASCII form when you convert to us-ascii (for example, an a-acute is reduced to a plain a, and a c-caron to a plain c). When the source and target encodings are identical the text is returned unchanged. An empty from or to defaults to utf-8. Typical uses: downgrade accented content to plain ASCII for slugs, filenames or legacy systems, or move older windows-1250 content to utf-8.
{cookie:name}System & Utility
Reads HTTP cookies sent by the visitors browser. With a cookie name, it returns that cookies value, or an empty string when the visitor has no such cookie. With no name, it returns every cookie as a JSON object (the raw PHP $_COOKIE array, json-encoded). The output reflects the current request, so it is not cacheable and not a fixed value - it changes per visitor. The name is trimmed before lookup. Cookie values come straight from the browser and are not trusted input; escape them before use and never rely on them for authorization.
{count:ids:delimiter}Data Access & Item Display
Counts the parts of a delimiter-separated string - typically a list of item IDs. It splits ids on the delimiter and returns how many non-empty parts remain, as a string. Counting an ID list this way is much faster than aggregate count, because it never reads the items from the database; feed it the output of the ids command and it simply counts. Empty input returns 0. Parts that are empty or whitespace-only are skipped, so a doubled delimiter does not inflate the total. The delimiter defaults to a single dash and is not trimmed, so it may itself contain spaces.
{credentials:slice_pwd:slice_id}Security & Authentication
Registers a slices reading password for the current page so protected content from that slice can be displayed later on the same page. The password is hashed and added to the pages list of known passwords; any view or item expression that reads the matching protected slice afterwards is then allowed to render its items. The expansion itself outputs nothing - it is a side effect only. Useful in the Site module and in views that pull in content from a password-protected slice. The first argument is the plain-text reading password (it must match the slices Reading Password). A second argument appears in the signature but is not used by the current engine. Marked experimental in the source.
{css:reserved:css}System & Utility
Registers a block of CSS to be emitted into the page HEAD. The stylesheet you pass is collected during page expansion and printed as a style element at the position marked by the generate HEAD command (the same mechanism the require command uses for JavaScript and external libraries). The expression itself outputs nothing at the call site - it always returns an empty string - so it is safe to place anywhere in a template or view without disturbing the surrounding text. The first parameter is reserved for future use (intended for CSS priority or layer) and is currently ignored; the actual stylesheet is the second parameter. With only one segment the value lands in the reserved slot and nothing is registered, so always keep the leading colon. Requires the page to include the generate HEAD marker for the style block to appear.
{csv:text:char}String & Text Manipulation
Escapes a single value so it is safe to place inside one field of a CSV (comma-separated values) row. If the value contains the separator character, a double quote, or a line break, csv wraps the whole value in double quotes and doubles every internal double quote (the RFC 4180 rule). A value with none of those characters is returned unchanged. The second parameter sets the separator character to test for; it must be exactly one character, otherwise a comma is used. Build a whole CSV row by escaping each field with csv and joining the results with your separator. Leading and trailing whitespace is trimmed from the value before escaping.
{datatable:selector:options}UI Components & Interactive
Turns plain HTML tables into interactive DataTables (the DataTables.net jQuery plugin): client-side paging, sorting, filtering, and search. It matches every table whose CSS selector is selector and calls DataTable(options) on it. The command itself prints nothing - it registers the DataTables library and an init script into the page head and footer, so the page must use generate:HEAD and generate:FOOT in its Site module for the table to activate. The selector defaults to .datatable (any table with class datatable). options is an optional JSON object forwarded verbatim to DataTable(), e.g. paging and info toggles. Note: experimental - the bundled version does not sort Czech or other accented characters correctly by default.
Formats a date or time using a PHP date() format string. The timestamp is a Unix timestamp; if you omit it the current time is used. A timestamp given as text (for example 2008-07-01 or the phrase next Monday) is first run through PHP strtotime(). If you omit the format too, date returns the raw Unix timestamp (PHP format "U"). The format parameter also accepts a PHP DATE_* constant name such as DATE_RFC2822 or DATE_ATOM. The third parameter, no_date_text, is printed instead when the timestamp is empty or within one day of zero, which is how AA marks an unset date field. The fourth parameter, zone, set to GMT, formats in UTC (PHP gmdate) instead of the server timezone. Note: the same colon that separates arguments will also split a literal clock time like 10:30, so format such a value from a field rather than typing it inline. The now expression is an alias for date and shares its first two parameters.
Returns the difference between two dates given as Unix timestamps. By default it reports whole completed years, which makes it handy for ages. The end date defaults to the current time, so a single timestamp gives the years elapsed since then. The third parameter is a PHP date_diff format string. Common codes: %y whole years, %m remaining months (0 to 11), %d remaining days, %a total days across the whole span, %h %i %s remaining hours/minutes/seconds, %R a sign that is + or -, %r a sign that is - or empty, and %% a literal percent. Upper-case codes (%Y %M %D %H %I %S) are the zero-padded forms of their lower-case counterparts. Each part is one slice of the decomposed interval, so %m never exceeds 11; use %a when you want the total number of days. The order of the two timestamps does not change the magnitude; only %R or %r reveals which date came first.
Formats a start and end timestamp as a compact date range, mainly for event calendars. It collapses the parts the two dates share: a range on a single day prints just that date, a range inside one year prints the year only once at the end, and a range across two years prints both years. If a timestamp carries a time of day other than midnight (or 23:59 at the end), that time is shown after the date. The output uses narrow non-breaking spaces after the day and month numbers and an en-dash between the two dates, so it stays on one line and reads as a typographic date range rather than plain ASCII.
Sends a message through the Czech Data Box system (datova schranka / Mojedatovaschranka). This is a side-effect command: it always returns an empty string, and on a valid send it redirects the browser to the Data Box login service to authorize and dispatch the message. Use it with care - it can trigger a send on every page load. The conf parameter controls whether anything is sent: empty (or any value other than 1, test, or standard) is a safe no-op that returns the empty string and does nothing; test sends to the testing server; 1 or standard send for real. The to, annotation, and attachments parameters are all required for a send; if any is missing the command is a no-op. attachments is one URL, a JSON array of URLs, or a JSON object mapping display names to URLs. The optional params is a JSON object of extra envelope fields (dmToHands, dmRecipientRefNumber, and similar). ret_url is where the service returns after sending (the current page by default), and related_to may be an item id to associate with the message. To review messages sent from a site use the oitem and oids commands on the datovka object.
{debug:level:store}System & Utility
Turns AA's internal diagnostic logging on or off for the current page render. It is a developer tool: the command itself produces no visible output (it returns an empty string), it only sets the debug level. When the level is non-zero, AA collects timing and tracing data while it builds the page and prints a diagnostics summary at the end of the render on pages that support it (view.php, the Site module). The level is a bitfield: 0 turns debugging off; bit 1 (value 1) enables page-cache notes; bit 2 (value 2) enables expansion and query tracing; higher bits add more detail (the engine reads levels up to 511). The optional second parameter is a named slot: set it to save the current level before changing it, then later restore that level by calling the command with an empty level and the same slot name. The slot lives only for the current page render. Calling the command with a non-numeric, non-empty level is a special undocumented form whose output is not stable and on this install raises an error - do not rely on it. Because the visible diagnostics depend on which page renders them and on runtime timing, the effect is runtime-dependent; the command's own return value is always empty.
{debuglog:text}System & Utility
Writes a message to the AA system log and returns an empty string. The text you pass is stored as a log entry of type DEBUG, together with the current user, module, IP address and request URI, so you can trace when and where a template was rendered. It produces no visible output - it is a diagnostic side effect, the template counterpart of writing to a server log. Use it to record that a branch was reached, dump a value into the log, or mark a render in the admin log viewer (aa_log.php). Because logging happens every time the template is expanded, it is never cached. View the entries under Logs in the admin interface, filtered by event type DEBUG.
{decrypt:text:key:output_type}String & Text Manipulation
Decrypts a ciphertext that was produced by the encrypt command, using key as the password, and returns the original plaintext. AA uses AES-256-GCM (via the PHP sodium extension); the key string is turned into a 32-byte key automatically - short keys are padded, long keys are hashed - so any key length works, but the SAME key must be used to encrypt and decrypt. Decryption is authenticated: if the key is wrong or the ciphertext was altered or is not a valid ciphertext, decrypt returns an empty string instead of an error or garbage. The third parameter output_type is deprecated and ignored (kept only for backward compatibility; the legacy mcrypt format is no longer supported). Encryption uses a fresh random nonce each time, so encrypting the same text twice gives two different ciphertexts that both decrypt back to the same plaintext.
{define:name:expression}System & Utility
Stores a named expression (a variable) that you read back later with the var command. The expression is evaluated where define runs, and the stored value lasts for the whole page render - so define lets you compute something once and reuse it many times, or pass a value from one view into another (for example email templates). define itself prints nothing; it only stores. Within one expression, commands run left to right, so define a name before the var that reads it; and because the store is page-wide, a var can also read a value defined earlier elsewhere on the page. Redefining the same name overwrites it. An empty name is ignored. The companion command is var, which both reads a defined value and, in its two-argument form, defines one.
{definejson:name:expression}JSON & Data Structures
Stores a parsed JSON value under a name so later expressions can read parts of it. The expression you pass - a literal JSON string, or anything that produces JSON such as an include of a remote endpoint or a view that outputs JSON - is JSON-decoded once and kept in the page-global content cache under the key definejson:name. You read it back with jsonpath:name:query, not with var:name (var reads a separate plain-text store that define writes). Like define, definejson prints nothing - it returns an empty string; its only effect is storing the value. The command token is case-insensitive, so definejson and defineJSON are the same command, but the variable name you choose is case-sensitive. If the expression is not valid JSON it is decoded to an empty array, with no error. The definejson must run before the jsonpath that reads it on the same page.
{detect}System & Utility
Detects the visitor device class from the browser User-Agent and returns one of three bare words: mobile, tablet, or desktop. Call it with no parameter. A server-side render with no mobile browser - the documentation test harness, search-engine crawlers, plain HTTP clients - reports desktop. Pair it with ifeq or switch to choose a layout per device. The one parameter is reserved for a future test selector and is not implemented; passing any value returns an empty string. The result is cached without the User-Agent in the cache key, so on a cached page the first visitor's device type may be served to others - render with nocache or clear the cache when per-device output must stay accurate.
Scans a block of text and replaces every whole word that matches a keyword in a dictionary slice with a format string of your choice - typically a link. The dictionary is one or more slices; each item lists its trigger words in its keywords........ field, and the format template uses the token _#KEYWORD_ for the matched word. Only whole words are replaced (not substrings), a keyword also matches its first-letter-uppercase form, and text inside script, h1-h6 and a tags, and inside HTML tags themselves, is skipped so existing links and headings stay intact. With an empty dictionary, or when nothing matches, the text is returned unchanged. Best used on a single item fulltext rather than long listings, since matching large dictionaries is costly.
Returns the great-circle distance in whole metres between two points on Earth, each given as a latitude and longitude in decimal degrees. The calculation uses the haversine formula on a sphere of radius 6371000 metres (the mean Earth radius), so it is the as-the-crow-flies distance, not a road or route distance. The four arguments are, in order, the latitude and longitude of the first point and the latitude and longitude of the second point. Use positive values for north and east, negative for south and west. Each argument is evaluated as a math expression (the same evaluator as the math command), so arithmetic and a decimal comma both work; anything that is not a number evaluates to zero. The result is truncated to a whole number of metres. To show kilometres, wrap the call in the math command and divide by 1000.
Renders a ready-to-use edit widget (a form input) for ONE field of an existing item, pre-filled with that field current value. The widget matches the field configured input type (text input, checkbox, select, date picker, ...) unless you override it. Resolution: item_id picks the item (leave it empty to edit the field on the CURRENT item being rendered); field_id is the field to edit, given as its full padded id such as headline........ (dots pad the name to 16 characters). edit returns ONLY the widget HTML - it does not output a form tag, a submit button, or any save logic, so it is only useful placed inside a form you build and submit yourself. It returns an empty string when field_id is empty or the item or field cannot be resolved (an unknown item id or field name yields nothing, no error). Companions: editfull renders the same widget WITH its label, live makes the field editable in place (save on change), and ajax edits it through a click-to-edit popup. This command is never cached (the value is read fresh from the database on every render).
{editable:item_id:field_id:placeholder}UI Components & Interactive
Renders the value of one field as an inline, in-place editor on the public page so a logged-in editor can change the content directly where it is shown, without opening the admin item form. The field value is wrapped in an HTML element with the attribute contenteditable=true: a div for multiline text fields (full text, textarea, HTML editor), a span for single-line fields. AA also loads the CKEditor rich-text editor and a Save changes toolbar button, so edits are written back to the item. With no item_id the current item in context is used. An optional placeholder shows when the field is empty. The command returns an empty string when no field_id is given, when the item cannot be found, or when the field does not exist on the slice. Because the markup carries live item and field ids and pulls in the editor scripts, the output is install and item specific - useful inside a slice or view template, not as a fixed value.
Renders a ready-to-submit edit widget for one field of an item, WITH its label and help text. It is the labelled form of edit: same parameters, same behaviour, but editfull wraps the input in the full form row (label, the required asterisk, and the field help), while edit shows the bare widget only. Use it to build in-place editing forms - typically inside a slice or view template where an editor is logged in. The widget is pre-filled with the field current value and posts back to AA on submit. With an empty item_id the command edits the CURRENT item in context (the item being rendered in the loop). Without a field_id, or for a field that does not exist on the item slice, it renders nothing. By default it shows the widget configured for that field; pass widget_type to override it (for example sel, dte, chb) and widget_properties (a JSON object) to set options such as const_arr, name and input_help. editfull is never cached - it always reads the live item from the database.
Encrypts text with a password using authenticated AES-256-GCM encryption (via libsodium). The key can be any length - it is derived into a 32-byte AES key. The result is a URL-safe Base64url string with a fresh random nonce prepended, so encrypting the SAME text twice gives DIFFERENT output every time; encrypt is therefore not deterministic and is meant to be paired with decrypt using the same key. Because it is authenticated, decrypting with a wrong key fails and returns an empty string rather than garbage. The third parameter output_type is obsolete and ignored (output is always Base64url now). This no longer uses the old mcrypt extension, so text encrypted by very old AA versions cannot be read back.
Returns the ID of an existing item, or creates a new item and returns its ID. The first argument is an existing item ID: if it is a valid 32-character item ID, ensureitem returns it unchanged and does nothing else - the template and any field/value pairs are ignored, and no item is created or modified. If the first argument is empty or not a valid ID, ensureitem behaves exactly like newitem: it copies the template item (given by its ID) into a new item, applies the field/value pairs, and returns the new ID. This is the lookup-or-create pattern: pass a found ID (for example from an ids lookup) as the first argument so an item is reused when it already exists and created only when it is missing. The template must live in a slice related to the current slice, the new item is set active with an empty seo field, single values are plain text and multi-values are JSON arrays. ensureitem never updates an existing item - use updateitem for that. Because it touches the database it is never cached.
Adds an EU cookie-consent banner to the page. The inline result is always an empty string - this is a side-effect command: it registers a footer script that holds the banner config, optional inline CSS for positioning, and the smart-eu-cookies JavaScript library. The banner only appears once the page is assembled, so the site template must contain generate HEAD and generate FOOT. All parameters are optional; called bare it shows a default English banner. Labels are passed verbatim, so localize them yourself (for a Czech site write Czech text and button labels). The type parameter controls placement.
{expand:string}String & Text Manipulation
Runs a second AA expansion pass over its argument. Templates normally expand once; a value read from a field is returned as plain text, so any AA constructs stored inside that value are left untouched. Wrap the read in expand and the engine resolves those constructs too. It is the standard way to run template syntax that was stored as content - for example a mail body or message template held in a field. Plain text with no AA syntax passes through unchanged. Note that inline syntax you type directly is already expanded by the normal pass, so expand only adds a visible effect when the text still contains unexpanded constructs after the first pass (typically because it arrived from stored data).
Shows text with a "more / less" toggle. If the text is longer than the length threshold, it renders a shortened version followed by a link that reveals the full text on click; a second link hides it again. When the text is shorter than the threshold no toggle is added and the text shows in full. Each call gets a fresh random element id, so the HTML differs on every render. The page must load the AA JavaScript library (aajslib) for the toggle to work. The empty-text and whitespace-only cases produce no output.
{facebook:url:type}Communication & Social
Renders a Facebook Share button for a given page URL. The button is output as an inline iframe that embeds Facebook's official share_button.php plugin, so it works without any extra script include. Pass the URL of the page you want people to share as the first parameter - typically the public URL of the current item, e.g. _#SEO_URL_. If the URL is empty the command returns nothing. The optional second parameter selects the layout: the default is a compact icon-only button (77x20 px); pass +share to get the wider button_count layout (110x20 px) that shows a running share-count badge next to the button. Because the button is rendered live from Facebook, its exact appearance and the share count depend on Facebook at view time.
{field2html:field_id}Data Access & Item Display
Renders one field of the current item as HTML. For a plain-text field, the value is HTML-escaped, bare URLs are turned into clickable links, and newlines become line breaks. A field already flagged as HTML is returned unchanged. An empty field, an unknown field name, or no current item all yield an empty string. The single parameter field_id is the field id (for example abstract........ or full_text.......), not a field alias. Because the field id is read against whichever item is current when the command runs, inside an item or view loop you must wrap the call in deferred-eval parentheses so it binds to the looped item rather than the surrounding template item.
{field:field_id:property:slice_id}Data Access & Item Display
Returns a property of a slice field - by default its admin-defined display name (caption), but also its input help, data type, aliases, or the multi-value, multilingual and formatable flags. It reads the field's configuration, not any item's stored value. Give the field id (the dotted slug), the property to read, and optionally the slice id; if the slice id is omitted the slice of the item currently being rendered is used. The property defaults to name, and any unrecognised property name also falls back to name. The common use is rendering a field's label in a template - for example a table header - so the caption stays in step with the slice configuration. Aliases come back with their leading _# prefix.
{fieldid:type:num:id_type}ID & Type Operations
Builds a 16-character field id from a type name and a number, the same id format AA uses internally to address an item field. The type name comes first, then the number is placed at the right end, and the space between is filled with a padding character (a dot by default, or an underscore). Number 0, or no number, gives the base field id of that type. The number must be between 0 and 99999, otherwise the result is an empty string. Use it when a template needs to compose a field id from parts rather than hard-code the 16-character string.
{fieldoptions:slice_id:field_id:values}Data Access & Item Display
Renders the HTML option tags for a field that has a defined set of allowed values - a select, checkbox, radio or multiselect widget, or a field whose options come from a constant group or a linked slice. Each allowed value becomes one option element. Pass the current value(s) in the third parameter to mark them as selected: a single value as plain text, or several values as a JSON array for multi-value fields. A field with no enumerable options - a plain text field, an unknown field id, or a field whose value list is empty - yields an empty string. Typically used to build or refresh a select box, for example in an AJAX-driven form.
{file2text:url}Media & Images
Reads the plain-text content out of an uploaded DOC, DOCX, PDF or ODT file, so the text can be searched or indexed. The url argument is the file path or address - usually a file-field getter. The install must define the matching external converter (CONV_TEXTFILTERS_DOC, _DOCX, _PDF or _ODT); if the converter for that file type is not configured, or the extension is none of those four, the result is empty. Output is runtime-dependent and never cached. Typical use: a Computed field stores the extracted text so an ordinary text search finds words inside attachments.
{fileinfo:url:info}Misc / Specialized
Returns one piece of metadata about a file, given its URL. The url is usually a file or upload field getter; the second argument names what you want. type and name are read from the URL string alone, so they work anywhere. size, bytesize, link, typesize, crc, time, mime and ifwebimg need the real file to be readable on disk or over HTTP and return empty when it is not. With no second argument, or an empty url, the result is empty. The companion command filelink builds a full download link and calls fileinfo internally for the type and size.
Builds an HTML download link for a file URL, annotated with the file type and size. Returns an a-element whose href and link text come from the URL (or from a supplied label), with a title attribute and a trailing fileinfo span showing the type and size in brackets. An empty url returns an empty string. Internally it asks fileinfo for the type (the URL extension) and size (read from the local upload path, or fetched over HTTP); the size is empty when the file is neither a local upload nor reachable, so only the type shows. Use it to turn a stored file field into a ready-made download link.
{filter:ids:expression:equals:operator}Data Access & Item Display
Filters a list of item ids by evaluating an expression for each item and comparing the result to a value. It returns the ids that pass, joined by dashes and kept in the same order as the input list. The expression is evaluated against each listed item, so refer to that item with its _#ALIAS aliases (a field-getter would read the rendering item instead). The operator chooses how the expression value is compared to equals: omit it for an exact match, or pass != , contain, !contain, isset, notset, or intersect. isset and notset ignore the equals value and test only whether the expression value is empty. Filtering in the database with ids is usually faster, but filter is handy when you already hold a set of ids and want to narrow it. Internally filter is a thin wrapper over aggregate with one of its filter functions.
Returns a value that is unique within one field across the given slice or slices. finduniq searches those slices for an item whose field equals the value; if one exists it appends 2, then 3, and so on (with no separator, so name becomes name2) until the value is free, and returns that. With no slices it returns the value unchanged. An item id can be passed as ignore_item_id so the item being saved does not collide with itself. If the value is empty it returns a fresh random id. The search covers active, expired, pending and holding items. This drives the Unq field inserter, which keeps a field unique on every save.
{fmod:num1:num2}Math & Numeric
Returns the floating-point remainder of dividing num1 by num2. It is the AA counterpart of PHP fmod(). Both arguments are converted to float before the division, so decimal operands and a decimal result are allowed - unlike an integer-only modulo. The remainder is what is left after num1 is divided by num2 a whole number of times: fmod(10, 3) is 1 because 3 fits into 10 three times with 1 left over. The result takes the sign of num1 (the dividend), not of num2, so fmod(-10, 3) is -1 and fmod(10, -3) is 1. A result of 0 means num1 is an exact multiple of num2, which makes fmod useful for cycle tests such as every Nth item or alternating rows. Dividing by zero is undefined and returns NAN. Non-numeric text converts to 0. fmod is never cached: it is re-evaluated on every request.
Iterates over a list of values, substituting each into a template fragment. It splits values by valdelimiter (default -), substitutes each non-empty value into text, and joins the results with outputdelimiter (default: nothing). Inside text the current value is _#1 — or its modern synonym _#loop (both are the value itself, not an index). Empty values are skipped.

JSON mode: when valdelimiter is the literal word json, values is read as JSON instead of being split by a character. A JSON array iterates into _#1; a JSON object names the variable after its key (a color key gives _#color); nested arrays produce the cartesian product with positional aliases _#loop0, _#loop1, …

Per-item conditions (gotcha): a nested if/ifeq that depends on the current value must be wrapped in deferred-eval braces and reference the value as _##1 (double hash). Deferred-eval braces postpone evaluation until each iteration; without them the inner expression runs once, before the loop, so every row gets the same answer — e.g. you get NO|NO|NO instead of NO|YES|NO. See the two per-item condition examples below for the exact syntax.
Renders a stored AA form by its form id, as an inline item-submission form a visitor can fill in and post. The form must first be defined and saved in the slice Forms admin (se_forms.php); the form id is that saved form object id, not a slice id or a view id. The output is a fieldset holding the form field rows, hidden inline and slice_id inputs, and an Insert button that posts the entry through filler.php. The first parameter form_id selects the form. The optional second parameter ok_code is placed in the form hidden ret_code input and is used as the response shown after a visitor successfully inserts an item. An empty form_id yields an empty string; any non-empty value loads a form (an unknown id loads an empty one) and emits the fieldset wrapper. The command is never cached, since the form HTML is rebuilt on every request, and the wrapper id is randomized per render.
Emits hidden anti-spam fields to drop inside an anonymous submission form. In its bare form it adds a hidden honeypot text input named answer (kept out of view by a CSS rule): a human leaves it blank, but a bot that fills every field sets it, and filler.php rejects any post whose answer is not empty. Pass a slice id to add stronger CSRF protection: AA issues a one-time per-session token, switches page caching off, and emits two more hidden inputs - slice_id and aa_token - plus a small script that fills slice_id only after the visitor moves the mouse, types, or touches the screen. filler.php then refuses any post whose aa_token is missing, already used, or older than the token lifetime; the slice must also have anonymous posting set to the token-protected level. Place the command inside the form tag, before the visible fields. Output is runtime-dependent (the token changes every render), so it is never cached.
Splits a slice item-edit form into named tabs (parts). You place it in a field Input before HTML in slice field administration; at that point in the form a new tab begins. Each colon-separated argument names a tab: the first names the new tab that starts here, and any further arguments pre-name the tabs that follow (handy for naming the last tab, which has no formbreak of its own). The command prints nothing - it only marks the split and registers the tab labels. By default the tab bar appears both above and below the form. Variants set the position: formbreaktop puts the tab bar only at the top, formbreakbottom only at the bottom. The companion command formpart prints the number of the current part. Tabs render only inside the item editor; the expression has no visible output on a public page.
Splits a slice item input form into tabbed parts and puts the tab switcher at the bottom of the form. Place it in the inputform template between the fields of one tab and the next; it marks the boundary. The colon-separated arguments are optional names for the tabs that follow the break - useful above all for naming the last tab, which has no break of its own. It prints nothing: its only effect is on how the admin add and edit form is laid out, so outside an inputform it produces empty output. Related: formbreaktop puts the switcher at the top, formbreak puts it at both top and bottom, and formpart prints the number of the current part.
Splits the item edit form into tabbed parts and places the row of tab buttons above the form. Put it in a field's Before-input HTML where one part should end and the next begin; everything after it (until the next break or the form end) becomes the next tab. The colon-separated arguments name the tabs - the first names the tab the break closes, the rest name following tabs (handy for the last tab, which has no break of its own). It is a layout-only marker: it prints nothing into the form body and has no effect outside the item editor. formbreaktop, formbreakbottom and plain formbreak differ only in where the tab bar is drawn (top, bottom, or both); see formpart for the running part number.
Renders an inline AJAX edit form for an EXISTING item, built from a saved AA form definition. The first argument, form_id, is the object id of a form created in Forms administration (it lists which fields to show and how). The second argument, item_id, is the long id of the item to edit; when omitted, the form edits the current item in context (for example the item rendered by a view). The command returns an empty string when form_id is missing or names no saved form, or when the item cannot be found. It is never cached: the output is a live editing widget, so examples here are illustrative. To render an empty form that ADDS a new item, use form instead of formedit.
{formpart}Forms & Input
Prints the number of the current form part. Form parts are tabbed sections of a slice input form created by formbreak, formbreaktop and formbreakbottom; each of those breaks increments a part counter, and formpart prints its current value. The counter starts at 0 and is reset at the start of every expansion pass, so with no break before it the result is 0, after one break 1, after two breaks 2, and so on. Typical use is inside a fields Input-before-HTML to tag each parts table rows with a part-specific CSS class for styling. Takes no parameters.
Adds a small panel of clickable buttons that remember what a visitor previously typed into a form, so they can refill it with one click. It must sit inside a form. On each submit the browser stores the serialized form values in the visitor browser (localStorage), keeping up to 5 distinct entries; each stored entry shows as a button labelled with the value of the form first input (truncated to 16 characters). Clicking a button resets the form and refills it from that stored entry. With no parameters it saves the whole enclosing form; pass a CSS selector as the first parameter to save only that subform. The second parameter is an optional label shown before the buttons (HTML allowed). The command emits an empty container div and loads the form-saver JavaScript; the buttons appear only once at least one entry has been saved, and only in the browser - there is no server-side output to test. Requires jQuery (loaded automatically).
{fulltext:item_ids}Data Access & Item Display
Renders one or more items using their slice fulltext template - the full-item HTML layout defined in slice admin under Design, Full text format (top, fulltext, bottom), with the slice Remove rules applied. The output is exactly what a single-item full view produces. Pass one id or a dash-separated list of short or long ids; each active item is rendered in turn and the results are concatenated. Ids that match no active item - inactive, expired, deleted, or simply unknown - are skipped and contribute nothing, so an empty or all-invalid argument yields an empty string. Because the output is the HTML your slice defines, it is install-specific; use it where you want a stored items full presentation rather than a single field.
{generate:section}System & Utility
Marks the spot in a site-module page where AA should drop the CSS and JavaScript that the rest of the page asked for. You normally place generate:HEAD just before the closing head tag and generate:FOOT just before the closing body tag. AA collects every library, stylesheet and script registered by require, css, eucookies, widgets and other commands across the whole page render, removes duplicates, orders libraries before the code that depends on them, and writes the head part at generate:HEAD and the footer part at generate:FOOT. Without these two markers the collected includes have nowhere to go and page features that depend on them stop working. Internally generate does not output the links immediately: it emits a placeholder comment (AAGenerate plus the section name) and registers a final postprocess pass that replaces the placeholder once the page is fully built. Because of this it only does its job when the page is finished by the Site module (or by an item-edit form), and its result depends on what the page required, so it is not a fixed string. generate is never cached - it is recomputed on every request. Google Analytics consent wiring is handled by the same pass when a tracking id and a consent bar are configured.
Returns the host name for an IP address by doing a reverse-DNS (PTR) lookup, the AA counterpart of the PHP gethostbyaddr function. Pass an IPv4 or IPv6 address; the command returns the registered host name, or the address itself when no PTR record exists. An empty argument returns an empty string and skips the lookup. Because the result comes from live DNS it can change over time and is not cached as a fixed value. Typical use is resolving the visitor's address from the server REMOTE_ADDR variable.
Builds a site URL from the page that is being viewed right now, then applies the changes you pass in the query string. Designed for the Site module: it reads the current router state (language, path segments, pager page, query string) and rewrites only the parts you name, leaving the rest in place. This makes it the canonical way to write internal links that stay on the same page or jump to a sibling section without hard-coding the full path. The query string is a list of name=value pairs joined by ampersands. Recognised names: xlang switches the interface language and resets to that language home; xseo1 through xseo9 set individual path segments (an empty xseoN cuts that segment and everything after it); xseoadd appends one extra segment to the current path; xpage sets the pager page (1 means no page suffix); xflag and xcat set the flag and category in the path prefix; xqs replaces the entire query string (xqs= alone clears it); and xqs_NAME sets or replaces a single query-string variable while keeping the others. Setting any xseo or xseoadd also clears the pager and query string. Pass 1 as the second argument to HTML-encode the result for safe use inside an attribute. Note: the URL is built relative to the page on which go runs - its language and current path - so the examples below show the representative URL a live page produces and are marked illustrative.
{gps:gps:format}Misc / Specialized
Parses a GPS coordinate string and returns it as decimal latitude/longitude. It accepts several common notations: decimal degrees with hemisphere letters (49.9679189N, 12.5029972E), signed decimals separated by a space or comma (-50.09697 14.42332 or 41.40338, 2.17403), and degrees-minutes-seconds (49 deg 58 min 4.508 sec N, 12 deg 30 min 10.790 sec E). The hemisphere letter, if present, must follow its number, not precede it. With no format given, the result is "latitude,longitude" (or just the one value that parsed). Pass a format template to control the output: the tokens _#lat and _#lon (case-insensitive) are replaced by the latitude and longitude. The format must not contain a colon - AA reads a colon as a parameter separator, so anything after it is dropped. Input that does not match any recognised pattern yields an empty string.
Sets an HTTP response header on the current page and expands to nothing (empty string). Use it to override the status code or Content-Type that AA would otherwise send, to force a download, or to attach a security header. The first parameter is the directive; the second is its value for directives that take one. Common directives: status codes 200, 201, 304, 400, 401, 404, 409, 410; content types plain, html, css, js, json, xml, csv, ical, svg, gif, jpg, png, ico, bin; and utf-8 for the charset. filename sets a download name (Content-Disposition attachment). Named headers CSP, CSP-RO, RT, NEL, XCTO, RP, and CORS take their value in the second parameter; CORS also allows the X-Requested-With request header. Because the call sets a header rather than printing text, place it where its empty output does no harm, and call it before the page body is sent. To decide the header at runtime, build the directive inside the first parameter (see the conditional example below); never wrap the whole header call inside another command argument, because then the header is set even when the condition says it should not be.
{history:item_id:field_id:time:format}Data Access & Item Display
Reads a field value from an item edit history (the change log). Give it the item long id and the field id; it returns what that field held at an earlier revision. The third argument time selects which revision: empty or -1 is the last value before the current one, -2 the one before that, and so on; a positive number is a Unix timestamp and returns the value in force at that moment (falling back to the current value if no older change is recorded); any other string (for example a single bar) is used as a delimiter and joins ALL historical values of that field. The fourth argument format is a template applied to each value, with the placeholders _#val, _#date, _#user and _#timestamp; it defaults to _#val (the bare value). A field with no recorded change history - and likewise a missing or unmatched item id or field id - returns an empty string (it does not error).
{hitcounter:type:ids:from}Misc / Specialized
Renders a per-day hit-statistics table plus trend charts for one or more items, built from the hit_archive log that AA writes on every public page view. Give it a time grouping (the type parameter), a dash-joined list of item ids, and optionally an earliest timestamp. The output is HTML and ChartJS canvases, so it belongs in an admin page or template, not in an RSS/JSON view. What it shows is the install live traffic: an empty or unrecognized type, or items that have no logged hits, render nothing at all. This is the same renderer the admin Statistics page uses.
{html2text:html}Encoding & Formatting
Converts an HTML fragment to plain text, the way AA builds the text alternative of an HTML e-mail. It decodes HTML entities (and nbsp to a space), turns each link into its visible text followed by the URL in curly braces, maps block tags to line breaks (br, closing p, closing h1-h9, closing tr), turns each li into a bulleted line, draws hr as a row of dashes, removes script, style and head blocks entirely, then strips every remaining tag and tidies whitespace. One important trap: the argument is read only up to the first unescaped colon, so any colon in the HTML (a URL, a style value, a time) must be written as #: to survive; otherwise the text is silently cut at the colon. The result is never cached and the input is not trimmed.
Builds an expand/collapse toggle. The first state is shown inline; the link switches to a second state whose HTML is fetched once by AJAX from a URL on the same server (the first time it is opened). Renders a togglelink anchor and two toggleclass divs (the second hidden until loaded), each carrying a random id so several toggles can coexist on one page. The page must load the AA JavaScript library (javascript/aajslib.php) for the AA_HtmlAjaxToggle handler. If both link labels are left empty they default to the plus/minus icons; position bottom puts the content divs before the link instead of after. Use htmltoggle when the second block is short and can ship inline; use this when it is large or expensive and should load on demand.
Builds a toggle link that shows and hides page element(s) matching a CSS rule, loading their content from a URL by AJAX on the first open. On the first click it fetches url_of_text, inserts it into the matched element, reveals it, and swaps the link to its second text; clicking again hides it (the loaded content is kept, so later toggles do not re-fetch). The optional fifth parameter lets the AJAX content land in a different element than the one shown and hidden - handy for tables, where you toggle a whole row but update only one cell. The css_rule_hide selector is required; without it the command outputs nothing. With both switch texts empty it falls back to the built-in [+] / [-] icons. The link runs the AA_HtmlAjaxToggleCss helper (provided by the bundled aa-jslib JavaScript, which must be loaded on the page) and the URL must be same-origin. The generated link id is random on every render, so this command is never cached. Compare with {htmltogglecss} (same show/hide, no AJAX load) and {htmlajaxtoggle} (AJAX into a fixed pair of divs rather than a CSS rule).
{htmlspecialchars:string}Encoding & Formatting
Escapes the HTML-special characters in a string so the result is safe to print inside HTML page text or an attribute. It is the AA counterpart of PHP htmlspecialchars and converts five characters to their HTML entities: ampersand, less-than, greater-than, double quote, and single quote (apostrophe). All other characters pass through unchanged. See the examples below for the exact entity each one produces. Note that it does NOT skip already-encoded entities, so an existing entity is encoded a second time (double encoding). This command is deprecated and is now just an alias of the safe command: internally both call the same safe() function, so prefer safe in new templates. Use it whenever you place untrusted or user-submitted text into HTML, to prevent broken markup and cross-site scripting.
Builds an inline show/hide toggle: a link plus two HTML blocks, with only one block visible at a time. Clicking the link swaps the visible block and the link label. switch_state_1 / switch_state_2 are the two link labels (the tokens [+] and [-] become small show/hide images); code_1 / code_2 are the two HTML blocks (code_1 shown first). If both blocks are empty the expression returns nothing; if the two blocks are identical it renders a single always-visible block with no link. position can be top (default) or bottom to place the link before or after the content. An optional persistent_id (letters and hyphens) remembers the open/closed state across page loads via browser localStorage. The expression needs the AA JavaScript library (aajslib / aa-jslib), which it requests automatically. Because each instance uses a fresh random element id, the exact HTML differs on every render.
Builds a small show/hide toggle. It outputs an anchor link that, when clicked, reveals or hides every page element matching a CSS selector, and switches its own label between two texts (for example Show details / Hide details). Use it for collapsible detail panels, FAQ answers, or read-more sections. The matched element(s) should start hidden with style display:none, unless is_on is 1. The page must load AAs aajslib.php so the toggle helper AA_HtmlToggleCss is available. Because the link needs a unique id each time, the output is never cached and differs on every render. An empty css_rule prints nothing. For AJAX-loaded panels use htmlajaxtogglecss; to switch between two full HTML blocks use htmltoggle.
{icq:user_id:action:style}UI Components & Interactive
Displays an ICQ status indicator for a user: a small online or offline image that links to that ICQ account. Pass the ICQ user number (UIN), an optional action that decides which ICQ page the link opens, and an optional icon style number. With an empty user id the expansion outputs nothing. The output is a fixed HTML anchor wrapping an image served from ICQ status server. Note that ICQ was shut down in 2024, so the live image and link no longer resolve; this expansion is kept for legacy templates and as a sibling of the skype and yahoo indicators.
Returns the long ids of items from one or more slices, filtered by conditions and ordered, as a delimiter-joined list. It is the building block for data-reading templates: feed its output to item, view, count or unique to display or tally matching content without writing SQL. Only active items are searched (holding, pending and trashed items are skipped), and ids are returned as 32-character long ids joined by the delimiter (default a dash). With no match the result is an empty string; with delimiter set to json the ids come back as a JSON array. The conds parameter is a d- string of field-operator-value triplets (operators include = and == for exact match, the comparisons less-than greater-than and not-equal, CONTAIN and BEGIN for text, ISNULL and NOTNULL for empty checks). sort takes one or more field ids, ascending by default or descending with a trailing dash. restrict_ids intersects the search with a known id set, and limit caps the count (a negative limit returns the last N).
{if1:condition:text:else_text}Logic & Conditionals
A strict boolean test against the literal value 1. Returns the second parameter (text) when the first parameter (condition), after whitespace is trimmed, equals exactly the one-character string 1; otherwise returns the third parameter (else_text), which defaults to empty. This is not a general truthiness test - only an exact 1 counts as true. The values 0, empty text, true, 01 and 1.0 all take the else branch. The typical use is with a checkbox or boolean field, which prints 1 when set and nothing when unset, so the condition reads that field-getter. For an any-non-empty-text test use ifset; for a numeric comparison with operators use if; for value equality use ifeq.

Numeric conditional. Compares a value (the etalon) against one or more test values using a single comparison operator, and returns the output paired with the first test value that matches. If nothing matches, the trailing else text is returned.

Comparison is always numeric (also for security reasons). The etalon (etalon) and every test value (value1, value2, ...) are converted to a float before comparing: spaces are stripped and a comma is read as the decimal point, so 1 000,5 becomes 1000.5. Any non-numeric string converts to 0 - so comparing two words always sees 0 against 0. For text equality use ifeq instead.

Operators (the etalon is the left-hand side):

  • = == eq - equal
  • <> != ne - not equal
  • > gt - greater than
  • >= ge - greater than or equal
  • < lt - less than
  • <= le - less than or equal

An unknown operator never matches, so the else text is returned. The aliases are ge and le - not gte/lte.

Multiple pairs: after the operator you may chain as many value:text pairs as you like. They are tested top to bottom and the first match wins, like a numeric switch. A final unpaired argument is the else text; if it is omitted and nothing matches, the result is empty.

Placeholders in the output: inside the returned text, _#1 is replaced by the etalon (as a normalized number) and _#2 by the first test value. The output may also contain any other AA expression.

Runtime-dependent: this command is never cached, since it usually compares live values.

Source: AA_Stringexpand_If in include/stringexpand.php.

Tests whether bits are set in an integer bitset (a number whose individual bits are independent on/off flags). Reads option-text pairs after the bitset: for each pair, the option is a bitmask and the text is returned when every bit of that mask is set in the bitset - that is, when bitset bitwise-AND mask equals mask. The first matching pair wins; if none match, the trailing else text is returned. A mask of 0, or an empty mask, always matches (useful as a default branch). Inside the returned text, _#1 expands to the bitset value and _#2 to the matched mask. It is the bitmask counterpart of the ifeq and ifin conditionals, but reads several flag conditions in one call.
Compares one value against one or more options and returns the text of the first option that matches. ifeq trims the etalon and each option, then tests them with strict, case-sensitive string equality. The first matching option/text pair wins and its text is returned; if nothing matches, the optional trailing argument (else_text) is returned, or an empty string when that argument is omitted. With several option/text pairs ifeq works like a compact switch. Inside the returned text the alias _#1 is replaced by the compared value (etalon) and _#2 by the first option, and any other AA expression is expanded as usual. Use ifeq for plain equality (marking the active navigation item, branching on a language or status code); for numeric comparisons such as greater-than or less-than use the if command instead, and to test a multi-value field against a value use ifeqfield. ifeq is never cached, so it always reflects the current request.
Compares a value against every value held by one field of an item, and prints one of two texts depending on whether any of them match. If the field is multivalue (a listbox, checkbox group, or any field that can hold several values), ifeqfield matches when at least one of those values equals var; for a single-value field it is a plain equality test. The first parameter is the item to read. Leave it empty (or pass current) to read the item currently being displayed. If the item does not exist, or the field is not present on it, the else_text branch is printed. Inside text or else_text the alias _#1 stands for var (the value you searched for) and is substituted in whichever branch is returned. The comparison is exact and case-sensitive. Unlike if, which compares numbers, ifeqfield compares the field values as strings.
Prints text when haystack contains needle as a substring, otherwise prints else_text. The test is a plain case-sensitive substring match (haystack contains needle), not equality and not word matching. You may pass several needle:text pairs after the haystack - they are tested left to right and the FIRST matching pair wins; any single leftover parameter at the end is the else_text used when nothing matched. Two placeholders are available inside the chosen text: _#1 expands to the whole haystack and _#2 expands to the needle that matched. Two edge cases to know: an empty needle ALWAYS matches (it short-circuits to its text), and parameters are NOT trimmed, so leading or trailing spaces in haystack or needle are significant. This command is never cached. For set membership use ifintersect; for exact equality use ifeq.
Tests whether two dash-separated sets of values share at least one member. set1 and set2 are split on dashes (members are trimmed; empty members are dropped). If the two sets have any common member, ifintersect returns text; otherwise it returns else_text. This is the set-overlap counterpart to ifset and ifeq, equivalent to checking that intersect of the two sets is non-empty. You may chain extra set2:text pairs after the first; the first set2 that overlaps set1 wins (the rest are skipped), and the trailing unpaired argument is the else_text fallback. Inside the returned text, _#1 expands to set1 and _#2 to the matching set2. Typical use is permission and tag matching: compare a content item rights set against the current user roles. ifintersect is never cached, so it re-evaluates on every render.
Prints text only when a condition has content. If condition is non-empty after trimming, ifset returns text; otherwise it returns else_text. Inside text or else_text the alias _#1 stands for the condition value, so you do not have to repeat the expression. A condition that is only an unresolved alias - a 10-character token like _#HEADLINE, or _#P followed by digits - counts as empty, so a missing or empty field falls through to else_text. ifset is variadic: you may chain several condition:text pairs and it returns the text of the first non-empty condition, with a trailing unpaired argument as the final else. Watch the colon delimiter - a colon inside text (a URL, a time, a CSS pseudo-class) starts a new argument and can break the expression.
Conditional text. Like ifset, but it first strips HTML comments from the condition before testing it, so a condition that contains only an HTML comment counts as empty. If the condition has any real text left (after removing comments and trimming) and is not an unresolved field alias, the text branch is printed; otherwise the else_text branch is printed. You may chain several condition:text pairs - the text of the first non-empty condition wins, with the final leftover argument as the else_text. The alias _#1 inside the chosen text is replaced by the condition that matched (empty in the else branch). Parameters are not trimmed when stored and the result is never cached (runtime-evaluated). Typical use: emit an HTML attribute or label only when a possibly comment-only field actually carries content.
Classifies a string by testing its type and returns the text for the first type that matches. The first parameter is the value to classify (the haystack); after it come type:text pairs tested left to right - the first matching type wins and its text is returned. A final unpaired parameter is the else text, returned when no type matched (omit it to return nothing). Supported types: longid (a 32-character hexadecimal item id), shortid (a positive whole number under 12 digits, used as a short item id), mail (a valid e-mail address), signed (any whole number, negatives allowed), number (a whole number of zero or more, no sign), positive (a whole number greater than zero). An unknown type name never matches. Inside any returned text _#1 is replaced by the tested value and _#2 by the name of the type that matched. Because 0 is a number but neither shortid nor positive, and a negative like -5 is signed but not number, list the most specific type first.
Builds a phpThumb image URL from an image path or URL plus resize parameters. By default (no info) it returns just the URL string, which you place inside your own img src attribute - this is the common use, with a file field as the image and a phpThumb size like w=150 and h=150 and zc=1. The phpthumb_params are passed straight to phpThumb (w, h, zc=1 for zoom-crop, iar=1 to keep aspect ratio, q for quality, and more). With no params the image path is returned unchanged. The info parameter switches the output: im or img or imgb returns a ready img tag (imgb adds border 0; param1 becomes the title and alt text, param2 adds extra attributes); picture returns a responsive picture element with an avif or webp source; url and rawurl return the relative or absolute URL; width, height, mime and imgtype return metadata read from the actual image (this loads the file, so it is slower and only works for a reachable image). An empty image argument yields an empty string. The URL points at this install img.php handler, so its path prefix is install-specific (for example /aaa here, /aadev through view.php).
Generates an image with text drawn on it and returns a ready-to-use img tag. The image is rendered on demand by the install img.php endpoint using the phpThumb wmt (watermark-text) filter, so the src points at img.php rather than a stored file. width, height and a non-blank text are required - if any is missing imgtext returns an empty string. The remaining parameters control the typography: font size, alignment, text colour, an optional TrueType font, opacity, margin, rotation angle, and a background colour with its own opacity. Because the output embeds the install path and is produced at request time, it is best used inline in templates where an image of a caption, label or watermark is needed without uploading a file.
Fetches the content of a file or URL and returns it inline. By default it makes an HTTP request to fn (a filename or URL); the type parameter selects another source or HTTP method. With type GET/POST/PUT/DELETE/PATCH/OPTIONS/HEAD it performs that HTTP method, sending data as the request body and headers (a JSON object, typically built with jsonasoc) as request headers - the common pattern for calling REST APIs. type http (the default) and ajax fetch a URL; site, fileman and readfile read a local file from the site or slice file area or the document root. If fn is empty nothing is fetched and the result is empty. On a failed request the err text is returned instead; inside err the tokens _#status and _#errmsg are replaced with the HTTP status code and the error message. The literal URL_PARAMETERS inside fn is replaced with the current query string. Note: every render runs the fetch, so use include only where a live request on each page view is intended.
{index:field_id:index:item_id:lang}Data Access & Item Display
Returns a single value from a multi-value field of an item. Fields in AA can hold several values at once (a checkbox or relation list, several abstracts, or language translations) and index reads the value at one zero-based position. With no item id it reads the field of the item being rendered; give an item id to read any item by its long id. The optional lang code shifts the position into that language's slot, so index can fetch one specific translation of a multi-language field. A position past the last value, or a language with no translation, returns an empty string. The default position is 0, the first value.
Renders the empty input widget (with its label and help text) for one field of a slice, ready to drop into a custom new-item submission form - the building block of hand-built filler/registration forms that post to filler.php. Give it the slice id and the field id; the widget is the same one the item editor would show for that field, and its form-control name is aa[nINDEX_SLICE][FIELD] so a filler POST creates a new item. Pass required=1 to mark the field required. You can override the widget with a 3-letter widget_type code (for example sel) and pass widget_properties as a JSON object to tune it (name, input_help, const_arr, row_count, input_type, ...). preset_value is accepted but the original code marks it not yet implemented, so do not rely on it. item_index (default 1) sets the aa[nN_...] group number so several inputs on one page belong to the same new item, or to different ones. If the slice or field does not exist the command returns an empty string (unless the slice has autofields, when an unknown field id is cloned from the text field). The companion inputonly does the same without the label and help.
Renders just the editing widget for one field of a slice - the bare form control, with no label and no help text around it. It is the no-chrome twin of input: same parameters, same widget, but input wraps the control in a labelled table row while inputonly emits only the widget itself. Use inputonly when you are building a custom new-item form and want full control over the surrounding markup. The input is named for a new (not-yet-saved) item, so posting the form creates a new item in that slice. If the slice or field cannot be found, inputonly returns an empty string. By default it uses the slice of the item being rendered and the widget the field is configured with; you can override the widget type, pass widget options as JSON, preset a value, mark it required, and index it so several new items fit on one page.
{inputvar:...}Forms & Input
Renders the input control (the actual edit field - text box, checkbox, select, date selector, file upload, ...) for one slice field, exactly as Slice Admin defines it. It is meaningful only inside a custom item-editing form: when a slice uses a custom field layout (its Input form template, the slice_field setting), AA builds each field control and stores its HTML in the page cache under the key inputvar plus the field id, and this command reads it back. Use it to place individual fields - a headline box, a price input, a checkbox, an image picker - anywhere in your own form layout, for example to put two inputs on one line. The first argument is the field id (the eight-plus-dots id, e.g. headline........). An optional second argument selects a named sub-part of a compound widget instead of the whole control: html_rb and plain_rb (the HTML/plain radio buttons of a text field), day, month, year, time (the pieces of a date field), unselected, selected and presets (parts of a select), file, change, retype, and a few more. Outside an item-editing form the cache key is not set, so the command returns an empty string. Content carried inside a control is protected so any _# aliases it contains are not expanded a second time. The result is never cached.
{internal:class_name}Misc / Specialized
Experimental extension hook. Dispatches to a named AA PHP class: it calls that class static internal_expand method, passing the current item content plus any extra colon-separated arguments. Used inside admin views to surface computed, non-stored values - for example a scheduled task next-run time, or a count of recent log entries. Three conditions must all hold: there is a current item, the class is already loaded in memory (no autoload is attempted), and the class defines a static internal_expand method. If any condition fails the command outputs the literal text qqq. Only a small set of internal classes implement this method (AA_Plannedtask and AA_Log); it is an admin-side mechanism, not a general content tag, and by design must never expose sensitive data. Because output depends on the live item and runtime state, results are never cached and are not guaranteed across versions.
{intersect:set1:set2}Sorting & Filtering
Returns the set intersection of two dash-separated id lists: the ids found in both set1 and set2, dash-separated. Output keeps the order of set1 and drops empty entries; duplicate ids inside set1 are preserved. Built on array_intersect over explode_ids, so each side is split on dashes and trimmed. A common use is to keep only the items a query or view returned that are also in some allowed or selected list. The companion command removeids returns set1 with the ids of set2 taken out.

Fetches one or more items by ID and renders a template against each of them. It is the core cross-slice lookup: read a field from a known item, or expand a small per-item template, without building a full view. Often paired with the ids command, which returns a dash-separated list of item IDs to feed in.

The content template is expanded in the context of each matched item, so reference the target item fields with that item aliases (such as _#HEADLINE). A plain field-getter inside content reads the surrounding item, not the fetched one.

When several IDs are given, the delimiter is placed between the per-item results. The delimiter also accepts two format modes: json returns a JSON object keyed by item ID, and jsonasoc reads each result as key to value and returns a JSON object. Empty per-item results are dropped before joining.

Only ACTIVE items are searched by default; the bin parameter widens this to HOLDING or TRASH. Tree notation with parentheses (with the top and bottom wrappers) renders nested structures such as breadcrumbs. An empty ID list returns an empty string. Parameters are not trimmed, so spaces in the delimiter are kept. Source: AA_Stringexpand_Item in stringexpand.php.

Renders a set of items arranged as a TREE. The first parameter is a tree string: a dash-separated list of item ids where parentheses mark children, for example Gamma(Beta-Kappa) means Gamma is the parent of Beta and Kappa. The remaining parameters are templates expanded once per node, reading that item with its field aliases such as _#HEADLINE (each node is bound as the current item, like inside item). For every parent node, top is printed before its children and bottom after them; the parent node itself prints no content, only its wrapper. For every leaf node, content is printed, and delim is inserted between siblings at the same level. itree is the tree-display sibling of item: same engine, but a more natural parameter order (top comes before content). Inside any template you may reference the sibling parameters as _#1 (top), _#2 (content), _#3 (delim) and _#4 (bottom), which is handy for nesting the content template inside top. A flat list with no parentheses, like Gamma-Beta, just prints content for each item joined by delim, with no top or bottom. Typical use is breadcrumb navigation built from a seo path, or a threaded discussion tree. The tree string is usually produced by treestring or by xid path. This expression is never cached because item data can change between requests.
{jabber:user_id:action:style}Communication & Social
Builds an XMPP/Jabber presence badge: an xmpp: link to the given address wrapped around a status image served by the legacy onlinestatus.org indicator at www.the-server.net. With no user_id it expands to an empty string. Note two source facts you should not rely on: the action parameter is accepted but unused by the current code (a leftover from the sibling ICQ and Yahoo commands), and the badge image host is a defunct third-party service, so the img will not load on a live page. The command still emits well-formed markup, so it documents the historical syntax; for a working contact link prefer a plain xmpp: anchor.
{javascript:text}Encoding & Formatting
Escapes a string so it is safe to drop inside a single-quoted JavaScript string literal. It does two things: every apostrophe (single quote) becomes a backslash followed by an apostrophe, and every line break (CR, LF or CRLF) becomes one single space. Nothing else is touched - double quotes, angle brackets and HTML entities are left exactly as they are, so this is not an HTML or XML escaper. The text is not trimmed, so leading and trailing spaces survive. Because AA splits expansion parameters on the colon, a literal colon in the text is read as a parameter break and everything after it is dropped; write such a colon as hash-colon so it reaches the output. To embed the result in an HTML attribute wrap the whole thing in safe; for full JSON-safe quoting use jsonstring instead.
{join:delimiter:val1:val2:...}String & Text Manipulation
Concatenates an unlimited number of values into a single string, separated by the first parameter (the delimiter). Values that are empty or contain only whitespace are dropped before joining, so the delimiter never appears next to a gap - handy for optional fields like a second address line. As a special case, a delimiter of the literal word json returns a JSON array of the non-empty values instead of a joined string. Parameters are not trimmed, so the delimiter may be a single space and values keep any leading or trailing spaces.
{jsonarray:text:delimiter}JSON & Data Structures
Splits a delimited string and returns its non-empty pieces as a JSON array. The default delimiter is a hyphen; pass a second argument to use another separator (a single space is allowed, because the arguments are not trimmed). Empty pieces are dropped. The input must be UTF-8. Note that if an empty piece is removed from the start or the middle, the surviving pieces keep their original positions and the result is a JSON object keyed by those positions rather than an array - a trailing empty piece is safe. Use it to feed a delimited field value into JavaScript or a JSON parameter.
Builds a JSON object (an associative array) from an even, alternating list of key and value pairs: key1, value1, key2, value2, and so on. Keys are trimmed of surrounding whitespace; values are kept verbatim (leading and trailing spaces are preserved). A pair whose key is empty after trimming is skipped, and a final key with no value is dropped. The result is a compact json_encode string with no spaces and with slashes escaped. Its main use is to supply a named map where another command expects one: HTTP request headers for include, button labels for manager, or a const_arr for input and edit. Sibling commands: jsonarray builds a JSON array from a delimited list, and jsonstring quotes a single value as a JSON string.
Runs a JSONPath query against a JSON value and returns the matching data. The first parameter is either a JSON variable name defined earlier on the page with definejson, or a literal JSON string (for example one loaded with include from a remote API). The second parameter is the JSONPath query (paths like dollar dot data, array indexes, wildcards, and filter expressions). By default only the first matching value is returned; pass a delimiter as the fourth parameter to return all matches joined by it (note: the delimiter is appended after every match, including the last, so a trailing delimiter remains). The optional third parameter picks one attribute from each matched object, or the literal JSON to return the whole matched structure as a JSON string, or varjson to store each match in a temporary JSON variable and return its name. A query that matches nothing, an invalid JSONPath, or invalid JSON all return an empty string without raising an error.
{jsonstring:string}String & Text Manipulation
Wraps a value as a JSON string literal: it adds the surrounding double quotes and escapes the characters JSON requires - the double quote, the backslash, and control characters such as newline and tab. Forward slashes and accented or non-ASCII letters are left as they are (the JSON standard allows this and parsers accept it); input that is not already UTF-8 is converted to UTF-8 first. Leading and trailing whitespace is trimmed before encoding. The typical use is inserting a text field value into a hand-written JSON object or a JavaScript function call so its quotes and newlines cannot break the surrounding syntax. The output already includes the quotes, so do not add your own around it.
{jwtdecode:key:add_validity}Security & Authentication
Reads the Authorization request header, validates a Bearer JWT against the secret key, and returns the authenticated user id on success or an empty string on failure. The header must be of the form "Authorization: Bearer TOKEN"; the token must be a JWT signed with HS256 using the same secret key passed to jwtencode. On any failure - no header, a non-Bearer scheme, a bad signature, an expired or malformed token - it returns empty, so a non-empty result means the request is authenticated. The returned value is the user id stored in the token sub claim. The optional add_validity is a revocation check for Reader Management users (long id): it is an alias or AA code evaluated for that user and compared to the aaValid claim baked into the token; if they differ the token is rejected. This is request-dependent, so during normal page rendering (no Authorization header) it returns empty. Some Apache or mod_fcgid setups drop the Authorization header; FcgidPassHeader Authorization in the server config restores it. Use jwtencode to mint the token that jwtdecode verifies.
Authenticates a user by username and password and, on success, returns a signed JSON Web Token (JWT) that the user can send back in an Authorization Bearer header to prove their identity. The token is signed with HS256 using your secret key and carries the user id (sub), an issued-at time (iat) and an expiry time (exp). If the secret key, username or password is missing, or authentication fails, the command returns an empty string. The lifetime parameter sets how many seconds the token stays valid; left empty it defaults to 86400 (one day). The optional add_validity parameter is an AA expression evaluated for the authenticated user and stored in the token as an extra check, letting you invalidate older tokens later (for example on logout); it only works for Reader Management users. Decode and verify a token with jwtdecode. Output is a fresh signed token on every call, so jwtencode is never a deterministic test.
{lastdisc:item_id:count_item_itself}Data Access & Item Display
Returns the Unix timestamp of the most recent visible discussion comment on a given item. It queries the discussion table for the latest posting (state 0, meaning shown - hidden comments are ignored) on that item and returns its date as a plain integer timestamp. Pass the long (32-character hex) item ID, usually the current item. If the item has no visible comments, the result depends on the second parameter: by default it returns 0, but when count_item_itself is the literal string 1 it falls back to the item publish date instead (any other value, including 0, keeps the 0 result). With no item ID at all the result is 0. The raw timestamp is meant to be fed to date for display, or used as a sort key to surface the most recently discussed items. The matching field alias on a slice is usually defined as lastdisc of the item ID. Related: changed and changedate (item edit times), and the discussion module that stores the comments.
Returns the date of the most recent item modification, formatted with a PHP date() format string. With no slice given it scans every slice and reports the newest last_edit across the whole install; pass a slice long id to limit it to that one slice. Every item store stamps last_edit with the current time, so the value tracks real edit activity. If no matching item exists the timestamp falls back to the Unix epoch (1.1.1970). The format string is a literal PHP date() format: letters are date codes, a backslash escapes the next letter to a literal character, and a colon must be written as the escaped hash-colon so it is not read as a parameter separator.
{lazy:url:placeholder:mode}UI Components & Interactive
Defers loading a chunk of page content until it is needed. It outputs a placeholder div and a small piece of JavaScript; the browser fetches the target url by AJAX and drops the response into the div. By default the fetch waits until the placeholder scrolls near the viewport (an IntersectionObserver with a 200px bottom margin), so heavy or rarely-seen views do not slow the first paint. The url is requested with method POST and the X-Requested-With header, the same way an ajax view call is made. An empty url produces no output. The mode parameter switches between the lazy default, now (fetch as soon as the page loads, no observer), and nolazy (load the content inline on the server at render time, with no JavaScript). Typical use is a relative url to a view, for example a comments list or a related-items block on an article page.
{lcfirst:string}String & Text Manipulation
Lowercases the first character of a string and leaves the rest unchanged. The AA counterpart of the PHP lcfirst function, but UTF-8 aware. Only the first character is touched, so a later capital letter (for example in an acronym or CamelCase word) is preserved. An empty input gives an empty result, and a string that starts with a digit or symbol is returned unchanged because there is no leading letter to lower. To uppercase the first character instead use ucfirst; to lowercase the whole string use strtolower.
{limit:ids:offset:length:delimiter}Data Access & Item Display
Returns a slice of a delimited list - typically a list of item ids. It works like the PHP array_slice() function: offset is the 0-based start position and length is how many entries to keep. Both offset and length may be negative (counted from the end of the list). The result is re-joined with the same delimiter. Leading and trailing whitespace and a single-character delimiter are trimmed off the input before splitting. The most common use is take the first id: limit a list to offset 0, length 1.
{linkcheck:url:format}System & Utility
Checks whether a URL is reachable and returns its HTTP status, formatted however you like. linkcheck makes a live request to the address (a HEAD, falling back to GET), follows redirects, and reports the result. With only a url it returns the status code, such as 200. A second format parameter is a template in which aliases are replaced with that link's values: _#code (status code), _#text (status comment like OK or Not Found), _#weight (severity from 0 healthy to 5 broken), _#color (a matching hex colour), _#span (a ready-made coloured badge), _#redir (final URL after redirects), _#hops (number of redirects), _#mime and _#charset (content type), and _#duration (seconds taken). mailto: addresses are checked for a valid mail domain - write the colon as mailto#: so it is not read as a parameter separator. The result is never cached, since it reflects the link's state right now.
Renders one field of an item as an in-place (live) editable widget that saves by itself the moment the editor leaves the field, with no full page reload and no surrounding form. Point it at an item id and a field id; on a published page the field shows its current value as an editable input, and an onchange handler posts the new value back over AJAX. Use the optional required, function (a JavaScript callback run after a successful save), widget_type (a 3-letter widget code such as sel or dte to override the field default) and widget_properties (a JSON object configuring that widget) parameters for finer control. Pass an empty item_id to edit the field of the current item in a loop (write _#ITEM_ID_ to be explicit). Live editing only renders for a logged-in editor with write permission and the aa-jslib script loaded; for an anonymous visitor, or an unknown item or field, it renders nothing. Related: edit and editfull render the same widget in form style, ajax gives a click-to-open inline editor, and input renders a widget for a brand-new item.
Renders a live search widget on the page - a search input plus a results list that refreshes as the visitor types. The first parameter is the AA view that produces the results; the typed phrase is passed into that view as the search term, so each keystroke re-runs the view and updates the list. Pass a bare view id and the phrase is matched against the views first condition automatically; pass full view parameters and mark where the phrase goes with the AA_LS_QUERY placeholder. The optional second parameter sets the search fields placeholder text, the third sets a default phrase searched when the field is empty (use a single dash to start with an empty list). Requires jQuery and aajslib-jquery. The output is HTML and JavaScript generated fresh on every request, so it is never cached and the examples below are illustrative rather than fixed test values.
{log:num:base}Math & Numeric
Returns the logarithm of num. When a base is given, it is the logarithm of num in that base; when base is omitted it returns the natural logarithm (base e), the same as PHP log() called with one argument. Both num and base are treated as floating-point numbers. A num of 0 returns -INF and a negative num returns NAN, since the logarithm is undefined there. This is the AA counterpart of PHP log().
Finds value in a delimited list and returns the matched item position. With no text parameter it returns the 1-based position (_#pos). The list is split on delimiter (a hyphen by default), or parsed as a JSON array when values starts with an open square bracket and ends with a close square bracket. Inside text you may use the placeholders _#pos (1-based position), _#key (0-based position) and _#count (the number of values). Returns an empty string when values is empty or when value is not in the list. The comparison is not case-insensitive and parameters are not trimmed, so a leading or trailing space is significant. This command is not cached (it is re-evaluated on every render).
{ltrim:string:chars}String & Text Manipulation
Removes characters from the LEFT (the beginning) of a string. ltrim is the left-only counterpart of rtrim (right only) and trim (both ends), and it is the raw PHP ltrim. The second argument, chars, lists which characters to strip. It is a SET of single characters, not a prefix: ltrim removes any of those characters one at a time from the start until it meets a character that is not in the set. PHP range syntax such as a..z is allowed inside chars. Important trap: unlike trim, ltrim does NOT default to stripping whitespace. When you give no chars argument the set is empty and ltrim strips nothing, so the string comes back unchanged. To remove leading spaces you must pass a space (or the characters you want) as chars. Because AA does not pre-trim ltrim's arguments, the leading whitespace of the input is preserved for ltrim to act on. ltrim works on bytes and is not multibyte aware, so use it with ASCII character sets; for whitespace on both ends prefer trim, which is UTF aware.
Sends an e-mail when the first parameter (condition) is true. WARNING: this runs on every page render, so it can send mail on every page load - guard it with a condition. The command does nothing (returns an empty string) when condition is empty or 0, or when body is empty. Recipients (to) may be one e-mail, a JSON array of e-mails, or item ids of Reader records in slices related to the current site (matched by their e-mail field). Mail is always sent as HTML. cc and bcc are filtered to valid e-mails. from accepts a plain address or a Name address form. attachments is one URL, a JSON array of URLs, or a JSON object mapping display names to URLs. On success it returns the number of recipients queued; the first two mails per request are sent immediately and the rest are deferred. Source: AA_Stringexpand_Mail in stringexpand.php.
Emits an HTML form that, when a visitor submits it, sends an e-mail. The form posts via AJAX to mail.php, so no mail is sent at page render - only when someone submits it. Arguments in order: to (recipient address, required), subject, html (the form body markup, required), body (an optional message template; the placeholder is replaced with the collected field values, otherwise the body is just those values), ok (the confirmation text shown after submit), lang, and from. With no recipient the submit is aborted and nothing is sent.
{mailtemplate:template:to}Communication & Social
Sends one of the slice/site e-mail templates to the given address. The first argument is the numeric id of an e-mail template (the templates editable under the slice e-mail settings); it must belong to a slice in the same site as the rendering context, otherwise nothing is sent. The second argument is one e-mail address, or a JSON array of addresses. The current item is passed to the template, so item aliases (the _#ITEM_ID style placeholders) expand inside the template body and subject. Returns 1 when the mail was accepted for sending, and an empty string otherwise (no template, non-numeric or empty first argument, template not owned by a related slice, or empty recipient). Because an empty or non-numeric first argument sends nothing and returns empty, the command doubles as a conditional gate: feed it a template id only when you actually want to send. WARNING: this is a side effect. It runs on every page render, so an unguarded call sends mail every time the page is built. Guard it with a condition so it only fires on the intended request.
Renders an inline management panel for the items related to the current one - a small admin UI with action buttons (New, Delete, Settings, Edit, eXternal edit, Back, file upload) over a queried set of items. It is an editing-context expression: it emits admin HTML plus the AA Site-edit JavaScript, so it only does something for a logged-in editor on a page that carries the parent item. The classic use is a parent item that owns a set of child items (for example an article that owns its photos); the photo slice has a relation field pointing back to the article, and the manager lets the editor add, edit, reorder and delete those photos in place with instant redraw. Pass the related slice id, the relation field that points back to the parent, the parent item id (the current item when omitted), and the per-row template code. The code is rendered once per related item; if it contains the literal token _#actions the action buttons replace that token and your own row markup is used, otherwise a standard card wrapper is added. The mode parameter selects which buttons appear and may be given as flag letters or as a jsonasoc map of custom button labels. With edit_code the panel can also render an inline edit form for one chosen item. The expression never caches, so it reflects the live set on every request.
Evaluates an arithmetic expression and optionally formats the result as a number. Supported operators are + - * / % (modulo) and the bitwise operators & | ^ - note that ^ is bitwise XOR, NOT a power operator, so 2^10 returns 8, not 1024. Parentheses group sub-expressions. Before evaluation, spaces, tabs and commas are stripped and a comma is treated as a decimal point, so a stored European-style number such as "1 421,823" becomes 1421.823. To compute on slice data, nest a field-getter inside the expression. Only digits and the operators above are allowed: any letters (so function names like ceil or sqrt are NOT supported) make the expression invalid, which formats as 0; division by zero also yields 0. The parameters after the expression control the output: decimals sets the number of decimal places, or the literal value bool to return the translated Yes or No; dec_point and thousands_sep set the separators, or pass a locale code (FR, EN or US) in dec_point; emptytext is returned when the expression is empty or only whitespace.
{max:val1:val2:...}Math & Numeric
Returns the largest of the supplied numbers. Give the values two ways: colon-separated (max:12:45:8) or as a single JSON array (max:[12,45,8]) - both yield the same result. Every value is parsed as a number: a decimal comma is read as a decimal point (1,5 means 1.5), surrounding spaces are ignored, and a non-numeric value counts as 0. With no values the result is empty; with one value that value is returned unchanged. The output is the raw number with no rounding - wrap it in round or number_format if you need fixed decimals. Sibling commands: min (smallest), avg (average).
{md5:text}String & Text Manipulation
Returns the MD5 hash of text as a 32-character lowercase hexadecimal string - the AA counterpart of PHP hash('md5', ...). MD5 is a one-way fingerprint, not encryption: you cannot get the original text back from the hash, and the same input always produces the same 32 hex characters. The input is not trimmed, so leading and trailing spaces change the result. Empty input is valid and hashes to d41d8cd98f00b204e9800998ecf8427e. Typical uses are cache keys, deduplication keys, and compact opaque tokens (often nested, e.g. base64 of a packed md5, then cut short with substr). Do NOT use md5 to store passwords - it is cryptographically weak and AA has pwdcrypt for password hashing. This command only computes the hash; there is no inverse.
Renders a nested HTML navigation menu as a ul of li elements from a tree of items, designed for the Site module Pages slice. Pass the first-level item ids and a code template (usually a link such as _#MENULINK); menu builds the sub-levels by following a parent relation field. Each li gets id="menu-itemid" plus CSS classes inpath (an ancestor of the current page), active (the nearest such ancestor) and xidmatch (the current page itself), so you can style the open branch and the current item. The code is expanded per item with that item bound as the current context; if it resolves to an empty string the item and its whole submenu are skipped, which lets you hide items conditionally. Returns an empty string when code is empty or no valid item id is given. By default only the branch on the path to the current page is expanded; type all expands every level (use all+ to also emit a toggle button on items that have a submenu).
{min:val1:val2:...}Math & Numeric
Returns the smallest of the supplied numbers. Give the values either colon-separated (min:12:45:8) or as a single JSON array (min:[12,45,8]). Values are read as numbers, so a comma decimal like 1,5 is treated as 1.5 and surrounding spaces are ignored. With no values the result is empty; with one value that value is returned unchanged; with two or more the lowest is returned. Negative and decimal values are supported. The sibling commands are max (largest) and avg (average).
Reads a property of a slice (or any module) by its id. The first argument is the slice id; the second names the property. With no second argument, or any unrecognized name, it returns the slice name. Recognized properties: url (the slice configured URL, empty when unset), charset (the slice character encoding, such as windows-1250 or utf-8), site_ids and site_id (the dash-separated ids of the sites the slice belongs to), and any slice setting field whose id begins with an underscore. It is the modern replacement for the deprecated slice command and for the older alias slice_info syntax. Returns an empty string when the slice id is missing.
{nevercache:number}System & Utility
Base class for stringexpand functions that require no caching; functions extending this are never cached. Line 7942 in stringexpand.php.
{nevercachenotrim:...}System & Utility
Base class for stringexpand functions that require neither caching nor parameter trimming; used for PHP-mapped functions. Line 7956 in stringexpand.php.
Creates a new item by copying a template item and applying field/value pairs, then returns the new item ID. The first argument is the ID of the template item to copy (a 32-character item ID); the remaining arguments are field-id and value pairs that overwrite fields in the copy. If the first argument is empty or not a valid 32-character ID, newitem does nothing and returns an empty string (it warns No template id) - so an empty or invalid template is a safe no-op. The template must live in a slice related to the current slice (or the current slice itself); otherwise newitem warns No related slice found and returns empty. If the template ID is well-formed but matches no existing item, nothing is created and the result is empty. On success the copy is set active with an empty seo field and newitem returns its new ID. Single values are plain text; multi-values are written as JSON arrays. Append a plus sign to a field ID (field........+) to ADD the value instead of replacing it. Because newitem writes to the database it is never cached and it runs on every render - so any live template (such as a fixture in a related slice) would be cloned each time the page is shown. Use a found ID with ensureitem for lookup-or-create, and updateitem to change an existing item. newitem never updates an existing item.
{next:ids:current_id}Sorting & Filtering
Returns the id that comes immediately after current_id in a dash-separated list of ids. Use it to build a forward (Next) link on a detail page: feed a list of item ids and the id of the item being shown, and next gives you the id of the following item. The list is usually a query result from ids, but any dash-separated list works (the values need not be ids). Returns an empty string when current_id is the last entry, is not found in the list, or when either argument is empty - so a Next link naturally disappears on the final item. The list is split on the dash and empty segments are dropped, so a doubled or trailing dash can break the lookup; keep the separators clean. The mirror command previous returns the id before current_id.
{nocache:level}System & Utility
Turns off AA caching while a template renders. AA caches in two places - a page cache (the whole rendered page) and an internal stringexpand cache (the result of expanding aa-expressions). nocache returns nothing visible; it only flips cache switches as a side effect. The level argument is a bitfield - 1 turns off the page cache for the current page, 2 turns off the internal stringexpand cache, 3 turns off both. With no argument nocache behaves as level 2. The typical use is at the top of an email or notification template whose parameters are supplied by define, where a stale cached expansion would be wrong. nocache itself is never cached.
Returns the current date and time, formatted with a PHP date() pattern. The first argument format is the date() format string (for example Y-m-d H:i:s); leave it empty for the AA default format. The optional second argument timestamp is a Unix timestamp to format instead of the present moment - handy for re-formatting a stored time. Because the value changes every second, now is never cached and its examples are illustrative.
Returns the long ids of stored OBJECTS of a given type, filtered by conditions and ordered, as a delimiter-joined list. Objects live in AA general object store (the object_ tables), separate from slice items, so oids is the object-store counterpart of ids: feed its output to oitem to display the matching objects. The only object type AA currently supports is datovka (records of messages sent to Czech state data boxes by the datovka command), so type must be datovka; any other or unknown type returns an empty string. With no modules given, the search is scoped to the object types owned by the current site; pass slice or module ids to widen or narrow it. conds is a d- string of field-operator-value triplets over the object fields (for datovka these include state, conf, dbIDRecipient and the dm envelope fields); sort takes one or more object field names, ascending by default or descending with a trailing dash. restrict_ids intersects the search with a known id set, limit caps the count (a negative limit returns the last N), and delimiter joins the ids (default a dash, or json for a JSON array). With no matching object the result is an empty string. Note: always supply the type - calling oids with no arguments at all raises a PHP error rather than returning empty.
{oitem:type:ids:format:delim}JSON & Data Structures
Renders fields and aliases of objects from the AA object store (the object_ database tables), the way the item command renders rows of a slice. The first parameter is the object type; the only type the engine registers is datovka (Czech Data Box / Datova schranka messages), so in practice oitem reads datovka send-log objects. Give it dash-separated object ids - usually produced by the oids command - and a format string; for each object the format is expanded with that object aliases (_#STATE___, _#STATETXT, _#DATOVKA_, _#AA_NAME_, and more) and its field-getters such as stateTxt, state or datovka_id. The objects rendered are those owned by the current site or slice. Returns empty when the type is not datovka, when no ids match an object, or when the id list is empty. A well-formed id that has no matching object raises an error, so only feed ids that exist - the oids command is the safe source. It never sends a message and never writes - it only reads and displays.
{options:group:selected}UI Components & Interactive
Builds the HTML option elements for a select dropdown. The first parameter is the source list of choices; the second marks which choice is pre-selected. The source can be a constants group id (the choices come from that group), a JSON array of plain values like [1,2,5,7], or a JSON array of value-label pairs like [[1,"January"],[2,"Feb"]] where the first item of each pair is the option value and the second is its visible label. With a plain-value array the option carries no value attribute, so the value equals the visible text. The selected parameter accepts a single value or, for a multiple select, a JSON array of values such as ["7","8"]; every matching option gets the selected attribute. Place the result inside your own select element. An unknown group or an empty array produces no output. Pairs nicely with the sequence command, which can generate the value list (for example a range of years).
{ord:string}String & Text Manipulation
Returns the byte value of the first character of the given string, as a decimal number. It is the AA counterpart of the PHP ord function. The result is a single byte (0 to 255), not a Unicode code point: for a multi-byte UTF-8 character such as an a-acute the value is the first byte (195), not the code point 225. Only the first character is read; any further characters are ignored. An empty string returns 0. One trap on this engine: a sole argument of exactly the single character 0 is treated by the parser as no argument at all, so it also returns 0 rather than 48 - feed 00 or prefix the value if you need the real code of the digit zero. The inverse direction (a code back to a character) has no template command. Parameters are not trimmed, so a leading space is read as the space character (code 32).
{order:ids:expression:type}Data Access & Item Display
Sorts a fixed list of item ids by an AA expression evaluated for each item, and returns the ids dash-joined in the new order. Give the ids dash-separated (the output of {ids} or any id-producing command works); the expression is computed once per item (usually a field alias such as _#NUMBER__ or _#HEADLINE) and its result is that item sort key. Choose the sort type: numeric (the default), rnumeric, string, rstring, locale or rlocale - the r-variants reverse the direction. Numeric and string sorting differ sharply: as numbers 7 sorts before 14 before 100, but as strings 100 sorts before 14 before 7 (compared character by character). Sorting inside the database (as {ids} does) is faster and preferred; reach for order only when you already hold a concrete id list that must be re-sorted by a non-database key. Built on {aggregate} with the order action.
{packid:unpacked_id}ID & Type Operations
Converts an unpacked id - a 32-character hexadecimal string, the human-readable long form of an AA id - to its packed binary form, the 16-byte representation AA stores internally. It is the template counterpart of pack_id() and the inverse of unpack. The output is raw binary bytes, not printable text, so packid is almost never used on its own; the canonical pattern is to feed it into an encoder, as in base64 of packid of md5 of some string, then take a short slice with substr, to build a compact stable token such as a verification code or a deduplication key. Two edge cases: an empty input returns empty, and the literal 0 also returns empty, because PHP treats the string 0 as false. And because the template path is not binary-safe, any packed byte above 0x7F is replaced by a question mark, so the value only round-trips or base64-encodes faithfully when every byte stays in low ASCII; for ordinary ids and hashes the encoded result is stable within one install but is not the true binary encoding.
{pager:target}Navigation & SEO
The pager command renders a page scroller (Previous | 1 | 2 | 3 | Next) for the view it sits in. Use it in views that belong to a site built on the Site module - typically drop it into the views Bottom HTML field. It calls the router, so the page links carry the correct SEO-friendly URLs for each page. The pager must be issued inside a view; outside a paginated view it returns the error string "Err in pager - pager not valid without a view, or for group display". The optional target is a div id: when given, the page links reload that div via AJAX (handy for live searches) instead of reloading the whole page. With fewer than two pages it renders nothing.
{partdiv:name:vars:content}UI Components & Interactive
partdiv wraps a region of a page in a div that AA can repaint on its own when the data behind it changes. You give the part a unique name, list the slices and query-string variables it depends on, and the content to show. When a visitor edits one of those slices in place, or a listed query-string variable changes, AA re-renders just this part and swaps it into the page without a full reload - the div carries the class aa-partdiv plus the name and a data-aa-part hash that the editor JavaScript targets. The dependency hash is built from the name and the vars only, so two parts that share a name and vars share a hash. If name is empty, partdiv does nothing and returns the content unchanged, so the live-update feature is simply switched off. One trap: a colon inside content is read as a parameter separator and truncates the content, so write a literal colon as #: (for example Total#: 3).
Returns the chain of item ids from the root of a tree down to one item, as long ids joined by dashes (root first, the item itself last). It follows a relation field that points each item at its parent - the same field used to build a tree, a menu, or a Pages hierarchy. Use it for breadcrumbs and to know where an item sits in its tree. The second argument names the parent relation field and defaults to relation........ An item with no parent is its own one-element path. The id is not checked against the database: an id that matches no item is echoed straight back, and an empty first argument raises an error - always pass a real item id. See also tree, treestring, menu and sortstring, which walk the same relations.
Reads data from one or more polls in the Polls module and prints it. A poll here is a single question - one row in the polls table - not the whole poll module. poll_ids is one or more poll ids separated by a dash; for each id the expression is evaluated against that poll and the results are concatenated with nothing between them. The expression can be a plain column of the polls table - headline (the question text), publish_date, expiry_date, params, design_id, module_id, id, status_code - in which case the stored value is returned as-is. Anything else is treated as a normal AA expression evaluated in the poll context, where the poll aliases are available: _#QUESTION (the question text), _#POLL_ID_, _#MODULEID, _#PUB_DATE, _#EXP_DATE, _#PARAMS__ and _#EDITPOLL (an admin edit link). An empty id, a lone dash, whitespace, or an empty expression all yield empty output, so a missing lookup never breaks the page. Two cautions. First, the poll: command ships with the Polls module and is only registered once that module has run on the page - for example after a polls: call, or inside a poll design template where the poll is already in scope; used entirely on its own with nothing to load the module, poll: is left as literal text. Second, a poll id that does not exist on the current install raises a fatal error rather than returning empty, so only ever pass ids that exist. The typical use is inside a poll design to print the current poll question, or to wrap a poll column such as publish_date in a date: expression for formatting.
{polls:pid:params}Polls Module
Renders a poll from the Polls module on the page. The first argument pid is the id of the Polls MODULE the poll belongs to, not a single poll id. With only pid, AA shows the one newest active poll of that module (status published, inside the publish/expiry window) in its before-vote design: the question, each answer as a clickable vote link with a bar showing its current share, and the running totals. The second argument params is an optional URL-encoded query string (name=value pairs joined by ampersands) that overrides the defaults - the same names a poll vote link carries. poll_id renders one specific poll directly, skipping the date filter; design_id forces a named design; listlen and from page through several of the module polls; conds and sort filter and order them the AA way (a conds entry carrying an expiry_date key also turns off expiry filtering); convertfrom and convertto recode the output charset. A visitor votes by following an answer link, which calls polls again with poll_id and vote_id set - that records one vote, subject to the poll IP-lock and cookie settings, and then re-renders the poll in its after-vote design. WRITE WARNING: poll_id together with vote_id WRITES a vote on every render, so never hard-code that pair in a page-load template; the answer link is built by the design for the visitor to click (add novote to take the after-vote path without recording). polls is never cached and its output is live, install-specific markup, so on an install with no published polls it renders nothing.
{poll_share[:max]}Polls Module
Inside a poll answer template (Polls module), gives this answer share of all votes in its poll - round of votes-for-this-answer divided by total-votes, times max. The max parameter defaults to 100, so plain poll_share is a percentage (0-100); pass a max to scale the number, e.g. 200 to drive a results-bar width in pixels. Returns 0 when the poll has no votes. The answer alias _#ANS_PERC is just poll_share with the default max. It only produces a value in the answer section of a poll design, where the current item is one poll answer carrying its votes and poll_id; used anywhere else there is no answer to measure.
{poll_sum}Polls Module
Outputs the total number of votes cast in a poll - the sum of votes across every answer of the current poll. It takes no parameters and reads the poll from the item being rendered, so it only works inside the Polls module, in a poll design template where the current item is a poll answer (the answer carries the poll_id). The Polls module exposes the same value through the answer alias _#ANS_SUM_, whose definition is simply the poll_sum expression. Typical use is the result line under a finished poll, for example "Total votes: 1240". The value is the live SUM of the votes column in the polls_answer table for that poll, so it is runtime-dependent (it changes as people vote) and is never cached. Outside a poll design - on an ordinary page or in this reference - there is no current poll answer and the Polls expansion classes are not loaded, so the token is left unexpanded; all examples below are therefore marked illustrative.
{post_str_replace:search:replace}String & Text Manipulation
Reserves a search-and-replace pair to run on the whole finished page after every other expression has expanded - the deferred companion to str_replace. Important: this command is registered but its action is disabled in the engine, so right now it always expands to an empty string and replaces nothing; both parameters are accepted but ignored. To replace text today, use str_replace, which acts immediately on a third text argument. The deferred form exists so a replacement can reach text that other commands or included views generate later in the page, which str_replace cannot see. If a future release enables it, the call would still output nothing where written and the replacement would be applied once, last, across the entire output. Also grouped with String Manipulation.
{preg_match:pattern:subject:matched}String & Text Manipulation
Extracts text from a string using a PCRE regular expression. Runs PHP preg_match on the subject and returns one match. By default it returns the whole matched text (match 0); pass a number as the third parameter to return that parenthesised capture group instead (1 for the first group, 2 for the second, and so on). If the pattern does not match, or the requested group does not exist, the result is an empty string - no error. The subject is usually an item field getter such as the headline field. One thing to watch: the colon is the AA parameter separator, so neither the pattern nor the subject may contain a bare colon - match around it. This expression is never cached, and its parameters are not trimmed.
{previous:ids:current_id}Sorting & Filtering
Returns the id that comes immediately before current_id in a dash-separated list of ids. Use it to build a backward (Previous) link on a detail page: feed a list of item ids and the id of the item being shown, and previous gives you the id of the preceding item. The list is usually a query result from ids, but any dash-separated list works (the values need not be ids). Returns an empty string when current_id is the first entry, is not found in the list, or when either argument is empty - so a Previous link naturally disappears on the first item. The list is split on the dash and empty segments from a doubled or trailing dash are dropped, which can break the lookup; keep the separators clean. The mirror command next returns the id after current_id.
{protectmail:email:text}UI Components & Interactive
Hides an email address inside client-side JavaScript so spambots that scrape the page source never see a plain mailto address, while a human visitor still gets a normal clickable email link. On render the command emits an empty anchor tag plus a small script that assembles the mailto target and the visible link text in the browser at load time. The first parameter is the address to protect. The optional second parameter is the visible link text; if you omit it, the address itself is shown. If the first parameter is empty the command returns just the second parameter unchanged (or nothing). Because the markup is built in JavaScript, the link is invisible to visitors with JavaScript disabled and to plain-text or feed renderers. The output is never cached and embeds a random element id, so the exact HTML differs on every render - useful examples are illustrative rather than asserted.
{pwdcrypt:text}Security & Authentication
Hashes a plain-text password into the AA password storage format. It calls PHP password_hash with PASSWORD_DEFAULT, which on this install is bcrypt: a 60-character string that begins with $2y$. Each call uses a fresh random salt, so hashing the same input twice gives two different hashes. That is by design - it is what lets the stored hash resist precomputed-table attacks. Because the salt is random, the output is never cached and is not reproducible, so a pwdcrypt result can be checked only by AA login code (password_verify), not by re-hashing and comparing in a template. Typical use: produce the value for a Reader-slice user password field, or generate a hash to store in a user record.
{qrcode:text:size:margin}UI Components & Interactive
Renders the given text as a black-and-white QR code and returns it as a base64-encoded PNG data URI, ready to drop straight into the src attribute of an img tag. The text is encoded as UTF-8 with medium error correction (level M). If text is empty or only whitespace, it returns a 1x1 transparent GIF placeholder (data:image/gif;base64,...) instead of an error, so a missing value never breaks the page. Errors during image generation return the same placeholder. The image is generated inline (no file is written and no extra HTTP request is made), which keeps the QR code self-contained but makes the data URI long. size sets both width and height in pixels (default 300); margin sets the quiet-zone border in modules (default 2). To encode a payment QR code with an amount and account number, use qrpay instead.
Generates a Czech QR Platba (SPD-format) payment QR code as a base64-encoded PNG data URI. Drop the result into an img src attribute so a payer can scan it with a banking app and have the payment pre-filled. The account may be an IBAN or a Czech prefix-number/bankcode number, which is converted to IBAN automatically. Only account and amount are required; if either is empty the command returns an empty string and no image. Currency defaults to EUR and must be a supported three-letter code. Message and recipient name have diacritics stripped and are truncated (60 and 35 characters). Because the output is a rendered PNG, examples that produce a real code are illustrative, not asserted.
Reads a variable from the current HTTP request and returns its value as text. With a variable name it returns that GET, POST, or cookie parameter (it looks in _REQUEST, then a JSON request body, then the parsed query string); called bare as qs with no name it returns the entire raw query string. If the matched value is an array (a repeated parameter, or one written with [] brackets), it is joined with the delimiter you pass, or encoded as JSON when you pass none. This is a never-cached, request-dependent reader: its output changes with every request, so it is never part of the cached page. It does NOT escape its output - printing a raw qs value into an HTML page is an XSS risk. Use the sibling qss command, which is exactly safe applied to qs, whenever the value goes into HTML.
Returns a GET or POST parameter from the current request, HTML-encoded so it is safe to print into a page. qss is the safe twin of qs: it runs the same lookup and then passes the result through safe(), the same encoder that turns less-than, greater-than, ampersand and quotes into HTML entities. Use qss every time you echo a value that came from the URL or a submitted form into HTML - it stops a crafted parameter from injecting markup or script (a cross-site scripting attack). Reach for the raw qs only when the value is consumed by another command rather than written straight to the page. With no parameter name qss returns the whole query string (GET and POST together), encoded. Given a name it returns that one parameter; a name that is not present expands to an empty string. A bracketed posted name such as a form field array index is matched verbatim against the raw query string. When the parameter holds several values, a second delimiter argument joins them with that delimiter; without a delimiter the list is returned as JSON. qss is never cached - it is recomputed on every request - and its arguments are not whitespace-trimmed.
{quote:text}Encoding & Formatting
Backslash-escapes the apostrophes and backslashes in a string so the result can be placed inside a single-quoted string literal - for example a PHP array entry or an SQL fragment you build up in a template - without an apostrophe in the content closing the literal early. Each apostrophe becomes a backslash followed by the apostrophe, and each backslash becomes two backslashes; every other character is left as it is. The backslashes are doubled first and the apostrophes are escaped second, so a value that already contains a backslash stays correct. quote does not add the surrounding quotes for you and does not touch double quotes - it escapes the content that goes between single quotes, and is not a substitute for proper database parameter binding.
{rand:min:max}Math & Numeric
Returns a random integer between min and max, inclusive of both ends - the AA counterpart of PHP random_int(). Both bounds are required as integers; a non-numeric or empty bound is read as 0, and any trailing non-digit characters in a bound are dropped (so 7abc is read as 7). When min equals max the result is fixed at that single value. The output is never cached and is recomputed on every render, so it changes each time the page is built. Use it for picking a random item, rotating a banner, or jittering a cache key; for a random text token use randomstring instead.
{randomstring:len}System & Utility
Returns a random string of the given length. The character set is fixed: 57 characters - lowercase a to x without q, y and z (23 letters), uppercase A to X without Y and Z (24 letters), and the digits 0 to 9. It is not a full alphabet, so do not use the result where every letter or a specific case must be possible. The output is regenerated on every render (the command is never cached), so the same template yields a different value each time and cannot be a deterministic test on its own. The length is the only argument; with no length, a zero length, or a length that is not a whole number greater than zero, the result is the empty string. Beware: a non-numeric length such as the word abc triggers an effectively endless loop and exhausts memory, so always pass a literal positive integer. For a configurable generator with more options see the AA_Generator_Rnd class.
{range:intvalues}String & Text Manipulation
Rewrites a dash-separated list of integers into a compact, human-readable run list. It splits intvalues on the dash -, casts each piece to an integer, sorts them ascending, then collapses every run of consecutive integers into a from-to span. Single values are printed alone; the spans and singles are joined with , (comma and space). So 1-4-5-6 becomes 1, 4-6 and 2008-2009-2010-2011 becomes 2008-2011.

Order does not matter: the input is sorted first, so 5-1-2-4-3 still yields 1-5.

Gotchas: input order is ignored but duplicates are not removed — a repeated value breaks a run, so 2020-2020-2021-2022 gives 2020, 2020-2022. A literal 0 is dropped (the splitter discards empty and zero-like pieces), and any non-numeric piece counts as 0 and is likewise dropped. Empty input produces empty output.

The natural source of intvalues is a multi-value field flattened with the {@field:-} getter, for example {range:{@year............:-}}, which turns the years stored on an item into a tidy span.
Decodes a percent-encoded (URL-encoded) string back to its original text, following RFC 3986 exactly the way PHP rawurldecode does. Every %XX sequence becomes the byte it stands for: %20 becomes a space, %2F a slash, %3D an equals sign, %26 an ampersand. This is the inverse of rawurlencode and the correct decoder for modern URLs and query values. The one difference from the older urldecode command: a literal plus sign is left as a plus, NOT turned into a space (only %20 means space here). Invalid or incomplete sequences are passed through unchanged. The command never caches and never trims its input.
Percent-encodes a string for safe use inside a URL, following RFC 3986 (the AA counterpart of PHP rawurlencode). Every character except letters, digits and the four unreserved marks - dash, underscore, dot, tilde - is replaced by a percent sign and its two-digit hex code: a space becomes %20, an ampersand %26, an equals sign %3D, a slash %2F. This is the preferred URL-encoder; the older urlencode command encodes a space as a plus sign (+) and is deprecated. The input is not trimmed, so leading and trailing spaces are encoded too. Typical use is wrapping a field value or search term before placing it in a link href or query string.
{recompute:item_ids:fields_ids}Data Access & Item Display
Recomputes the computed fields on one or more items, as if those items had just been saved. A computed field is a slice field whose value is generated by an expression (its Computed insert/update function) - a counter, a slug, a cached total, an aggregate of related items. recompute re-runs those expressions and writes the fresh values back. It is most often placed inside another item own computed field, so that saving item A also refreshes a derived value on related item B (recompute a parent link count, refresh a cached sum, propagate a change down a relation). recompute produces no visible output: it returns an empty string and does its work as a side effect. The first argument is a dash-separated list of item long ids; empty entries and ids with no matching item are skipped. The optional second argument is a dash-separated list of field ids that limits the recompute to those fields - otherwise every computed field on the item is refreshed.
{redirect:url:code}Navigation & SEO
Sends the visitor straight to another URL the moment the engine reaches this command, then stops rendering the rest of the page. It is meant for Site-module spots and pages: use it to route a request to another branch, enforce a canonical domain, or bounce to a login page. The redirect only fires when the URL (first parameter) is non-empty - an empty URL is a no-op that prints nothing and lets the page continue, which is exactly why the conditional forms wrap the URL in ifset or ifeq with an empty true-branch. Always escape the colon in the scheme as http#:// (or https#://) so the engine does not read it as a parameter separator. The optional second parameter is the HTTP status code and defaults to 301 (Moved Permanently); pass 302 for a temporary redirect. The command itself never outputs any text.
{removeids:set1:set2}Sorting & Filtering
Set subtraction of two dash-separated id lists: returns set1 with every id that also appears in set2 removed, dash-separated. The remaining ids keep set1's original order. Built on array_diff over explode_ids, so each side is split on dashes, trimmed, and empty parts are dropped - leading, trailing or doubled dashes do not matter. An id listed in set2 is removed from set1 every time it occurs, but duplicate ids that are unique to set1 are kept (the command does not de-duplicate). It works on any dash-separated tokens, not only item ids. A common use is to take a few items out of a larger id list, for example all items a view returned except the current one. The companion command intersect keeps only the ids found in both lists.
{replace:search:replace:text}String & Text Manipulation
Replaces text using a regular expression. The first parameter is a PCRE pattern, the second is the replacement (it may use backreferences such as $1 or $2 to insert captured groups), and the third is the text to search. Internally it calls PHP preg_replace with backtick delimiters that AA supplies for you - you write only the bare pattern, never delimiters or modifiers, so the dangerous /e modifier can never be used. All three parameters are passed verbatim (not trimmed), and the result is never cached. Because parameters are split on the colon, a literal colon anywhere in the pattern or the text must be escaped as #: (for example a non-capturing group (?#:...) or a time like 10#:30). For plain, non-regex substitution where the search text may itself contain regex metacharacters, use str_replace instead.
require declares a page dependency - a JavaScript library, a CSS stylesheet, or a snippet of JS to run after a library loads. It prints nothing where you write it; instead it registers the dependency, and the matching generate:HEAD and generate:FOOT commands emit the deduplicated script and link tags in the page head and foot. AA tracks each dependency by a hash, so requiring the same library from ten views loads it once. The first parameter, libs, is either a single name or path, or a JSON array of several. A bare word with no slash and no .js or .css extension (aa-jslib, tippy, select2 with a version like select2@4) is a built-in library AA knows how to load. A value ending in .css, or containing .css? or /css? (Google Fonts), becomes a stylesheet link; you may append a media type such as print. Anything else with a slash or a .js extension becomes a script tag, and you may append defer, async, or an SRI integrity hash. The second parameter, script, is JavaScript run once the libraries are ready - use it to initialise the library you just required. The third parameter, position, set to FOOT, loads the libraries at the end of the body instead of the head. require needs generate:HEAD and generate:FOOT present in your site template to have any visible effect. See css for adding a block of CSS code.
{reverse:ids:limit}Sorting & Filtering
Reverses the order of a dash-separated list of ids and returns it joined again by dashes. It is the deterministic counterpart of shuffle, which uses the same code but randomises instead of reversing. Empty segments and segments that trim to nothing are dropped before reversing, and the string 0 is treated as empty and dropped too, so reverse of 0-1-2 is 2-1. Whitespace around each segment is trimmed. The optional limit keeps only the first N ids of the already-reversed list (it slices after the reverse, not before). Typical use is flipping the result of an ids or treeids list so the newest or last item comes first. Like shuffle it is never cached, but unlike shuffle its output is fully predictable.
Builds a rotator (a slideshow or carousel) that cycles through several content blocks in one spot on the page, switching automatically at a fixed interval. You give it a list of item ids and a small template; for each item it expands the template into one frame, stacks the frames in a div, shows the first, and emits a script that advances to the next frame on a timer. Inside the frame template, an alias such as _#HEADLINE resolves against the item being shown, not the surrounding page, so each frame can carry that item's own fields. The rotation is driven by AA_Rotator in the aa-jslib JavaScript library, which rotator requests automatically; hovering the rotator pauses it and moving away resumes it. The interval is given in milliseconds and defaults to 3000 (three seconds). speed sets how fast each switch animates (the jQuery duration: empty for an instant change, or slow or fast) and effect chooses how it switches (empty hides and shows the frame, fade cross-fades it). An optional sixth template, the li-code, builds a clickable list of switcher buttons under the frames so a visitor can jump to or hover over any frame. Items whose frame template expands to nothing are skipped, and an empty id list or a single frame produces no rotation. rotator reads live items and emits markup with a generated id, so its output is recomputed on every request rather than cached.
Fetches a remote RSS feed over HTTP and renders its items as HTML. The first parameter is the feed URL; because a colon is the AA parameter separator, write the scheme with a hashed colon - http#:// or https#:// - so the URL is not split. The optional second parameter caps how many items are shown, counted from the top of the feed; 0, empty, or a non-numeric value shows all items. The optional third parameter is an XSLT per-item template applied to each feed item: inside it use an attribute-value template like href="..." for attribute values and an xsl value-of element for text, where the RSS item children - title, link, description, pubDate, ... - are the available fields. With no template the feed is rendered as an unordered list of links: each item becomes a list element wrapping an anchor whose text is the item title and whose href is the item link. The feed is loaded with DomDocument and transformed by an XSLT processor (libxml/xsl, enabled by default on the supported PHP). An empty URL, an unreachable feed, or a transform that yields no output returns an empty string and logs a warning rather than raising an error. The feed is fetched on every render, so the output depends on the live remote source and the network; wrap the result in convert to change its encoding.
{rss:text:maxlen}Encoding & Formatting
Prepares text for output inside an RSS or other XML feed. It strips all HTML tags, turns each non-breaking space (the nbsp entity) into a normal space, escapes a bare ampersand that is followed by a space (so the feed stays well-formed XML), and trims leading and trailing whitespace. Give the optional second parameter to cut the cleaned result to that many characters. The classic use is wrapping a headline or abstract inside the title and description elements of a feed item.
{rtrim:string:chars}String & Text Manipulation
Strips characters from the RIGHT (end) of a string and returns the result. You name the characters to strip in the second argument, which is a SET of single characters, not a substring to match: chars set "as" strips any trailing a or s, in any order, until a character that is not in the set is reached. Only the right end is affected - the left side and the interior are left untouched. IMPORTANT: unlike PHP rtrim called with a single argument, {rtrim:text} with NO second argument strips NOTHING. The command always passes a second argument to PHP rtrim and it defaults to an empty string, and an empty character set removes no characters. To strip trailing whitespace you must list those characters yourself, for example {rtrim:text: } for spaces. Unlike most commands, rtrim does not pre-trim its own arguments, so trailing whitespace you pass in is preserved until you strip it. For the left end use ltrim; for both ends use trim.
{safe:text}Encoding & Formatting
Escapes the five HTML-special characters in text so it can be placed safely into HTML output: & becomes &, < becomes <, > becomes >, double quote becomes ", and single quote becomes '. This is AA wrapper around PHP htmlspecialchars (flags ENT_QUOTES and ENT_HTML5), so quotes of both kinds are escaped - making it safe inside attribute values and textarea content as well as in element text. It is a plain escape, not entity-aware: it does NOT skip text that is already encoded, so an existing & is turned into &amp;. Use it whenever you print untrusted or user-entered values into a page to prevent broken markup and HTML/script injection. The deprecated alias {htmlspecialchars:...} produces identical output; prefer {safe:...} in new templates.
{safexml:text}Encoding & Formatting
Escapes the five XML special characters in text so the result is safe to drop into an XML or RSS document, both inside an element and inside a quoted attribute. The ampersand becomes &amp;, the less-than sign becomes &lt;, the greater-than sign becomes &gt;, the double quote becomes &quot;, and the single quote (apostrophe) becomes &apos;. Every other character, including UTF-8 letters and accents, passes through unchanged. Empty input gives empty output. Use it whenever you place raw item content into a hand-built XML or RSS template, because AA does not auto-escape there. The companion command safe does the same job for HTML output (it differs mainly in charset and a few edge cases), and xmlfield wraps a value in a full XML element for you. One trap: AA splits parameters on the colon, so a value containing a colon must escape it as hash-colon or everything after the colon is dropped.
Renders a numeric page scroller (pagination bar) for the view it is written in. Place it in a view body field, such as Bottom HTML, of a view that splits its items into pages with a Listlen. It outputs one link per page, plus Previous and Next, so visitors can step through long listings. The four optional parameters wrap and decorate the page numbers: begin is printed before the numbers, end after them, add is inserted inside each page link tag (typically an attribute such as a class), and nopage is the text shown when the result fits on a single page and no scroller is needed. scroller is the older, view-based pager. Inside Site module views use pager instead, which asks the router for clean page URLs. When scroller is expanded outside a valid paginating view (for example on this reference page) it cannot find an itemview and returns the literal notice: Scroller not valid without a view, or for group display.
Looks up items by their SEO slug and returns their long ids. It searches the given slices for items whose seo............. field exactly equals the seo_string you pass, and returns the matching long ids joined by dashes (normally just one). This is the reverse of seoname, which builds a slug, and it is the mechanism behind friendly URLs: the site router takes a path like /expressions/seo2ids and uses seo2ids to find the item that page should show. Only slices that actually have a seo............. field are searched; others are skipped silently. An empty seo_string returns nothing. By default it looks in the approved bins (active, pending and expired); pass the bins argument to widen or narrow that. Feed the resulting id straight into item, view or count to read or render the matched item.
Generates a URL-safe SEO name (slug) from a string. It lowercases the text, transliterates accented letters to plain ASCII, replaces every character that is not a letter, digit, dash, underscore or dot with a dash, collapses repeated separators, and trims leading and trailing dashes and dots. The text About Us becomes about-us. A result longer than 124 characters is cut (without splitting a word where possible). Give a second argument to make the slug unique within one or more slices: pass all to cover every related slice, or a dash-separated list of slice IDs. When an active, expired, pending or holding item already uses the slug, a numeric suffix (-2, -3, and so on) is appended until it is unique. The optional third argument is the source character encoding used for transliteration; the default is utf-8.
Builds a sequence of values and returns them as a JSON array (the default) or joined by a delimiter you choose. Three sequence types: num (whole numbers from min to max), string (PHP character ranges such as A to E), and day (one timestamp per day across a date span). The result is meant to feed list commands - most often {options:...} to fill a year or letter dropdown, or {foreach:...} to loop. For num, both min and max must be plain non-negative whole numbers (a minus sign, decimal point, or letters yield an empty result); step defaults to 1, and the direction is chosen automatically (if min is greater than max the sequence counts down). An empty or unrecognised type, or a range that produces no values, returns an empty string.
{server:variable}System & Utility
Returns the value of a PHP $_SERVER variable as a string. Pass the variable name - for example REMOTE_ADDR for the visitor IP address, HTTP_HOST for the requested host name, or REQUEST_URI for the path and query string of the current request. The output is whatever the web server placed in that entry of the $_SERVER superglobal, so it depends entirely on the request and the server configuration and is never cached. If the named variable is not set, the result is an empty string. Common uses are reading the client address (often combined with gethostbyaddr for a reverse-DNS host name), detecting the current host to build absolute links or enforce a canonical domain, and inspecting the request path. Because the value reflects the live request, treat every server lookup as runtime-dependent - the same template can print different values for different visitors. See the PHP manual for the full list of $_SERVER keys.
{serverload}System & Utility
serverload prints the host machine current system load average - the one-minute figure the operating system reports (the same number shown as the first value by the Unix uptime and top tools). It is roughly how many processes were running or waiting to run on the CPU, averaged over the last minute, so a value near the number of CPU cores means the machine is busy but keeping up, and a much larger value means it is overloaded. The command takes no parameters and reads nothing from the database; it just asks the server for that single number and returns it as text. The result is never cached and is recomputed on every request, so it changes from one page render to the next and differs from server to server. On a platform that does not report a load average it returns 0. Use it only for diagnostics or an admin status page, never as the value of a test, because it is non-deterministic by nature.
{sessurl:url}HTTP & URL
Builds session-aware and state-aware URLs and form fields. With no argument it returns the current session id. With the keyword param it returns the session parameter ready to append to a query string (AA_Session=); with the keyword hidden it returns a ready-made hidden form input carrying the session. Given any other value, it treats that value as a URL and returns it with the current module context preserved (it appends module_id= when a module is active and the URL does not already carry one), otherwise the URL is returned unchanged. Session-related output (the bare id, param and hidden modes) is runtime-dependent and differs on every request.
{set:set_id}Sorting & Filtering
Returns the dash-joined item IDs of a saved Item Set. An Item Set is a named, reusable query stored per slice in Admin under Slice Admin, Sets of Items (the se_sets page): you give it a name, one or more slices, conditions, and a sort, and AA stores it as an object with its own 32-character ID. The set ID is shown in that admin form next to each set. set takes that object ID and runs the stored query, returning the matching IDs separated by dashes, in the set sort order, exactly the same id-list that the equivalent ids command would produce. Use it to keep a complex or shared selection in one named place instead of repeating the same conditions in many templates. The output is a plain id list, so feed it to count, foreach, loop, view, or any command that consumes dash-separated IDs. An empty or unknown set ID returns an empty string. Active items only, unless the set itself is configured for other bins.
{setsecret:username:password:code2fa}Security & Authentication
Generates a Google Authenticator two-factor (2FA) secret for the currently logged-in user, after re-checking that user's own credentials. It always returns an empty string (it produces no template output). Parameters in order: username, password, code2fa (the current 6-digit authenticator code). The command does nothing unless username and password are both non-empty, the credentials authenticate successfully, and the authenticated user is the SAME user who is already logged in - so a session can only re-confirm its own account, never set a secret for someone else. WARNING: in the current engine build this command is experimental and incomplete - on success it generates a secret and writes diagnostic text to the server output, but it does NOT persist the secret anywhere, so it has no lasting effect. To actually store a 2FA secret for a reader, use a slice field configured with the AA_2FASECRET field writer (see Reader Management / two-factor setup), not this expression. Because it depends on the live session and a real authenticator code, every call is runtime-dependent (never cached) and cannot be a deterministic test.
{shorten:text:length:mode:add}String & Text Manipulation
Shortens a text to at most length characters and always strips HTML tags first. If the text already fits within length, it is returned unchanged (HTML kept); otherwise the HTML is removed and the result is cut to length. The mode parameter chooses where to cut: 0 cuts at the exact length, 1 tries to stop at the end of a paragraph or sentence, 2 (the default) is smart - it behaves like 0 for length under 50 and like 1 for length 50 or more, and 3 keeps the start and the end of the text and joins them with an ellipsis in the middle. The add text is appended only when the text was actually shortened, so the result can be up to length plus add long. Parameters are not trimmed, so a leading space in add (for example " ...") is preserved.
{shuffle:ids:limit}Sorting & Filtering
Randomly reorders a dash-separated list of values and joins them back with dashes. Each segment is trimmed; empty segments and a bare zero are dropped before shuffling (the same list parsing as ids, reverse and sort). With the optional limit it returns only the first N values of the shuffled list, so it doubles as a random picker. The order is random on every render and the command is never cached, so its raw output is non-deterministic; wrap it in count or sort when you need a stable, testable result. Typical use: randomise a set of item ids before passing them to a view, or pick one random id with a limit of 1.
{site:site_ids:property}System & Utility
Lists the slices that belong to one or more sites. A site is a Site-module group that ties slices together (shared navigation, friendly URLs, cross-slice search). The first argument is one or more site ids, dash-separated; the second argument is the property to read. Only the property modules is recognized: it returns the dash-separated ids of every ACTIVE slice related to those sites. Any other property, a missing property, an empty site id, or an id that is not a site returns an empty string. The site itself is not included in the list. The most common use is feeding this list into another command, for example count to count the slices in a site, ifin to test whether a given slice belongs to a site, or ids to search across every slice of a site at once. AA core uses it together with modulefield to compute seo names and to scope backlink searches to all sibling slices of an item.
{siteitem:seo_string:text}Data Access & Item Display
Looks up an item by its SEO-string name within the current site module and prints it. With one argument it prints the item fulltext; with a second argument that text is expanded in the found item context (so _#ALIAS field-getters resolve against that item). Resolution searches only the current (approved/active) items of the current site, matching the seo............. field, and uses the first match. An empty, missing, or unresolvable name returns an empty string; a present second argument that is empty also returns empty. This is the name-based counterpart to id-based item access: it lets templates pull a known content block (for example a config snippet stored as an item with a stable SEO name such as cfg-title or body-class-style) anywhere on the site without hardcoding an item id.
{sitespot:spot_id}System & Utility
Returns the rendered HTML of a Site module spot - a named page-fragment (header, footer, sidebar, body block) - identified by its numeric spot ID, within the current site. The spot content is expanded through the template engine before it is returned. Output is produced only while a Site module page is being rendered, where the current site is known; on a plain view or slice render the site is not set and sitespot returns an empty string. The spot ID must be all digits: a non-numeric or empty ID yields an empty string and never errors. Spot 1 is the site root (start) spot. Use sitespot to reuse one shared spot inside another spot or inside item content.
Builds a legacy Skype "My status" button: a script tag plus a linked status image for a given Skype name. The first parameter is the Skype name; the rest set the link action, the image style, and the alt/title text. With an empty name it expands to nothing. Note: the image and script it points at (mystatus.skype.com, download.skype.com) were retired by Skype years ago, so the button no longer shows a live status - the command still emits the same markup but the image will not load. Treat it as historical. The Skype name and the action and style values are URL-encoded; the message is HTML-escaped.
{slice:property}System & Utility
Returns a property of the current slice - the slice that the rendering item or view belongs to. Outside an item context it uses the active slice_id; if no slice is in scope it returns an empty string. With no property given, or any unrecognized property name, it returns the slice name. Supported properties: name (the slice title), url (the slice public URL setting, stored as slice_url), site_ids (dash-joined id(s) of the site module(s) the slice belongs to; site_id is an older single-value alias), charset (the slice character set). A property that starts with an underscore reads that slice setting value. This command takes no slice id - it always reads the current slice. To read a named slice by its id, use the preferred modulefield:slice_id:property, which this command is a thin wrapper over.
{slice_comments:slice_id}Communication & Social
Returns the total number of discussion comments posted across all items in one slice. It sums the disc_count column of every item in the slice. disc_count is the per-item comment total kept by the discussion module - it counts every comment, including hidden or unapproved ones, not only the visible ones. The single argument is the 32-character slice id. A slice with no comments, an empty slice id, or an unknown slice id all return 0. This is a live, mutable count: it changes whenever a comment is added, removed, hidden, or approved, so it is not a fixed value. It is a specialized, rarely used command (the source marks it as not yet in regular use).
Sorts a delimited list of values and returns it as a string joined by the same delimiter. Supports six sort orders (numeric ascending is the default), optional de-duplication, optional truncation to the first N values, and an optional value to append when truncating. Sorting is value-based, so to sort items by a field, build the value list with another command first.
{sortable:selector:options}UI Components & Interactive
Turns an HTML table into one the visitor can sort by clicking its column headers, entirely in the browser. The expression itself prints nothing - it loads the small plain.sortable JavaScript library plus its stylesheet and runs the sorter against the tables matching selector. selector is a CSS selector and defaults to table.sortable, so giving your table the class sortable and writing the bare expression is enough; pass a selector like #prices or table.report to target specific tables. For the library to be injected the site module page must contain the generate HEAD and generate FOOT markers (those emit the queued scripts and styles). A second options argument appears in the signature for forward compatibility but the current version ignores it - sorting uses the library defaults. Because the work happens client-side, sorting reorders only the rows already on the page; it does not re-query the database or change which items a view selects.
{sortid:number}Sorting & Filtering
Builds a text sort key from a number so that numbers sort correctly when compared as plain text. In a plain alphabetical (lexicographic) sort, "10" comes before "9" because the engine compares character by character and "1" is less than "9". The sortid command fixes that by prefixing each number with a single letter that encodes its length: a 1-digit number gets "B", a 2-digit number gets "C", a 4-digit number gets "E", and so on (the letter is chr(65 + number of characters), so an empty input gives just "A"). Shorter numbers therefore always sort before longer ones, and numbers of the same length sort by value. So 1, 10 and 89 become B1, C10 and C89, which sort in the right numeric order as text. This is the per-level building block that the sortstring command uses to order an item tree.
Builds a single, lexically sortable key for an item within its relation tree. It walks the branch from the item up to the tree root (via the relation field, same traversal as path and tree), reverses it to root-first order, takes each step ordering value (the short item id by default, or the value of the expression you supply), and encodes each value with the sortid scheme - a length-prefix letter (A for 0 chars, B for 1, C for 2, ...) followed by the value - then concatenates them. Because the prefix encodes length first, the resulting strings sort the same way the numbers/values would sort numerically, so ordering rows by this key reproduces the tree order. An unresolved or empty id yields the bare prefix A (sortid of an empty string). The default relation field is relation........ . Source: AA_Stringexpand_Sortstring in stringexpand.php; cacheable (deterministic).
{specialstring:type}Misc / Specialized
Returns a fixed special string selected by name. The only recognized name is BOM, which returns the three-byte UTF-8 Byte Order Mark (the bytes EF BB BF). Any other name, or an empty argument, returns an empty string. The typical use is to prepend the BOM at the very start of an exported feed, CSV, or other download so that consumers reliably detect UTF-8 encoding. The BOM bytes are not visible characters, so the output looks empty on screen even though three bytes are produced.
{string2id:string}ID & Type Operations
Converts any string into an AA item id - a 32-character lowercase hexadecimal long (unpacked) id. It is the template counterpart of AA core string2id() function. The id is built from the MD5 hash of the input, so the same string always produces the same id (the mapping is deterministic, never random). Use it to derive a stable, collision-resistant id from arbitrary text, or to compare two strings by comparing their ids. AA uses it internally to mint item ids for fed items, by hashing the source item id together with the target slice id. The hash is sanitized for AA binary id packing: if the raw MD5 would contain the byte pair 00 (a string terminator), 27 (a packed quote), or 20 (a space, which MySQL trims) at position 30, the function appends a space to the input and re-hashes until the result is safe - so for some inputs the id is not the plain MD5, yet it is still fully deterministic. One parser trap: a sole argument of the single character 0 is read as no argument, so it hashes the empty string; pass 00 to hash a literal zero.
{striptags:string:allowed_tags}String & Text Manipulation
Removes HTML and PHP tags from a string and returns the plain text between them. It is the AA counterpart of the PHP strip_tags function. The first argument is the text to clean; an optional second argument lists tags to keep (for example b and i in angle brackets), and every tag not on that list is removed. The text inside removed tags is always kept. Typical use is flattening rich-text into a plain-text field, such as an item abstract written into a calendar or RSS feed.
{strlen:string}String & Text Manipulation
Returns the length of a string, the AA counterpart of PHP strlen. The result is the number of BYTES, not characters - so a multi-byte UTF-8 character (an accented letter, an em-dash, an emoji) counts as the 2, 3 or 4 bytes it occupies, not as one. Whitespace counts and the argument is NOT trimmed, so leading and trailing spaces add to the length. A missing or empty argument returns 0. Use it to test a field for emptiness, enforce a length limit, or drive a condition on content.
{strtolower:string}String & Text Manipulation
Converts a string to lowercase and returns it. Letters change case; digits, spaces, and punctuation are left unchanged. On a UTF-8 install the lowercasing is Unicode-aware, so accented and non-Latin letters are lowercased too. The argument is not trimmed - any leading or trailing whitespace is kept. This is the template counterpart of PHP strtolower (mb_strtolower on a UTF-8 install). The mirror command strtoupper does the opposite.
{strtoupper:string}String & Text Manipulation
Converts a string to upper case. This is the AA counterpart of the PHP strtoupper function. On a UTF-8 install it is multibyte-aware, so accented letters are upper-cased correctly (for example a-acute becomes A-acute); on a non-UTF-8 install only the ASCII letters a-z are converted. Digits, spaces and punctuation pass through unchanged, and a string that is already upper case comes back the same. The input is not trimmed, so leading and trailing spaces are preserved. With no argument the result is an empty string. Use it for all-caps headings, badge and tag labels, acronyms, and case-insensitive comparisons.
{str_repeat:string:times}String & Text Manipulation
Repeats a string a given number of times. The AA counterpart of PHP str_repeat: the first parameter is the text to repeat, the second is how many times to repeat it. The count is read as a whole number, so a non-numeric count counts as zero (empty output) and a count with a leading number like 3px is read as 3. A count of zero returns an empty string. A negative count is not allowed and raises an error, so guard against negative values before you call it. Parameters are not trimmed, so leading or trailing spaces inside the text are kept. Typical uses: drawing a divider line, padding a value, or building a fixed-width spacer.
{str_replace:search:replace:text}String & Text Manipulation
Replaces text, the AA counterpart of the PHP str_replace function. The arguments are, in order, what to search for, what to replace it with, and the text to search in. With plain strings it swaps one term for another; pass a JSON array of strings as the search to replace several terms at once, and a JSON array as the replacement to map each search term to its own replacement by position. Replacing with an empty value deletes the match. Matching is case-sensitive, and the arguments are not trimmed, so spaces in the search and replacement are significant. For pattern-based replacement use replace instead.
{substr:string:start:length:add}String & Text Manipulation
Returns part of a string. Give it the input text, a start position (0-based; a negative value counts back from the end), an optional length (a negative length cuts that many characters off the end instead), and an optional add string. The add string is appended only when the result is actually shorter than the input - which makes this the standard way to shorten a headline or teaser and show an ellipsis. Counts characters in a UTF-8 aware way, not bytes. With no length the rest of the string is returned.
Tests a condition value against a list of cases and returns the result of the first matching case. Each case is a regular expression matched against the condition with preg_match, so a case succeeds when its pattern is found anywhere in the condition - anchor with ^ and $ for an exact match. Cases and results alternate after the condition. The first matching case wins and its result is returned; if no case matches, the optional last parameter (an unpaired trailing value) is returned as the default. An empty case matches any condition, so it works as a catch-all else branch. In the chosen result, _#1 is replaced by the condition value. The colon separates parameters, so to keep a literal colon inside a case or result escape it as #: (the same trick that protects a URL as http#://). A condition that itself contains colons can use the parentheses form switch(condition) - the first close-parenthesis ends the condition - after which the cases and results follow as usual. switch is never cached: it is re-evaluated on every request.
{table:id:cmd:r:c:val:param}JSON & Data Structures
Builds a small two-dimensional table in memory during one page render and reads values back out. The first argument names the table instance: every table: call sharing that id works on the same table. The second argument is the command - set stores a value at a row and column, get reads it back, addset adds a number to a cell, joinset appends to a cell with a delimiter, sum totals a column over all rows, and print renders the whole table as HTML. A cell can hold several named attributes (the 6th argument of set); get and sum take an output template where _#1 is the cell value or column total and _#attr pulls a named attribute. The table is not persisted - it exists only for the current render, and is never cached. Experimental: the author marks it as likely to be replaced by the array: command, so prefer array: for new templates.
{tableexport:selector}UI Components & Interactive
Adds an "Export to XLSX" button to every HTML table on the page that matches the CSS selector. It loads the required JavaScript libraries (the TableExport library plus its dependencies) and registers an init script - it prints nothing into the page itself, so its output is always empty. The button lets a visitor download the table as an Excel .xlsx file. Two requirements: the table must carry a class or id that the selector targets, and the Site module template must use generate:HEAD and generate:FOOT so the libraries get emitted. The underlying JavaScript library may be swapped for an equivalent one in the future, but the command stays functional. Class: AA_Stringexpand_Tableexport.
Builds an HTML tag cloud (an unordered list with class tagcloud) from a set of items, weighting each tag by how often it is used. Every item becomes one list element whose CSS class, tagcloud1 through tagcloud8, encodes its rank: tagcloud1 is the most-used tag (style it largest), tagcloud8 the least. You supply the tag items as a dash-separated id list (commonly built with the ids expression), an optional maximum number of tags to show (the highest-count tags win), the AA expression rendered as each tag label, and the field or expression that yields each tag usage count. The default label alias _#HEADLINK is empty on most slices, so set your own (for example _#HEADLINE). Tags are listed in input order; only the class number is ranked by count, so the busiest tag is not necessarily first. The command outputs no styling itself - size the eight classes in your own CSS.
{text2html:text:type}Encoding & Formatting
Converts a plain-text string into HTML. In the default mode it does three things: it HTML-escapes the text (so a less-than sign becomes the entity and the result is safe to drop into a page), it turns bare http and https URLs and e-mail addresses into clickable links (e-mail addresses get a mailto link with the at-sign obfuscated), it converts newlines to line breaks, and a double space becomes a wide space. Pass the second parameter as CZHTML to switch to Czech typography mode instead: it does NOT escape or linkify, it only inserts non-breaking spaces after Czech one-letter prepositions (a, i, o, s, z, k, v and their capitals) and before units and after common abbreviations and academic titles, leaving any HTML tags in the text untouched. The command was written mainly to build the HTML body of e-mails sent by the mail commands from a text field. It does not trim its input. With an empty first parameter it returns an empty string.
Converts a textual date into a Unix timestamp - the number of seconds since 1970-01-01 00:00:00 UTC. It is a thin wrapper around PHP strtotime, so it understands ISO dates (2008-07-01), full datetime strings (2008-07-01 14:30), compact ISO basic form (20080701t223807), and relative English phrases (today, next Monday, +1 day). The result is the integer you would feed to date-and-time commands such as date, daterange and datediff, all of which expect a Unix timestamp. The parameter is parsed in the server timezone (Europe/Prague on this install). Two traps worth knowing: an empty parameter and any text strtotime cannot parse both return an empty string (not 0), and a bare integer such as 1700000000 is NOT recognised as an already-made timestamp - it returns empty; prefix it with an at-sign, as in @1700000000, to force strtotime to read it as a Unix timestamp. Relative phrases are evaluated against the current clock, so their output changes over time.
{tooltip:element:html}UI Components & Interactive
Attaches a rich pop-up tooltip to a page element. The element is named by its id or by a CSS selector; the tooltip body is HTML. Output of the command itself is always empty - it works as a side effect, registering the Tippy.js library and an init call for the page. The visible tooltip therefore appears only when the page also emits the loaded libraries, which on a Site module means a generate HEAD and a generate FOOT in the template. The selector rule: if the first argument contains only letters, digits, underscore or hyphen it is treated as an element id (a hash is prepended); any other character (a leading dot or hash, a space, a bracket) means it is used verbatim as a CSS selector. The underlying library may be swapped for an equivalent one later, so do not rely on Tippy specifics; the command stays functional.
{tr:text:param1:...}Misc / Specialized
Looks up a string in the site translation slice and returns its current-language version. If no translation slice is configured for the site, or the string has no entry yet, tr returns the text unchanged - and, when a slice is configured, quietly inserts the untranslated string so it can be translated later. The text may carry numbered placeholders _#1, _#2, ... that following parameters fill in, which keeps a whole phrase together for translators instead of splitting it around the inserted value. Placeholders are substituted from the highest number down, so _#10 is replaced before _#1 and they do not collide. Empty text yields an empty string. Translation lookup is configuration dependent, so its result varies per install; placeholder substitution is deterministic.
Returns the long ids of all items in the tree under a root item, found by following a relation field from parent to child. The root id is always included, then each item below it, walked depth-first and joined with a dash. Pass several root ids (dash-separated) to walk more than one tree at once; the combined list is de-duplicated. The result is a plain id list you feed into view or item to render a section together with its sub-pages, or into count to size a branch. The default relation field is relation........ ; set the third parameter to 1 for a reverse tree (the field points child to parent), and the fifth to restrict the walk to listed slices. Related: treestring returns the same tree as a nested string, path returns the ids from the root down to one item, and menu builds an HTML navigation menu.
Builds a text representation of an item tree rooted at the given item and returns it as a string of long item IDs. Children are wrapped in parentheses after their parent and siblings are joined with a hyphen, so a parent A with children B and C prints as A(B-C), and nesting deepens with each level: A(B(D)-C). An item with no children prints as just its own ID. The tree is walked through a relation field: each item points (by default through the relation........ field) at its child items; set reverse to 1 to walk the opposite direction (each item points at its parent), which builds the subtree of descendants under the starting item. The output is not meant to be read directly - it is the tree string that {itree:...} consumes to render a nested menu, breadcrumb, or sitemap. Pass several root IDs joined with a hyphen to get several trees in one string. Only active items in the listed slices are included; IDs that match no active item are echoed back unchanged. treestring is cacheable, so its output is deterministic for a given tree.
{trim:string:chars}String & Text Manipulation
Strips characters from both ends of a string and returns the result. With one argument it removes whitespace (spaces, tabs, newlines, and other Unicode whitespace) from the start and end. Give a second argument to strip a specific set of characters instead.
{twitter}Communication & Social
Renders a Twitter/X "Tweet" share button - the standard anchor that the Twitter/X widgets script turns into a live share button on the current page. Takes no parameters and always emits the same fixed markup; it does not insert a specific URL or text (the widget shares the page it loads on). As a side effect it queues the platform widgets script (platform.twitter.com/widgets.js) to be loaded; the script tag is only emitted where the page template has a generate:HEAD (or generate:FOOT) spot, so without that spot the button stays an inert plain link. Output is raw HTML, so examples are illustrative rather than asserted. Note: X (formerly Twitter) has changed its widget platform since this command was written; verify the button still activates on your install.
{ucfirst:string}String & Text Manipulation
Uppercases the first character of a string and returns the result. Only the first character is changed - the rest of the string is left exactly as it is, it is NOT lowercased. This is the counterpart of the PHP function ucfirst. Use it to turn a stored lowercase value (a status key, a tag, a category slug) into a display label with an initial capital, for example draft becomes Draft. Related commands: ucwords uppercases the first letter of every word, lcfirst lowercases the first letter, strtolower and strtoupper change the whole string. Combine with strtolower when you want the rest of the text lowered before capitalizing the first letter. On a UTF-8 install the first character is uppercased with multibyte awareness, so a leading accented letter (an a-acute becomes A-acute) is handled correctly. The argument is not trimmed: a leading space is treated as the first character and stays a space.
{ucwords:string}String & Text Manipulation
Uppercases the first character of every word in a string, leaving the rest of each word untouched - the AA wrapper around PHP ucwords(). Words are separated by whitespace only (spaces, tabs, newlines), so text joined by a hyphen or an apostrophe counts as a single word and only its very first letter is capitalized. It does not lowercase the other letters, so an already-uppercase word stays uppercase; pipe the text through strtolower first if you want clean Title Case. It is ASCII-only: accented first letters (an e-acute, for example) are left unchanged - use ucfirst, which is Unicode-aware, when the first letter may be accented. The input is not trimmed.
{unique:ids:delimiter}Sorting & Filtering
Removes duplicate values from a delimited list, keeping the first occurrence of each and preserving order. The input is split on the delimiter (a single dash by default), empty or whitespace-only parts are dropped, and the remaining values are rejoined with the same delimiter. If the input starts with a left square bracket it is treated as a JSON array instead: duplicates are removed and a re-indexed JSON array is returned. Comparison is exact, so values that differ only in surrounding spaces count as different. Commonly wrapped around a collected list of item ids or field values to de-duplicate before counting or displaying them.
{unpack:string}ID & Type Operations
Converts a packed (binary) string to its hexadecimal text form - the AA counterpart of PHP bin2hex() and the AA function unpack_id(). AA historically stores item IDs as 16 raw bytes to save space; unpack turns such a packed value back into the readable 32-character hexadecimal long ID. More generally it hex-encodes the bytes of any string: each input byte becomes two lowercase hex digits. The input is NOT trimmed, so leading or trailing spaces are encoded too (a space becomes 20). Edge case: a single 0 passed as the whole argument is read by AA as an empty argument and yields empty output (not the hex 30). Empty input also yields empty output. The inverse operation is packid - but note that round-tripping arbitrary binary through templates is lossy (non-printable bytes degrade to a question mark), so use packid/unpack in templates only for printable data.
{updateitem:...}Data Access & Item Display
Updates one or more fields of an existing item, given its long (32-character) item id. This is the write companion to newitem (which creates a new item from a template) and ensureitem (which finds an item or creates it). updateitem changes an item that already exists. Pass the item id first, then field/value pairs: a 16-character field id followed by the new value. To replace the field value give the value directly; to add another value to a multi-value field, append a plus sign to the field id. A value may be a single scalar, or a JSON array for several values at once. Security: this only writes on slices whose Allow anonymous editing of items setting is All items (or Only by Planned tasks when run from cron). On any other slice updateitem makes no change and returns nothing. The plan is to honour per-field permissions in the future. Conditional update: if the item id is empty or not a valid id, nothing is updated. This lets you drive an update from a lookup - feed an ids lookup as the id and the update only fires when the lookup matches. Returns the item id when an item was updated, and nothing otherwise. On this Czech-localized demo install the test-data slice forbids anonymous editing, so the examples below return an empty result and never change the fixture; the field-changing forms are shown as illustrative.
{url2bin:data}Encoding & Formatting
Decodes a Base64url-encoded string back to its original bytes. It is the inverse of bin2url: it replaces - with + and _ with /, re-adds the stripped = padding, then runs standard Base64 decoding. Use it to read values that were packed into a URL path, query string, or filename with bin2url (RFC 4648 section 5). Decoding is tolerant - missing padding and a mixed +/_ and standard +/ alphabet both decode correctly. Undecodable input yields empty output.
Decodes a URL-encoded (percent-encoded) string back to its original text, the way PHP urldecode does for query strings and HTML form data. Every %XX sequence becomes the byte it stands for: %20 becomes a space, %2F a slash, %3D an equals sign, %26 an ampersand, %25 a percent sign. The one trait that sets it apart from rawurldecode: a literal plus sign is decoded to a SPACE (the application/x-www-form-urlencoded rule), so a real plus must arrive as %2B. Invalid or incomplete sequences such as a lone percent are passed through unchanged. For modern RFC 3986 URLs where a plus must stay a plus, use rawurldecode instead. This command never caches its result and never trims its input.
URL-encodes a string for safe use in a URL - the counterpart of PHP urlencode(). Spaces become plus signs and every character outside A-Z a-z 0-9 and the set - _ . * is percent-encoded (for example & becomes %26). This is form encoding (application/x-www-form-urlencoded). Deprecated: prefer rawurlencode, which is RFC 3986 compliant and encodes a space as %20. Takes one argument; a literal colon inside it must be escaped as #: so it is not read as a parameter separator.
{user:field}Security & Authentication
Returns information about the currently logged-in user. With no parameter it returns the login username (a quick lookup that does not touch the database). The keyword password returns the plain-text password, but only when the request used HTTP Basic auth. The keywords role and permission both return the user permission role for the current slice: super, administrator, editor, author, or undefined. The keyword id returns the long item id of the user Reader record. Any other value is read as a field id (or a _#ALIAS) from the logged-in user Reader item, so user headline........ returns that field, typically the display name. Because the result depends on who is logged in, any view that uses this command is never cached, and on a public page with nobody logged in the user-specific values are empty. Note: a bare username read returns nothing in an anonymous context; prefer a field read such as user headline........ for display. For a cacheable variant that reads the same Reader item see xuser; to look up another user by id see userinfo.
{userinfo:user:property}Security & Authentication
Looks up information about an AA user from a stored user id - the kind of id AA keeps in the posted_by and edited_by fields of every item. The first parameter is that user id; the optional second parameter selects what to return. With no second parameter (or any value other than logintime or logintimes) it returns the user display name. The special user id 9999999999 is the anonymous user and always returns the name anonym. An empty user id returns an empty string. Use it on item-display templates to turn the numeric author or editor id into a readable name, for example by feeding the posted_by field into it.
{utfnormalize:text}String & Text Manipulation
Normalises a UTF-8 string to Unicode Normalization Form C (NFC): it composes a base letter followed by combining diacritical marks into the single precomposed character, so two byte-sequences that look identical become identical. For example the letter a followed by a combining acute accent becomes the one-character a-acute. Plain ASCII text and text that is already in NFC pass through unchanged. Use it to canonicalise text before comparing, deduplicating, sorting, or storing it, so visually equal strings match. It always uses form C; there is no parameter to pick a different form. Internally it calls PHP Normalizer::normalize on the input.
{validate}System & Utility
Runs the slice field-validation rules against the current item and returns the result as JSON. When every field is valid the result is an empty array, written []. Otherwise it is a JSON object keyed by field id, where each value is a pair of error code and human-readable message; the message is localized to the install language. The check covers all fields of the slice, not only the ones shown on the edit form. This command takes no parameters and reads the item it is rendered on, so it belongs in an item or form context - for example a confirmation view shown after a save. Rendered outside any item it returns an empty string. It only reads; it never changes or stores anything.
{var:name:expression}Views & Display
Prints a named expression. With one parameter it prints a variable previously stored with define:name on the same page. With two parameters it both stores the second parameter under name AND prints it, so the value can be reused later by var:name. Variables live for the duration of a single page render only and are evaluated in source order, so the defining call must run before any var:name that reads it. Reading a name that was never defined prints nothing. The main use is to compute an expensive value once (a count, an aggregate, a lookup) and reuse it in several places, and to pass values between nested views. Note the parameterized form var:name:arg1:arg2 from older docs is not implemented; the second parameter is stored verbatim as the value, it is not a template argument.
{version:type}System & Utility
Returns information about the running ActionApps installation - its version, the SVN revision, or the PHP version. The optional type argument selects what to return: with no argument (or an unknown value) it returns the full descriptive string. Because the output reflects the live install (and the full form includes the visitor IP), it is never cached and is install- and request-dependent, not a fixed value. Typical use is a footer or an admin diagnostics line that shows which AA build is running.

Renders a stored AA view and returns its HTML output. This is the main way to embed one slice listing inside another template, page, e-mail, or even inside another view.

The view supplies the layout and the default item set, sort and conditions (all configured in the View admin). At call time you may narrow the view to a specific set of items and override individual view settings.

vid accepts the numeric view ID or a named view alias. The ids parameter restricts output to the listed items (dash-separated long IDs, typically produced by ids). The settings parameter overrides stored view options as comma-separated name-value pairs, for example listlen-5 or sort-headline........

Note: when you pass ids, the view still applies its own sort - the items come back in the view sort order, not the order you listed them. Pass settings sort-AAnoSORT to keep the exact ids order. An empty or missing vid renders nothing.

This is the colon form handled by AA_Stringexpand_View. AA also accepts a legacy query-string form, view.php?vid=N, which additionally supports cmd-style per-view conditions; prefer the colon form in new templates.

{xid[:level]}Navigation & SEO
Returns the id of the current page item in a Site module, the counterpart to the xseo navigation variables. With no argument it gives the id of the page the visitor is on. A digit selects the ancestor at that directory level. The literal path gives the nested id path 2587(2877(3004)) for breadcrumbs; the literal list gives the dash-joined list 2587-2877-3004. A slice id returns the nearest ancestor page in that slice. Any other text is expanded as the content argument against the current page item. xid needs a Site module router, so its value depends on the current page; outside a router it returns an error. A second argument lets you ask about another url instead of the current page.
{xmlfield:tags:field_id}String & Text Manipulation
Wraps an item field value in an XML element, for building XML or RSS export feeds from item content. The first parameter is the tag (or two space-separated names: an outer wrapper tag and the inner element tag). The second parameter is a field id of the current items slice - or any AA expression/alias, which is then resolved and wrapped as-is. xmlfield needs a current item: with no item in context it returns nothing. A multi-value field repeats the element once per value; a multilingual field adds a lang attribute per translation (lang="cs", lang="en"); a field that offers a formatter choice adds a format attribute (format="plain" or format="html"). Empty values are skipped, and the outer wrapper is emitted only when there is at least one inner element. Element content is XML-escaped. Bind a specific item with the item expression, deferring xmlfield so it runs in that items context: see the examples.
{xmlformat:xml}Encoding & Formatting
Pretty-prints an XML string: parses it with DOMDocument and re-serializes it with formatOutput on, so the result is reindented with two-space steps, one element per line, and an XML declaration line prepended (version 1.0). The single parameter is the XML to format; it must be well-formed and have a single root element. On malformed or non-XML input the parser fails quietly and the command returns just that one declaration line followed by a newline (22 bytes). Empty input is a hard error - DOMDocument loadXML throws on an empty string - so never pass an empty value. Because the output carries real angle-bracket tags, the live result of a raw call is shown on this page as Illustrative rather than asserted; the asserted examples wrap the call in strlen to get a deterministic, tag-free byte length.
Runs an XPath query against an XML or HTML string and returns the matching content. The first parameter is the markup to search - usually a remote page or feed loaded with the include command, but any literal XML/HTML string works. The second parameter is the XPath query (for example //title, //book[2]/title, or //book[@id="b2"]/author). The engine first tries a strict XML parse and falls back to a more tolerant HTML parse if that fails. By default only the first matching node is returned, as its text value. The optional third parameter changes what is returned from each match: give an attribute name to return that attribute (for example id or width), or the literal XML to return the matched node as inner markup. The optional fourth parameter is a delimiter: supply it to return all matching nodes joined by that delimiter instead of just the first - note the delimiter is appended after every match, including the last, so a trailing delimiter remains. A query that matches nothing returns an empty string; markup that cannot be parsed at all returns an error message. Because a colon separates parameters, an XPath axis written with a double colon such as following-sibling must be escaped in the query as following-sibling#:#: so the colons are not read as parameter separators.
{xseo[:level]}Navigation & SEO
Reads one directory segment from the current SEO-friendly URL path, as parsed by the site module router (AA_Router_Seo). The router splits a path like /en/about-us/projects/efficiency into language plus numbered segments xseo1, xseo2, xseo3 and so on; xseo (with no number) is an alias for the last segment. With no argument the command returns the last segment; with a digit it returns that level (xseo:1 is the first directory level, xseo:2 the second, and so on). A non-digit argument is treated as no argument and returns the last segment. The value is read live from the router state and is never cached, so it depends entirely on the URL of the page being viewed; outside a site-module router page it returns an empty string. Typical use is highlighting the active item in a menu by comparing a segment to each item SEO slug, or building links and switching content per URL level. The matching ID reader is xid (xid returns the item id behind the same segment).
{xuser:field}Security & Authentication
Inserts information about the currently logged-in user, taken from AA session state (apc_state xuser / xuid). With no argument it returns the login name; the special argument id returns the user item long ID; any other argument is treated as a field id or alias and returns that field from the user item. Returns an empty string when nobody is logged in, which makes it the usual way to test for a logged-in visitor. Output depends only on the AA session state and not on the surrounding item, so views using xuser stay page-cacheable - unlike the related user command, which disables the page cache.
{yahoo:user_id:action:style}Communication & Social
Builds a Yahoo Messenger presence badge: a link with the ymsgr: protocol wrapping a status image that used to show whether the account was online. The first parameter is the Yahoo account name and is required; with an empty name the expansion outputs nothing. The optional action (default sendim) sets the verb after ymsgr: and must be addfriend, call, or sendim, otherwise it falls back to sendim. The optional style (default 2) is an icon size from 0 to 4; anything else falls back to 2. This is a legacy helper. Yahoo Messenger was discontinued in July 2018 and the status-image host opi.yahoo.com no longer resolves, so the badge image will not load; the engine still emits the same markup. It builds the string only, with no network call at render, so it is safe to use but mostly of historical interest. Compare the sibling badges icq and skype, which share this shape.
{_:shortcut:param1:...}Aliases & Variables
Calls a named, admin-defined alias - a reusable block of template code - and fills in its parameters. Aliases are created in the site Aliases manager; each stores template code under a name. Writing _:Name inserts that code in place; extra colon-separated values fill the placeholders _#P1, _#P2, ... inside the alias code, in order. The inserted code is then expanded in the current item context, so an alias can itself call views, fields and other commands, and aliases can be nested. Aliases are scoped to the current site (plus any sites it shares aliases with), so the same name can expand differently from one install to another. An unknown name, or an empty name, yields an empty string. Use the _ command to hide long view ids behind a short name, share a header or e-mail template across many views, or build small parameterised helpers.