Bind dynamic data to reusable HTML components.
Built on top of PHP.Gt/Dom, this project provides dynamic data binding to DOM Documents, document templating and reusable HTML components.
Directly manipulating the DOM in your code can lead to tightly coupling the logic and view. Binding data using custom elements and data attributes leads to highly readable, maintainable view files that are loosely coupled to the application logic.
Consider a page with a form, with an input element to enter your name. When the form is submitted, the page should greet you by your name.
Without submitting the form, the HTML will be rendered untouched, showing the default message “Hello, you!”.
name.html
)The HTML below shows a basic “Hello, you” message, but due to the data-bind:text
attribute, when the form is submitted, the PHP code binds the submitted name to the DOM at the correct place, greeting the user.
greeter.html
:
<!doctype html>
<h1>
Hello, <span data-bind:text="name-output">you</span>!
</h1>
<form>
<input name="name" placeholder="Your name, please" required />
<button>Submit</button>
</form>
<?php
$html = file_get_contents("greeter.html");
$document = new \Gt\Dom\HTMLDocument($html);
if($name = $_GET["name"]) {
$binder = new \Gt\DomTemplate\DocumentBinder($document);
$binder->bindKeyValue("name-output", $name);
}
echo $document;
In the following example, the template of the HTML is defined, with a data-template
attribute to indicate that the LI should be repeated for every item in the data, and a data-bind:text
attribute to set the textContent of the LI to the value of each item in the data.
Note: when binding an array of strings (or Stringable
objects), there is no need to specify a bind key for the data-bind:text
attribute, however in the next example you will see how more complex data structures can be used to bind data at different locations within the template element.
shopping-list.html
:
<!doctype html>
<h1>Shopping list</h1>
<ul>
<li data-template data-bind:text>Item</li>
</ul>
$html = file_get_contents("shopping-list.html");
$document = new \Gt\Dom\HTMLDocument($html);
$shoppingList = [
"Pasta",
"Rice",
"Butter",
"Eggs",
"Vegetables",
];
$binder = new \Gt\DomTemplate\DocumentBinder($document);
$binder->bindList($shoppingList);
// this removes the data-bind and data-template attributes:
$binder->cleanupDocument();
echo $document;
<!doctype html>
<h1>Shopping list</h1>
<ul>
<li>Pasta</li>
<li>Rice</li>
<li>Butter</li>
<li>Eggs</li>
<li>Vegetables</li>
</ul>
In the following example, the data-template
attribute is used to repeat the LI for every result in the dataset. This dataset represents data that would typically come from a database query or API, but for this example we’re simply hard-coding the data.
Within the LI, you can see where the various fields will be bound:
Note that the actual structure of the HTML can be changed at any time, and it’s just the data-bind
and use of curly braces that define where the data is bound to.
user-list.html
:
<!doctype html>
<h1>Users</h1>
<ul>
<li data-template>
<a href="/user/settings/{{id}}">
<img src="/img/user/{{username}}.jpg"
alt="Profile image for {{username}}" />
<h2 data-bind:text="username">username</h2>
<h3 data-bind:text="type">user type</h3>
</a>
</li>
</ul>
// The $data could be from a database, or any other source.
// For now, we're just hard-coding the data, so we can see its structure.
$data = [
[
"id" => 123,
"username" => "codyboy",
"type" => "user",
],
[
"id" => 456,
"username" => "scarlett",
"type" => "user",
],
[
"id" => 789,
"username" => "greg",
"type" => "owner",
],
];
$html = file_get_contents("user-list.html");
$document = new \Gt\Dom\HTMLDocument($html);
$binder = new \Gt\DomTemplate\DocumentBinder($document);
$binder->bindList($data);
$binder->cleanupDocument();
echo $document;
<!doctype html>
<h1>Users</h1>
<ul>
<li>
<a href="/user/settings/123">
<img src="/img/user/codyboy.jpg"
alt="Profile image for codyboy" />
<h2>codyboy</h2>
<h3>user</h3>
</a>
</li>
<li>
<a href="/user/settings/456">
<img src="/img/user/scarlett.jpg"
alt="Profile image for scarlett" />
<h2>scarlett</h2>
<h3>user</h3>
</a>
</li>
<li>
<a href="/user/settings/789">
<img src="/img/user/greg.jpg"
alt="Profile image for greg" />
<h2>greg</h2>
<h3>owner</h3>
</a>
</li>
</ul>