Functional & immutable HTML builder for PHP 8.1+.
Install the library via Composer:
composer require darksynx/sublimeOnce installed, everything is auto-loaded through Composer:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use function Sublime\{Sublime, body_, div_, p_};
echo Sublime(fn () => body_(data: [
div_(class: 'app', data: [
p_('Hello, Sublime!')
])
]));Sublime exposes a Sublime(fn () => ...) entry point. Inside the callback you compose HTML using the underscore tag helpers (body_(), div_(), p_(), ...). All children are normalized, arrays are flattened, and scalar values are escaped by default.
use function Sublime\{Sublime, body_, div_, h1_, p_};
echo Sublime(fn () => body_(data: [
div_(class: 'container', data: [
h1_('Welcome đź‘‹'),
p_('Build HTML with pure PHP, no templates required.'),
]),
]));Output:
<body>
<div class="container">
<h1>Welcome đź‘‹</h1>
<p>Build HTML with pure PHP, no templates required.</p>
</div>
</body>If you are prototyping or want the smallest possible bootstrap file, you can
simply include the generated helper file and call Sublime() directly without
adding use function ... statements. This is convenient when sharing
copy/pasteable examples with newcomers.
<?php
namespace Sublime;
include __DIR__ . '/sublime.php';
$user = 'admin';
echo Sublime(fn () =>
body_([
link_(rel: 'stylesheet', href: 'style.css'),
div_(class: 'container', data: [
header_([
h1_('Mon Super Site'),
nav_([
a_(href: '/', data: 'Accueil'),
a_(href: '/about', data: 'Ă€ propos'),
$user !== 'admin' ? ruby_(' 漢 6565') : ' => admin',
div_(
class: 'article',
data: raw_html('<z>test de texte</z>')
),
]),
]),
]),
])
);Composer remains the recommended installation method, but the helper file is 100% standalone, so you can tailor the ergonomics to your preferred “one shot” style.
If you prefer importing only the main Sublime() function, declare a parameter in
the callback. Sublime will automatically inject a TagFactory instance that
exposes every helper dynamically:
use function Sublime\Sublime;
echo Sublime(fn (\Sublime\TagFactory $tags) => $tags->body(
data: [
$tags->div(
class: 'container',
data: [
$tags->p('Factory-powered rendering!'),
],
),
],
));The factory also exposes $tags->tag('my-element', ...), $tags->raw('<b>..</b>'),
and $tags->fragment(...) helpers for custom elements and raw output.
Everything is just PHP, so you can create reusable components by returning HtmlElement instances from plain functions.
use Sublime\HtmlElement;
use function Sublime\{div_, nav_, a_, main_, footer_, small_, Sublime, body_};
function navbar(): HtmlElement
{
return nav_(data: [
a_(href: '/', data: 'Home'),
a_(href: '/docs', data: 'Docs'),
a_(href: '/github', data: 'GitHub'),
]);
}
function layout(HtmlElement $content): HtmlElement
{
return body_(data: [
navbar(),
main_(data: $content),
footer_(data: small_('© ' . date('Y')))
]);
}
echo Sublime(fn () => layout(div_('Hello from a component!')));- Every string child and attribute is HTML-escaped automatically (
&,<,>, quotes, etc.). - Nested arrays,
null, andfalsevalues are removed when normalizing children. - When you really need to inject trusted markup, wrap it in
raw_html('<span>Trusted</span>'). Do not useRawHtmlfor user-generated content, otherwise you may introduce XSS vulnerabilities.
use function Sublime\{div_, raw_html};
div_(data: [
'Safe: ',
raw_html('<strong>Trusted markup</strong>'),
]);Run the bundled examples with:
php -S localhost:8000 -t examplesexamples/basic.php– minimal “Hello world” rendering.examples/components.php– layout + reusable components.examples/conditions.php– conditional rendering in callbacks.
- No template inheritance – compose everything with PHP functions.
- No client-side hydration helpers yet.
- Limited to standard HTML tag helpers (custom elements are supported by calling
_tag('my-element', ...)). - Future roadmap: better documentation, Packagist release, and extra developer tooling.
Released under the MIT License.