Skip to content

Block tags

A block tag wraps a piece of the template in a paired construct and decides whether to show it:

fenom
{auth}
    <a href="/profile">Profile</a>
{/auth}

{guest}
    <a href="/login">Login</a>
{/guest}

🔧 Built-in tags

TagShows the content to
{auth}a user authenticated in the current context
{guest}a guest
{admin}an authenticated administrator (sudo)

The body always runs, even when it is not shown

A block tag receives content that has already been rendered: the body executes first, then the function decides whether to return it. So everything inside runs for everyone, including those the block is not meant for.

fenom
{auth}
    Hello, {$modx->user->getOne('Profile')->fullname}
{/auth}

For a guest, getOne() is called on null — a fatal error and a blank 500, even though the block is "for authenticated users". Guard anything that needs an object with a plain {if}:

fenom
{if $modx->user->isAuthenticated($modx->context->key)}
    Hello, {$modx->user->getOne('Profile')->fullname}
{/if}

A block tag is about showing markup, not about guarding computation.

🧩 Your own tags

core/App/Helpers/fenom/block_tags.php

The file returns a name → function map. The function receives $params (the tag's parameters) and $content (the rendered body) and returns what ends up on the page; returning null outputs nothing.

php
return [
    'superadmin' => function (array $params, $content) {
        if ((int) $this->modx->user->id === 1) {
            return $content;
        }
    },
];
fenom
{superadmin}
    <div class="alert alert-danger">You're a super-admin!</div>
{/superadmin}

$this->modx is available — the file is included from inside View. Your tags are read after the built-in ones, so a tag with the same name overrides the built-in.

Tag names collide

A block tag name shares the namespace with the engine's own tags: escape and strip are both modifiers and block tags in Fenom. Name yours the same and you overwrite the built-in — {strip}…{/strip} then does something else.

Parameters

Parameters use the same syntax as pseudo-tags — spaces, no parentheses:

php
'role' => function (array $params, $content) {
    $groups = array_map('trim', explode(',', $params['in'] ?? ''));
    return $this->modx->user->isMember($groups) ? $content : '';
},
fenom
{role in='Managers,Editors'}
    <a href="/moderation">Moderation</a>
{/role}

© PageBlocks 2019-present