Shortcodes
Shortcodes are the safe dynamic mechanism for CMS bodies. In html and markdown pages — the formats a content editor can touch — there's no code, so anything dynamic (a menu, a reusable section, the page body inside a layout) is expressed as a [shortcode]. A phtml body doesn't need them: it's trusted code and already has full view access.
Syntax
The renderer (Tiger_Cms_Renderer) recognizes two forms:
[name attr="value"] self-closing
[name attr="value"]inner[/name] with inner content
- Names are case-insensitive.
- Attributes are
key="value"pairs (double-quoted). - An unregistered shortcode is left untouched — the literal text stays in the output, so a stray
[foo]never errors.
Shortcodes are processed after the body is rendered (HTML as-is; Markdown → HTML first), and they resolve recursively — a partial pulled in by a shortcode can itself contain shortcodes.
Built-in shortcodes
Three ship with the platform, registered at bootstrap:
Renders an admin-authored navigation menu by key — the same output as the {menu} view helper and Tiger_Menu::getHTML(), auth-filtered (items hide by ACL), labels translated, hrefs resolved.
name (or key) is required; class and id are optional pass-throughs.
Renders a published partial row by its page_key, in place, honoring the org cascade (an org's own partial wins over the global one). Resolves recursively with a cycle-and-depth guard. This is the composition primitive — see Layouts & partials.
Emits the page body when a layout wraps a page — the one reserved slot that makes a visually-built layout "just partials around the content." It's populated only during layout rendering (Tiger_Cms_Renderer passes the page HTML in as the content context var); rendered anywhere else it's harmlessly empty.
How a module registers its own
The registry is static on the renderer. A module registers a handler from its Bootstrap (an _init* method), typically once at boot:
Tiger_Cms_Renderer::registerShortcode('year', static function (array $attrs, ?string $inner, array $context) {
return date('Y');
});
The handler signature is:
function (array $attrs, ?string $inner, array $context): string
$attrs— the parsedkey="value"attributes.$inner— the inner content for the[name]…[/name]form, ornullwhen self-closing.$context— the render context (the currentpage, and when inside a layout,content). Thehandler uses this to carry its recursion guard (_partialStack).
The handler returns the string to substitute. Register with a lowercase name; registering an existing name replaces it. Because the substitution runs on every html/markdown/builder body, keep handlers cheap and side-effect-free.
Shortcodes are for the safe formats. A
phtmlpage is trusted code and can call services and helpers directly, so it doesn't route through the registry.
See also
- Pages — body formats and the render pipeline
- Layouts & partials —
andin composition - Menus — building the menus
renders - The visual builder — the builder's menu and partial widgets