Ui
A set of classes for creating HTML documents.
Install / Use
/learn @WebFiori/UiREADME
WebFiori UI Package
<p align="center"> <img src="https://img.shields.io/badge/PHP-8.1%2B-blue" alt="PHP Version"> <img src="https://img.shields.io/packagist/v/webfiori/ui" alt="Latest Version"> <img src="https://img.shields.io/packagist/dt/webfiori/ui" alt="Total Downloads"> <img src="https://img.shields.io/github/license/WebFiori/ui" alt="License"> </p> <p align="center"> <a href="https://github.com/WebFiori/ui/actions"> <img src="https://github.com/WebFiori/ui/actions/workflows/php84.yaml/badge.svg?branch=main"> </a> <a href="https://codecov.io/gh/WebFiori/ui"> <img src="https://codecov.io/gh/WebFiori/ui/branch/main/graph/badge.svg" /> </a> <a href="https://sonarcloud.io/dashboard?id=WebFiori_ui"> <img src="https://sonarcloud.io/api/project_badges/measure?project=WebFiori_ui&metric=alert_status" /> </a> </p>A PHP library for creating HTML documents and DOM manipulation with an object-oriented approach. Build dynamic web pages, forms, tables, and complex UI components programmatically with clean, readable code.
✨ Features
- 🏗️ Object-Oriented DOM Creation - Build HTML elements using intuitive PHP classes
- 🎨 Template System - Support for both HTML templates with slots and PHP templates
- 🔄 Iterator Support - Traverse child nodes using foreach loops
- 🎯 Type Safety - Full type hints and comprehensive PHPDoc documentation
- 🛡️ Security First - Built-in HTML entity escaping
- 🌐 XML Support - Generate both HTML and XML documents
📋 Table of Contents
- Installation
- Quick Start
- Core Concepts
- HTML Document Creation
- Working with Elements
- Forms and Input
- Tables and Data
- Lists and Navigation
- Images and Media
- Template System
- Styling and CSS
- Advanced Features
- Performance Tips
- API Reference
- Examples
- Contributing
🚀 Installation
The basic use case is to have HTML document with some text in its body. The class HTMLDoc represent HTML document. Simply, create an instance of this class and use it to build the whole HTML document. The class can be used as follows:
use WebFiori\Ui\HTMLDoc;
```bash
composer require webfiori/ui
Or add to your composer.json:
All HTML elements are represented as an instance of the class HTMLNode. Developers can extend this class to create custom UI components as classes. The library has already pre-made components which are used in the next code sample. In addition to that, the class has methods which utilize theses components and fasten the process of adding them as children of any HTML element. The following code shows a code which is used to create a basic login form.
use WebFiori\Ui\HTMLDoc;
//Create new instance of "HTMLDoc".
$doc = new HTMLDoc();
// Build a login form.
$body = $doc->getBody();
$body->text('Login to System')->hr();
$form = $body->form(['method' => 'post', 'actiion' => 'https://example.com/login']);
$form->label('Username:');
$form->br();
$form->input('text', ['placeholder'=>'You can use your email address.', 'style' => 'width:250px']);
$form->br();
$form->label('Password:');
$form->br();
$form->input('password', ['placeholder' => 'Type in your password here.', 'style' => 'width:250px']);
$form->br();
$form->input('submit', ['value' => 'Login']);
echo $doc;
The output of the code would be similar to the following image.
<img src="tests/images/login-form.png">HTML/PHP Template Files
Some developers don't like to have everything in PHP. For example, front-end developers like to work directly with HTML since it has femiliar syntax. For this reason, the library include basic support for using HTML or PHP files as templates. If the templates are pure HTML, then variables are set in the document using slots. If the template has a mix between PHP and HTML, then PHP variables can be passed to the template.
HTML Templates
Assume that we have HTML file with the following markup:
<!DOCTYPE html>
<html>
<head>
<title>{{page-title}}</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="{{page-desc}}">
</head>
<body>
<section>
<h1>{{page-title}}</h1>
<p>
Hello Mr.{{ mr-name }}. This is your visit number {{visit-number}}
to our website.
</p>
</section>
</body>
</html>
It is noted that there are strings which are enclosed between {{}}. Any string enclosed between {{}} is called a slot. To fill any slot, its value must be passed when rendered in PHP. The file will be rendered into an instance of the class HTMLNode. The file can be rendered using the static method HTMLNode::fromFile(string $templatePath, array $values). First parameter of the method is the path to the template and the second parameter is an associative array that holds values of slots. The keys of the array are slots names and the value of each index is the value of the slot. The following code shows how this document is loaded into an instance of the class HTMLNode with slots values.
$document = HTMLNode::fromFile('my-html-file.html', [
'page-title' => 'Hello Page',
'page-desc' => 'A page that shows visits numbers.',
'mr-name' => 'Ibrahim Ali',
'visit-number' => 33,
]);
echo $document
The output of the above PHP code will be the following HTML code.
<!DOCTYPE html>
<html>
<head>
<title>Hello Page</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="A page that shows visits numbers.">
</head>
<body>
<section>
<h1>Hello Page</h1>
<p>
Hello Mr.Ibrahim Ali. This is your visit number 33
to our website.
</p>
</section>
</body>
</html>
PHP Templates
One draw back of using raw HTML template files with slots is that it can't have dynamic PHP code. To overcome this, it is possible to have the template written as a mix between HTML and PHP. This feature allow the use of all PHP features in HTML template. Also, this allow developers to pass PHP variables in addition to values for slots.
Assuming that we have the following PHP template that shows a list of posts titles:
<div>
<?php
if (count($posts) != 0) {?>
<ul>
<?php
foreach ($posts as $postTitle) {?>
<li><?= $postTitle;?></li>
<?php
}
?>
</ul>
<?php
} else {
echo "No posts.\n";
}
}
Requirements
- PHP 8.1 or higher
- No additional dependencies required
⚡ Quick Start
Create Your First HTML Document
<?php
require_once 'vendor/autoload.php';
use WebFiori\Ui\HTMLDoc;
// Create a complete HTML5 document
$doc = new HTMLDoc();
$doc->getHeadNode()->setPageTitle('My First Page');
$doc->setLanguage('en');
// Add content to the body
$body = $doc->getBody();
$body->addChild('h1')->text('Welcome to WebFiori UI!');
$body->addChild('p')->text('Building HTML has never been easier.');
// Output the complete document
echo $doc;
Build Elements Programmatically
use WebFiori\Ui\HTMLNode;
// Create a navigation menu
$nav = new HTMLNode('nav', ['class' => 'main-nav']);
$ul = $nav->addChild('ul', ['class' => 'nav-list']);
$menuItems = ['Home', 'About', 'Services', 'Contact'];
foreach ($menuItems as $item) {
$li = $ul->li(['class' => 'nav-item']);
$li->anchor($item, [
'href' => '#' . strtolower($item),
'class' => 'nav-link'
]);
}
echo $nav->toHTML(true);
🧠 Core Concepts
HTMLNode - The Foundation
Every HTML element is represented by an HTMLNode object:
// Basic element creation
$div = new HTMLNode('div'); // <div></div>
$div = new HTMLNode('div', ['id' => 'main']); // <div id="main"></div>
// Add content
$div->text('Hello World'); // <div id="main">Hello World</div>
// Chain operations
$div->setAttribute('class', 'container')
->setStyle(['padding' => '20px'])
->addChild('p')->text('Nested paragraph');
Method Chaining
Most methods return the HTMLNode instance, enabling fluent interfaces:
$card = new HTMLNode('div');
$card->setClassName('card')
->setStyle(['border' => '1px solid #ccc', 'padding' => '1rem'])
->addChild('h3')->text('Card Title')->getParent()
->addChild('p')->text('Card content goes here.');
Parent-Child Relationships
$parent = new HTMLNode('div');
$child = $parent->addChild('span');
// Navigate relationships
$parent === $child->getParent(); // true
$parent->hasChild($child); // true
$parent->childrenCount(); // 1
📄 HTML Document Creation
Complete Document Structure
use WebFiori\Ui\HTMLDoc;
$doc = new HTMLDoc();
// Configure document
$doc->getHeadNode()->setPageTitle('My Application');
$doc->setLanguage('en');
$head = $doc->getHeadNode();
$head->addMeta('description', 'A powerful web application')
->addMeta('keywords', 'php, html, webfiori')
->addCSS('styles/main.css')
->addJs('scripts/app.js');
// Add structured content
$body = $doc->getBody();
// Header section
$header = $body->addChild('header', ['class' => 'site-header']);
$header->addChild('h1')->text('My Application');
// Main content
$main = $body->addChild('main', ['class' => 'main-content']);
$main->addChild('h2')->text('Welcome');
$main->addChild('p')->text('This is the main content area.');
// Footer
$footer =
Related Skills
node-connect
349.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.0kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
