The HtmlElement
class is the core component of the hypertool/html
library. Its primary purpose is to provide a flexible and fluent interface for programmatically generating HTML elements in PHP. It serves as the base class for all specific HTML element classes (like Div
, Button
, etc.) and also provides static factory methods for creating any HTML element. It supports setting standard HTML attributes, managing child elements, adding text content, and includes dedicated methods for integrating with HTMX and Hyperscript attributes.
Within the Hypertool HTML Generator project, HtmlElement
is the foundation upon which all HTML structures are built.
__construct(string $tagName)
$tagName
(string, required): The HTML tag name for the element (e.g., ‘div’, ‘p’, ‘span’).(Note: This is not exhaustive for all attribute setters, but covers key methods and categories.)
output(): string
text(string $content): self
$content
(string, required): The text content to set.self
) The instance, allowing method chaining.add_child(?string $identifier, string|HtmlElement $tagNameOrElement): HtmlElement
$identifier
(?string, optional): A unique string identifier to access this child later via magic properties (e.g., $parentElement->childIdentifier
). If null
, an auto-incrementing numeric identifier is used (not accessible via magic properties).$tagNameOrElement (string |
HtmlElement, required): Either the tag name (string) of the child element to create, or an existing HtmlElement instance to add as a child. |
HtmlElement
) The newly added child element instance.setClass(string $class): self
class
attribute for the element. Overwrites any existing classes.$class
(string, required): The CSS class(es) to apply.self
) The instance for chaining.class
attribute.setId(string $id): self
id
attribute for the element.$id
(string, required): The unique ID.self
) The instance for chaining.id
attribute.setAttribute
, setStyle
, setSrc
, setHref
, etc.)href
, src
, type
, value
, etc.). They generally follow the pattern setAttributeName($value)
.Parameters: Typically a single $value (string |
int | bool) appropriate for the attribute. |
self
) The instance for chaining.setHxGet
, setHxPost
, setHxTrigger
, setHxSwap
, setHxTarget
, setHxOn
, etc.)hx-get
, hx-trigger
).$value
(string) representing the attribute’s value. setHxOn
takes $event
(string) and $handler
(string).self
) The instance for chaining.setHyperscript
)_
attribute for Hyperscript.$script
(string, required): The Hyperscript code.self
) The instance for chaining._
attribute.HtmlElement::div()
, HtmlElement::button()
, etc.)$content = ''
(string, optional) for the element’s initial text content. Some elements might have different required parameters (e.g., img
might require src
).HtmlElement::div()
returns a Hypertool\Html\Div
instance).All functional properties are managed internally and accessed/modified via public methods. There are no public attributes intended for direct manipulation.
(Assumes Composer autoloader is included and use Hypertool\Html\HtmlElement;
)
Example 1: Basic Form Input
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use Hypertool\Html\HtmlElement;
$label = HtmlElement::label('Username')->setFor('username-input');
$input = HtmlElement::input()
->setType('text')
->setId('username-input')
->setName('username')
->setPlaceholder('Enter your username')
->setClass('form-control'); // Example Bootstrap class
echo $label->output();
echo $input->output();
?>
// Expected Output:
// <label for="username-input">Username</label>
// <input type="text" id="username-input" name="username" placeholder="Enter your username" class="form-control">
Example 2: Nested Structure with Children
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use Hypertool\Html\HtmlElement;
$list = HtmlElement::ul()->setClass('list-group'); // Create a <ul>
$item1 = HtmlElement::li('First item')->setClass('list-group-item');
$item2 = HtmlElement::li('Second item')->setClass('list-group-item active'); // Add 'active' class
$item3 = HtmlElement::li()->setClass('list-group-item'); // Empty item
$link = HtmlElement::a('Click me')->setHref('#');
$item3->add_child('link', $link); // Add link to the third item
$list->add_child('i1', $item1)
->add_child('i2', $item2)
->add_child('i3', $item3);
echo $list->output();
?>
// Expected Output:
// <ul class="list-group">
// <li class="list-group-item">First item</li>
// <li class="list-group-item active">Second item</li>
// <li class="list-group-item"><a href="#">Click me</a></li>
// </ul>
Example 3: HTMX Partial Loading with Hyperscript Interaction
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use Hypertool\Html\HtmlElement;
$loadButton = HtmlElement::button('Load Content')
->setClass('btn btn-secondary')
->setHxGet('/content-partial')
->setHxTarget('#content-area')
->setHxSwap('innerHTML')
->setHyperscript('on click add @disabled then add .opacity-50 until htmx:afterRequest then remove @disabled remove .opacity-50');
$contentArea = HtmlElement::div()->setId('content-area');
echo $loadButton->output();
echo $contentArea->output();
?>
// Expected Output:
// <button class="btn btn-secondary" hx-get="/content-partial" hx-target="#content-area" hx-swap="innerHTML" _="on click add @disabled then add .opacity-50 until htmx:afterRequest then remove @disabled remove .opacity-50">Load Content</button>
// <div id="content-area"></div>
HtmlElement
, applying consistent styling (e.g., Bootstrap/Tailwind classes) and behavior.hx-get
, hx-target
, hx-trigger
, etc.) to elements to create dynamic, AJAX-driven user interfaces without writing complex JavaScript._
attribute via the setHyperscript
method, often in conjunction with HTMX events.>=7.4
(as defined in composer.json
).Hypertool\Html\Div
, Hypertool\Html\Button
) located within the same namespace (src/
) when using the static factory methods. These are part of the same library.add_child
for the same parent will result in only the last child being accessible via the magic property (e.g., $parent->childId
). The element will still be rendered correctly as a child.<div>
inside a <p>
). Incorrect usage can lead to invalid HTML output.use
statements, PHP will throw errors related to class not found.HtmlElement
itself.ScriptManager
class uses the APP_ENV
environment variable (or setEnv
method) to determine whether to load assets locally or from CDN, but this doesn’t directly affect HtmlElement
.$el->setId('x')->setClass('y')->setHxGet('/z');
HtmlElement::div()
) for readability and convenience over new HtmlElement('div')
.new Div()
) can sometimes offer more tailored methods or constructors, although the static factories are generally sufficient.setClass()
calls or using helper methods if you implement them (see framework compatibility discussion).add_child
if you need to access or modify specific children later via magic properties. Avoid relying on numeric indices.text()
might be ignored if the element already has children added via add_child
. Add text content to child elements instead if needed.