Getting started

temples renders data into plain HTML. A template is a normal HTML fragment decorated with a few data-* attributes. Nothing else: no framework, no build step, no non-HTML syntax.

Install

Pick the packages you need. All of them depend on @temples/engine.

PackageInstallUse it for
@temples/enginebun add @temples/engineDirect rendering in the browser.
@temples/componentsbun add @temples/componentsDeclarative Web Components.
@temples/ssrbun add @temples/ssrServer-side rendering and static site generation.
@temples/jquerybun add @temples/jquery jqueryjQuery pages (jQuery is a peer dependency).

Your first template

Write the markup you would write anyway, with sample content inside. Add one data-bind attribute per bound element:

<div id="logged-user">
    <img data-bind="src=user.avatar" src="http://avatar.com/default.png" />
    <div data-bind="user.fullname" class="active">John DOE</div>
</div>

The sample content stays visible before any data arrives — designers work on real pages, and the bindings never break their markup.

Build a Renderer from the template and render a data dictionary into it. The source is an element id, a DOM element, or an HTML string:

import { Renderer } from "@temples/engine";

const renderer = new Renderer("#logged-user");

renderer.render({
    user: {
        avatar: "http://avatar.com/johndoe",
        fullname: "John DOE",
    },
});

A string starting with # names an element already in the page: the renderer binds it in place, so every render writes into the live DOM. An unknown id throws a clear error. The other forms bind a detached element or a freshly parsed fragment:

const fromElement = new Renderer(document.getElementById("logged-user"));
const fromString = new Renderer("<h1 data-bind='article.title'>Title</h1>");

The binding paths (user.avatar, user.fullname) resolve against the data dictionary you pass. See Data-binding syntax for the complete reference.

Partial updates

render(data) touches only the paths present in the data. Absent paths keep their current state. To change one value in real time, update(path, value) re-renders only the bindings bound to that exact path:

renderer.update("user.fullname", "Jane DOE");

This is what makes temples suitable for live updates: a websocket message that carries one value re-renders one binding, not the page.

Serialize to HTML

On the server, pair the engine with @temples/ssr: prepare(source) returns an async render function whose result is the rendered HTML string.

import { prepare } from "@temples/ssr";

const render = prepare("<h1 data-bind='article.title'>Title</h1>");

const html = await render({ article: { title: "The Great Race" } });
console.log(html); // <h1>The Great Race</h1>

See SSR and static site generation for prepare(), full-page rendering, and component rendering.

Next steps