Skip to content

Conditional and optional elements

Greg Bowler edited this page Apr 12, 2026 · 1 revision

When using the plain HTML to structure your pages, the default state and the optional state are both stored in a single place.

This page describes how state can be managed within the HTML itself by explaining the following concepts:

  • placeholders with defaults
  • data-element
  • cleanupDocument()

Placeholders with defaults

We have already seen basic placeholders:

<a href="/profile/{{username}}">Go to profile</a>

DomTemplate also supports defaults:

<a href="/profile/{{username ?? me}}">Go to profile</a>

If username is null or an empty string, the fallback text is used instead.

This is handy when the default state should still work naturally before any data is bound.

data-element

data-element marks an element as optional.

If the element is never bound, and we later call cleanupDocument(), the element is removed from the final output.

Example: optional error messages

HTML:

<form method="post">
	<div data-element data-bind:text="error">Something went wrong.</div>
	<input name="email" />
	<button>Save</button>
</form>

PHP:

try {
	$database->saveForm(); // just as an example of doing some work.
}
catch(Throwable $exception) {
	$binder->bindKeyValue("error", $exception->getMessage());
}

$binder->cleanupDocument();

If there is no error, the <div> disappears completely. If there is an error, the element stays and shows the message.

data-element="someKey"

Sometimes we want to toggle an element's presence even though there is no separate data-bind:* attribute on it.

HTML:

<p data-element="isAdmin">You are an administrator.</p>
<button data-element="isAdmin" name="do" value="delete">Delete record</button>

PHP:

$binder->bindKeyValue("isAdmin", $user->isAdmin());
$binder->cleanupDocument();

Only truthy values keep those elements in the document.

cleanupDocument()

cleanupDocument() is the final tidy-up step.

It does three main things:

  • removes data-bind, data-list, data-template, data-table-key, and data-element attributes
  • removes internal data-bound markers
  • removes optional elements that never became bound

That means we can keep the source HTML expressive without leaking framework markup into the final response.

When to call cleanup

Call cleanupDocument() after all binding is finished.

That includes:

  • scalar binds
  • list binds
  • table binds
  • component-scoped binds
  • partial variable binds

If we call it too early, later binding operations will have fewer markers to work with.

Note

There's no need to call cleanupDocument in WebEngine applications as this is handled automatically for you.

A good workflow

In most plain PHP usage, the recommended order of execution is:

  1. expand partials
  2. expand components
  3. bind data
  4. call cleanupDocument()
  5. echo the document

This covers all the binding operations. Next, move on to HTML components so we can split larger HTML structures into reusable files.

Clone this wiki locally