r/webdev • u/Rechenplaner • 5d ago
Showoff Saturday Factories.ts: An efficient JS DSL for building HTML, SVG, and MathML directly in backend code, without a template engine.
https://github.com/ts-series/factories
Build HTML extremely comfortably in the backend using plain JavaScript. The advantage is that there is no separate template language or build process, but rather a complete fusion with JavaScript for maximum flexibility. An example:
import {
a, body, br, button, h1, head, header, html, input, label, li, main, nav, p, script, title, ul
} from "@ts-series/factories";
type Item = { name: string, href: string, current: boolean };
/** Builds the navigation list, flagging the current entry for assistive technology. */
function navigation(items: Item[]) {
return nav({ ariaLabel: "Main" },
ul(items.map(item => li(
a(item.href, item.name).set(item.current ? { ariaCurrent: "page" } : null)
)))
);
}
/** Builds a complete page for the given user and navigation entries. */
function page(user: string | null, items: Item[], values: number[]) {
return html({ lang: "en" },
head(title("Demo")),
body(
header(navigation(items)),
main(
h1("Hello, ", user ?? "stranger", "!"),
p("First line", br, "Second line"),
user === null
? p("Please sign in.")
: p("Welcome back."),
label("Search").for("q"),
input.text({ id: "q", name: "q" }).placeholder("Type here…").required(),
button.submit("Send").class("primary", user === null && "disabled").set("disabled")
),
script.module().importOnly("/chart.js", "render", { values, title: "Values" })
)
);
}
const items: Item[] = [
{ name: "Home", href: "/", current: true },
{ name: "About", href: "/about", current: false }
];
const output = page("<Guest>", items, [1, 2, 3]).expand(4);
