template-sluz
v0.9.6
Published
A minimalistic JavaScript templating engine with Smarty-like syntax
Maintainers
Readme
⚡ Sluz templating system
A JavaScript templating engine with Smarty-like syntax. Zero dependencies, single source file, and lite.
📦 Installation
npm install template-sluz🚀 Quick Start
import Sluz from 'template-sluz';
const sluz = new Sluz();
sluz.assign('name', 'Scott');
sluz.assign('user', { first: 'Jason', last: 'Doolis', age: 43 });
console.log(sluz.parse('Hello {$name}')); // Hello Scott
console.log(sluz.parse('{$user.first} {$user.last}')); // Jason Doolis🌐 Browser Usage
Load Sluz from a CDN with a plain <script> tag (sets window.Sluz):
<script src="https://cdn.jsdelivr.net/npm/template-sluz/src/sluz.global.min.js"></script>
<script>
const sluz = new Sluz();
sluz.assign('user', { name: 'Alice', role: 'admin' });
document.body.innerHTML = sluz.parse("Welcome {$user.name} you are {$user.role}");
</script>Or as an ES module import:
<script type="module">
import Sluz from './js/sluz.min.js';
const sluz = new Sluz();
sluz.assign('user', { name: 'Alice', role: 'admin' });
document.body.innerHTML = sluz.parse("Welcome {$user.name} you are {$user.role}");
</script>📝 Variables
Variables are inserted with {$varname}. Dotted paths resolve nested objects
and arrays.
sluz.assign('person', { name: { first: 'Jane' }, colors: ['red', 'green'] });
sluz.parse('{$person.name.first}'); // Jane
sluz.parse('{$person.colors.0}'); // red
sluz.parse('{$missing}'); // '' (empty string)assign()
Accepts key/value pairs or a single object:
sluz.assign('color', 'blue'); // Scalar
sluz.assign('size', ['small', 'medium', 'large']); // Array
sluz.assign('info', { color: 'yellow', age: 43 }); // Hash📖 API Reference
new Sluz()
Creates a new template engine instance.
assign(key, value) / assign(object)
Sets template variables. Accepts:
- Key/value pairs:
sluz.assign('name', 'Scott') - A single object:
sluz.assign('info', { name: 'Scott', age: 43 })
parse(string)
Parses a template string with the current variables and returns the rendered output.
set_delimiters(left, right)
Changes the tag delimiters from the default {/} to any other
single-character pair. Both arguments must be strings of exactly length 1 and
must be different characters.
sluz.set_delimiters('[', ']');
sluz.parse('[$name]'); // resolves {$name}All tag types work with any delimiter pair: variables, modifiers, if/elseif/else, foreach, literal, comments, and expression blocks.
sluz.set_delimiters('[', ']');
sluz.assign('items', ['a', 'b', 'c']);
sluz.parse('[* loop through items *][foreach $items as $x][$x] [/foreach]');
// a b csetAutoEscape(bool)
Enables or disables automatic HTML escaping for all {$var} output. When
enabled, every variable is escaped unless |noescape is explicitly used.
sluz.setAutoEscape(true);
sluz.parse('{$xss}'); // <script>...registerModifier(name, fn)
Registers a custom modifier function. The function receives the variable value as the first argument, followed by any user-supplied arguments from the template.
sluz.registerModifier('truncate', (s, n) => String(s).slice(0, n));
// Template: {$name|truncate:3}🔧 Modifiers
Modifiers transform variable output using pipe (|) syntax. Arguments follow a
colon (:), multiple arguments are comma-separated.
Built-in modifiers
| Modifier | Description | Example |
|------------|------------------------------------------|--------------------------------|
| upper | Uppercase string | {$name\|upper} |
| lower | Lowercase string | {$name\|lower} |
| ucfirst | Capitalize first character | {$name\|ucfirst} |
| trim | Trim whitespace | {$name\|trim} |
| length | String length | {$name\|length} |
| substr | Substring (start[, length]) | {$name\|substr:0,3} |
| replace | Replace all occurrences | {$name\|replace:"old","new"} |
| join | Join array with separator | {$items\|join:", "} |
| count | Count array keys / object keys / truthy | {$items\|count} |
| first | First element of array / first character | {$items\|first} |
| last | Last element of array / last character | {$items\|last} |
| escape | HTML-encode & < > " ' | {$var\|escape} |
| noescape | Bypass auto-escaping (identity) | {$var\|noescape} |
Default values
The default: modifier returns a fallback when the variable is empty
(undefined, null, or empty string):
sluz.parse('{$name|default:"N/A"}'); // Scott (unchanged)
sluz.parse('{$zero|default:"123"}'); // 0 (zero is not empty)
sluz.parse('{$missing|default:"N/A"}'); // N/AChained modifiers
sluz.parse('{$name|upper|substr:0,2}'); // SCAuto-escaping
Sluz can automatically HTML-escape all {$var} output to prevent cross-site
scripting (XSS). Enable it with setAutoEscape(true):
sluz.setAutoEscape(true);
sluz.assign('html', '<script>alert("xss")</script>');
sluz.parse('{$html}'); // <script>alert("xss")</script>Per-variable opt-out with |noescape:
sluz.parse('{$trusted_html|noescape}'); // raw HTML, not escapedExplicit |escape still works and won't double-escape:
sluz.parse('{$html|escape}'); // still single-escapedChaining with auto-escape: the auto-escape applies after all explicit modifiers run, so it won't interfere with transformations:
sluz.parse('{$safe|upper}'); // uppercase then auto-escaped
// <B> <B>Custom modifiers
sluz.registerModifier('greet', name => `Howdy, ${name}!`);
sluz.parse('{$name|greet}'); // Howdy, Scott!🔢 Expressions & Math
Wrap any JavaScript expression in braces for evaluation:
sluz.parse('{$count + 10}'); // 17
sluz.parse('{($count * 3) - 5}'); // 16
sluz.parse('{$count > 5}'); // true🔀 Conditionals: {if} / {elseif} / {else} / {/if}
sluz.parse('{if $admin}Welcome admin{/if}');
sluz.parse('{if $count > 5}Big{else}Small{/if}');
sluz.parse('{if $age < 21}Minor{elseif $age < 65}Adult{else}Senior{/if}');Supports &&, ||, !, parentheses, and comparison operators (==, !=,
<, >, <=, >=).
🔄 Loops: {foreach} / {/foreach}
// Simple iteration
{foreach $items as $x}{$x} {/foreach}
// Key/value iteration (index => value for arrays, key => value for objects)
{foreach $items as $idx => $x}[{$idx}]: {$x} {/foreach}
// Works with objects
{foreach $user as $key => $val}{$key}: {$val} {/foreach}Foreach magic variables
Available inside loops:
| Variable | Description |
|----------------------|----------------------|
| $__FOREACH_FIRST | 1 on first iteration |
| $__FOREACH_LAST | 1 on last iteration |
| $__FOREACH_INDEX | 0-based index |
{foreach $items as $x}
{if $__FOREACH_FIRST}>>> {/if}
{$x}
{if $__FOREACH_LAST} <<<{/if}
{/foreach}📄 Literal Blocks
{literal}...{/literal} bypasses template parsing, outputting content verbatim:
sluz.parse('{literal}function foo() { .. }{/literal}');💬 Comments
{* ... *} comments are stripped from output.
sluz.parse('Kitten{* favorite animal *}'); // Kitten⚠️ Error Handling
Syntax errors throw SluzError with a descriptive message and error code:
import Sluz, { SluzError } from 'template-sluz';
try {
sluz.parse('{foo');
} catch (e) {
console.log(e.code); // 45821
console.log(e.message); // Template::Sluz error #45821: Unclosed tag ...
}| Error Code | Description |
|------------|--------------------------------|
| 45821 | Unclosed tag |
| 48724 | Missing comment close *} |
| 73467 | Unknown block type |
| 18933 | Unknown tag / invalid eval |
| 47204 | Unknown modifier function |
| 95320 | If/else parsing error |
