v0.9.7 PHP 8.x+ Zero dependencies Single file

A lite, Smarty-like
templating system
for PHP.

Separate logic (.php) from presentation (.stpl) with a tiny, single-file engine that speaks the Smarty syntax you already know.

$ composer require sluz/sluz
E_ALL clean Fully tested on PHP 8.x+ GPL-3.0-or-later
script.php
include 'sluz.class.php';
$s = new sluz();

$s->assign('name', 'Jason');
$s->assign('languages', ['PHP', 'Perl', 'JS']);

print $s->fetch('tpls/script.stpl');
tpls/script.stpl
<h1>Hello {$name|default:"world"}</h1>

<ul>
{foreach $languages as $item}
	<li>{$item|strtoupper}</li>
{/foreach}
</ul>
Rendered output
Hello Jason
  • PHP
  • PERL
  • JS
Why Sluz?

Everything you need.
Nothing you don't.

Drop in one file, and get familiar Smarty-like syntax, modifier chaining, and layout tools — with zero bloat and zero surprises.

Single file

Just sluz.class.php. No autoloader maze, no build step. Simple. Copy it and go.

Zero dependencies

Requires PHP 8.x+ and nothing else. Composer-friendly but not Composer-required.

Smarty-like syntax

If you know Smarty, you know Sluz. Variables, blocks, and filters feel like home.

Modifiers & chaining

{$var|default:"?"|strtoupper} — pipe as many native PHP functions as you like.

Dot-notation access

{$user.name.first}$user['name']['first']. Arrays stay ergonomic.

Expressions

{$x + 3}, {count($arr)} and friends — math and function calls right in templates.

foreach superpowers

$__FOREACH_FIRST, $__FOREACH_LAST, $__FOREACH_INDEX for clean list rendering.

Includes & layouts

{include} and parent/child templates for composable pages.

{literal} & {* comments *}
·
Custom delimiters via set_delimiters('[', ']')
·
Inline & simple modes
Cheat sheet

Smarty-like, without the weight.

A tiny vocabulary that covers the 95% you actually use.

SyntaxExampleOutput
{$var}{$name}Jason
{$hash.key} / {$arr.0}{$cust.first}Scott
{$var|modifier}{$animal|strtoupper}KITTEN
{$var|mod:params}{$greet|substr:0,3}Hel
{$var|mod1|mod2}{$word|strtolower|ucfirst}Crazy
{$var|default:"val"}{$null|default:"?"}?
{$var|escape}{$name|escape}<script> → &lt;script&gt;
{$expr}{$number + 3}18
{if}…{elseif}…{else}{/if}{if $x}yes{else}no{/if}yes
{foreach $a as $v}{foreach $items as $x}{$x}{/foreach}onetwothree
{foreach $a as $k => $v}{foreach $m as $k => $v}{$k}{/foreach}012
$__FOREACH_FIRST/_LAST/_INDEX{if $__FOREACH_FIRST}…{/if}
{include file='…'}{include file='header.stpl'}
{literal}…{/literal}{literal}function foo() { {/literal}function foo() {
{* comment *}{* hidden *}(empty)
{function()}{count($array)}3
Quick start

From zero to rendered in 30 seconds.

1

Install

Composer or single-file drop-in — you choose.

Terminal
# via Composer
composer require sluz/sluz

# or just grab the one file you need
curl -O https://www.sluz.org/latest/sluz.class.php
2

Create a template

Save as tpls/hello.stpl next to your script.

tpls/hello.stpl
<h1>Hello {$name}!</h1>

{if $items}
	<ul>
	{foreach $items as $item}
		<li>{$item}</li>
	{/foreach}
	</ul>
{/if}
3

Render it

Assign data and fetch. That's it.

hello.php
<?php
require 'sluz.class.php';
$s = new sluz();

$s->assign('name', 'Ada');
$s->assign(['items' => ['Logic','Presentation']]);

print $s->fetch('tpls/hello.stpl');

Pick your mode

Classic, simple, or inline — same engine, three ergonomics.

Classic

Full control: assign, fetch, parent templates.

$s = new sluz();
$s->assign('age', 38);

print $s->fetch('tpls/index.stpl');
Simple mode

Singleton helper — auto-renders tpls/[script].stpl in the destructor.

sluz('name', 'Ada'); // Alias for assign()
sluz('color', 'green');
// done — template renders itself
Inline mode

Template lives in the same file after __halt_compiler();. Great for single file scripts.

$s->fetch(SLUZ_INLINE);

__halt_compiler();
<h1>Hello {$name}</h1>
Security

Escape by default when you want it.

Variables are verbatim by default. Wrap untrusted output with |escape, or flip the safety switch and auto-escape everything.

  • {$var|escape}htmlspecialchars
  • {$var|escape:"url"} / |escape:"js" for URL and JS contexts
  • $s->setEscapeHtml(true) + |raw to opt out when HTML is trusted
escaping — tpls/secure.stpl
{* manual escaping *}
{$user_input|escape}					{* HTML-encode *}
{$redirect_url|escape:"url"}	{* URL-encode *}
{$inline_js|escape:"js"}			{* JSON-encode for JS *}

{* auto-escape mode (PHP) *}
$s->setEscapeHtml(true);

{$user_input}								 {* now auto-escaped *}
{$user_input|escape}				 {* not double-escaped *}
{$trusted_html|raw}					 {* opt out — verbatim *}
Auto-escaping applies to {$var} blocks only. Expression blocks like {$x + 3} and function calls like {count($arr)} are not auto-escaped.

Tiny API, familiar feel.

Mirrors the bits of Smarty you actually reach for.

$s->assign('key', 'value')single or bulk ['k'=>'v']
$s->fetch('tpls/a.stpl')render template file to string
$s->display('tpls/b.stpl')print rendered template

Testing

250+ Unit tests covering over 94% of the codebase
Fully tested on PHP: v8.x+
php unit_tests/tests.php           # full suite
php unit_tests/tests.php "Foreach" # filter by name
php unit_tests/tests.php --simple  # quiet counts only
Ecosystem

One idea, three runtimes.

Sluz started in PHP, but the same light Smarty spirit lives on in Perl and JavaScript.

Keep your PHP tidy.

One file to include, Smarty-like syntax to love, and no hidden magic. Grab Sluz and keep presentation where it belongs.

Or composer require sluz/sluz — your call.