-
-
Notifications
You must be signed in to change notification settings - Fork 3
HTML Components
Components let us keep a chunk of HTML in its own file and pull it into the page using a custom element such as <profile-summary>.
This is particularly helpful when a section of UI becomes awkward to maintain inline, or when the same structure appears on several pages.
Page HTML:
<h2>Account details</h2>
<profile-summary />Component file:
_component/profile-summary.html
<dl>
<dt>Name</dt>
<dd data-bind:text="name">Guest</dd>
<dt>Email</dt>
<dd data-bind:text="email">guest@example.com</dd>
</dl>PHP:
use GT\DomTemplate\ComponentExpander;
use GT\DomTemplate\PartialContent;
$expander = new ComponentExpander(
$document,
new PartialContent(__DIR__ . "/_component"),
);
$expandedComponents = $expander->expand();If we do this, the <profile-summary> element stays in the document, but its inner HTML is replaced with the component file contents.
The W3C have decided that custom component names must contain a hyphen.
Good examples:
<profile-summary><calendar-control><shop-item-card>
This keeps custom elements distinct from native HTML elements.
The src attribute lets us load from a subdirectory.
Page HTML:
<date-picker src="calendar" />
<date-picker src="christmas" />Component files:
_component/calendar/date-picker.html_component/christmas/date-picker.html
That gives us a tidy way to organise larger component libraries without inventing a separate naming system.
Components can contain other components.
So if profile-summary.html itself contains <avatar-image />, DomTemplate will keep expanding until there are no more matching component files.
This makes it practical to build layered interfaces from smaller pieces.
Once a component has been expanded, we often want to bind data only within that one component, and not leak data binding out to the rest of the document. That is what ComponentBinder is for.
use GT\DomTemplate\ComponentBinder;
$componentElement = $document->querySelector("profile-summary");
$componentBinder = new ComponentBinder($document);
$componentBinder->setDependencies(
$elementBinder,
$placeholderBinder,
$tableBinder,
$listBinder,
$listElementCollection,
$bindableCache,
);
$componentBinder->setComponentBinderDependencies($componentElement);
$componentBinder->bindData([
"name" => "Ada",
"email" => "ada@example.com",
]);The API is intentionally the same as DocumentBinder, but the scope is locked to one component subtree.
Note
In WebEngine applications, you can use the Binder helper class, which will be automatically instantiated as a DocumentBinder when in page context, and ComponentBinder when in component context.
ComponentBinder also accepts selector string contexts:
$componentBinder->bindKeyValue("title", "Orders", ".heading");If the selector does not match inside the component, it throws ContextElementNotFoundException.
When a component contains a <form method="post">, DomTemplate automatically prepends a hidden input named __component with the component tag name.
That gives server-side code a tidy way to tell which component submitted the form, and makes custom routing easier.
Components handle reusable fragments of HTML, but Partials are used for whole-page templates.
PHP.GT/DomTemplate is a separately maintained component of PHP.GT/WebEngine.