Block tags
A block tag wraps a piece of the template in a paired construct and decides whether to show it:
{auth}
<a href="/profile">Profile</a>
{/auth}
{guest}
<a href="/login">Login</a>
{/guest}🔧 Built-in tags
| Tag | Shows 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.
{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}:
{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.phpThe 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.
return [
'superadmin' => function (array $params, $content) {
if ((int) $this->modx->user->id === 1) {
return $content;
}
},
];{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:
'role' => function (array $params, $content) {
$groups = array_map('trim', explode(',', $params['in'] ?? ''));
return $this->modx->user->isMember($groups) ? $content : '';
},{role in='Managers,Editors'}
<a href="/moderation">Moderation</a>
{/role}