Literal

Literal enhances the <template> element with a reactive DOM renderer that evaluates literal expressions and binds updates to a signal graph. It is a view layer designed for HTML authors to enhance content.

Weighs under 15kB bundled and gzipped.

<template is="literal-html">

Literal's entry point is the literal-html template. It is replaced in the DOM with its own rendered content:

<template is="literal-html">
    <p>${ 'Hello world' }</p>
</template>

Import data

Data is sourced with the src attribute, which imports a JS module or fetches JSON. Inside a template this data is available as the constant data:

<template is="literal-html" src="./data.json">
    <p>${ data.text }</p>
</template>

Templates that share a src share a data object. As renders are bound to data mutations, changes made in one template are rendered in the others:

<template is="literal-html" src="./data.json">
    <input value="${ data.text }" oninput="${ data.text = e.target.value }">
</template>

Declare data via dataset attributes

For quick prototyping, you can, alternatively, declare data using data-* attributes:

<template is="literal-html" data-text="Hello world">
    <p>${ data.text }</p>
</template>

Include a template

Besides a data object, templates have various other objects and functions in scope. The include(url, data) function gives Literal its composition model, rendering another template from a given data object:

<template id="todo-li">
    <li>${ data.text }</li>
</template>

<template is="literal-html">
    <ul>${ include('#todo-li', { text: 'Brush your teeth' }) }</ul>
</template>

Map arrays to templates

The include() function is partially applicable, allowing you to concisely map an array of objects to template includes:

<template is="literal-html" src="./data/todo.json">
    <ul>${ data.tasks.map(include('#todo-li')) }</ul>
</template>

Renderer features

Due to these features, Literal is suitable for animating the DOM.

Try it

Literal is written in JavaScript and can run in the browser without any build/compile step. Turn logs and inline messages on on by setting a DEBUG flag on window:

<!-- Enable debug messages -->
<script>window.DEBUG = true;</script>
<!-- Import and register template is="literal-html" -->
<script type="module" src="https://cdn.jsdelivr.net/gh/stephband/literal@main/literal-html/element.js"></script>

The production bundle strips logs and inline messages:

<!-- Import and register template is="literal-html" -->
<script type="module" src="https://cdn.jsdelivr.net/gh/stephband/literal@main/build/literal-html/element.js"></script>
Extend the template scope

You are free to put any functions and objects you like into literal's shared template scope. Simply assign them to the Literal.scope object – which must be done before a template is compiled.