A very small JavaScript <template>
manipulation library.
Note
TemplateTemplate is feature complete and will only be updated to address bugs or security issues.
- Uses established Web standards (e.g.
<template>
,document.querySelector
) - Dependency-free
- JavaScript module (ESM)
You've got a couple options for adding TemplateTemplate to your project:
- Download a release from GitHub and do it yourself (old school).
- Install using npm:
npm install @jgarber/templatetemplate --save
- Install using Yarn:
yarn add @jgarber/templatetemplate
TemplateTemplate takes two arguments: a reference to a <template>
element and an object of insertions
defining the content to insert into the <template>
.
A basic example, inserting a row into a <table>
:
<table id="projects">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Author</th>
<th scope="col">URL</th>
<th scope="col">Languages</th>
</tr>
</thead>
<tbody></tbody>
</table>
<template id="row-template">
<tr>
<th class="name" scope="row"></th>
<td class="author"></td>
<td class="url"></td>
<td class="languages"></td>
</tr>
</template>
<script type="module">
import TemplateTemplate from "@jgarber/templatetemplate";
const tbody = document.querySelector("#projects tbody");
const emptyTemplate = document.querySelector("#row-template");
const insertions = {
".name": "TemplateTemplate",
".author": "Jason Garber",
".url": "https://github.com/jgarber623/TemplateTemplate",
".languages": "JavaScript",
};
const renderedTemplate = TemplateTemplate(emptyTemplate, insertions);
tbody.appendChild(renderedTemplate);
</script>
In the example above, a reference to the <template>
element is passed to TemplateTemplate using document.querySelector
. The insertions
argument an object whose keys (e.g. '.name'
) are valid CSS selectors and whose values (e.g. 'TemplateTemplate'
) are strings of text to insert into the selected node.
A more complex example, inserting a row into a <table>
with different types of insertions.
<table id="projects">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Author</th>
<th scope="col">URL</th>
<th scope="col">Languages</th>
</tr>
</thead>
<tbody></tbody>
</table>
<template id="row-template">
<tr>
<th class="name" scope="row"></th>
<td class="author"></td>
<td class="url"></td>
<td class="languages"></td>
</tr>
</template>
<template id="anchor-template">
<a></a>
</template>
<script type="module">
import TemplateTemplate from "@jgarber/templatetemplate";
const tbody = document.querySelector("#projects tbody");
const anchor = document.createElement("a");
anchor.setAttribute("href", "https://sixtwothree.org");
anchor.textContent = "Jason Garber";
tbody.appendChild(
TemplateTemplate("#row-template", {
"tr": [null, {
"class": "project",
"id": "project-cashcash",
}],
"th": "CashCash",
"th + td": anchor,
".url": ["https://github.com/jgarber623/CashCash", {
"style": "font-style: italic;",
}],
"td:last-child": TemplateTemplate("#anchor-template", {
"a": ["JavaScript", {
"href": "https://github.com/search?q=language%3AJavaScript",
"target": "_blank",
}],
}),
}),
);
</script>
The example above demonstrates a handful of additional features that you may find useful. Let's break it down with a commented version of the most interesting bits:
// The first argument to TemplateTemplate may also be a valid CSS selector.
TemplateTemplate("#row-template", {
// When an array is passed as a value, TemplateTemplate will use the first
// index in the array as the `textContent` for the node. If this value is
// `null`, TemplateTemplate skips setting the node's `textContent`.
//
// The second index is an object whose properties are added to the node as
// HTML attributes.
"tr": [null, {
"class": 'project',
"id": 'project-cashcash',
}],
"th": 'CashCash',
// TemplateTemplate will use `appendChild` when given an instance of a
// `DocumentFragment` or an `HTMLElement`.
"th + td": anchor,
".url": ["https://github.com/jgarber623/CashCash", {
"style": "font-weight: bold;",
}],
// TemplateTemplate may also be used to generate content from another
// `<template>` and reuse it on the fly!
"td:last-child": TemplateTemplate("#anchor-template", {
"a": ["JavaScript", {
"href": "https://github.com/search?q=language%3AJavaScript",
"target": "_blank",
}],
}),
})
For a full-featured TemplateTemplate demonstration, check out the demo page and the example file.
TemplateTemplate works in modern browsers. The library makes use of several new(ish) JavaScript features and, in an effort to remain as lightweight and dependency-free as possible, leaves it up to you to choose whether or not to polyfill features for older browsers.
TemplateTemplate is written and maintained by Jason Garber and is another in a growing collection of small, curiously-named JavaScript utilities:
- CashCash, a very small DOM library inspired by jQuery.
- RadioRadio, a very small PubSub library.
- RouterRouter, a very small routing library extracted from Backbone's Router.
TemplateTemplate is freely available under the MIT License. Use it, learn from it, fork it, improve it, change it, tailor it to your needs.