Skip to content

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 parsed key="value" attributes.
  • $inner — the inner content for the [name]…[/name] form, or null when self-closing.
  • $context — the render context (the current page, and when inside a layout, content). The handler 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 phtml page is trusted code and can call services and helpers directly, so it doesn't route through the registry.

See also