Streaming doT is a doT-based streaming templating language.
Quick facts:
- Generates a stream
- Can consume streams and promises
- Built for Node and for the web (with ServiceWorkers in mind)
- 2KB small (1KB gzip’d)
- Conditionals built-in
- Compiles templates to JavaScript
- Templates can contain arbitrary JavaScript
Compiles templateString
to JavaScript. By default, it returns a function that takes the data object as an argument. Inside the template string the following expressions can be used:
{{=<value>}}
: Inserts<value>
into the template.<value>
must be a string, aUint8Array
or a Promise that resolves to a value of any of these types. The data object is accessible asit
.{{?<value>}}...A...{{??}}...B...{{?}}
: Only inserts A if<value>
is truthy or is a Promise that resolves to a truthy value. Otherwise, B is inserted. The B block is optional.{{~<value>}}
: Inserts<value>
into the template.<value>
must be a stream.{{<code>}}
: Inserts<code>
into the generator function. The code canyield
Promises to insert their value into the template. For example,{{=it.name}}
is equivalent to{{yield Promise.resolve(it.name)}}
opts
is an object with any subset of the following default values:
{
evaluate: /\{\{(([^\}]+|\\.)+)\}\}/g,
interpolate: /\{\{=\s*([^\}]+)\}\}/g,
stream: /\{\{~\s*([^\}]+)\}\}/g,
conditional: /\{\{\?(\?)?\s*([^\}]*)?\}\}/g,
node: typeof(process) === 'object',
noEval: false,
varname: "it"
}
evaluate
,interpolate
,stream
andconditional
are the RegExps for the previously mentioned template expressions.node
: Iftrue
, the generated code will be targeted for Node, otherwise for browsers.noEval
: Iftrue
, return the functions code instead of a callable.varname
: The name under which the data object is accessible in the template expressions.
Browser | Support | Links |
---|---|---|
Node | ✅ ≥5 | |
Chrome | ✅ ≥52 | |
Firefox | ⏰ In Development | Missing [ReadableStream] on fetch (https://bugzilla.mozilla.org/show_bug.cgi?id=1128959) |
Safari | ⏰ In Development | Missing TextDecoder (polyfillable) |
Edge | ⏰ In Development | Missing TextDecoder (polyfillable) and ReadableStream (polyfillable) |
- The parser itself is not streaming (i.e.
doT.compile()
cannot consume a stream). Currently, the body of a conditional cannot contain template expressions- Nested conditionals are not possible due to the RegExp-based nature of the parser
A fully runnable example can be found in the example
folder. It is a node webserver using streaming doT as a templating language. The website has a service worker that uses streaming doT as well.
To run the example, start the webserver by running node index.js
in the example
folder or visit https://streaming-dot-example.hyperdev.space/ for a hosted version of the example code (thanks HyperDev).
{{~it.header}}
<h1>This is a doT template</h1>
<h2>
This content was generated
{{?it.location}}
{{=it.location}}
{{??}}
server-side (refresh for ServiceWorker)
{{?}}
</h2>
{{~it.footer}}}
function handler(req, res) {
fs.readFile('app/index.dot', 'utf-8', (_, data) => {
var template = doT.compile(data);
var stream = template({
header: fs.createReadStream('app/header.partial.html'),
footer: fs.createReadStream('app/footer.partial.html'),
});
res.set('Content-Type', 'text/html');
stream.pipe(res)
});
}
self.onfetch = event => event.respondWith(
getTemplateSomehow()
.then(body => {
const template = doT.compile(body);
const response = template({
header: caches.match('/header.partial.html').then(r => r.body),
footer: caches.match('/footer.partial.html').then(r => r.body),
serviceworker: timeoutPromise(2000).then(_ => true)
});
return new Response(response, {headers: {'Content-Type': 'text/html'}});
);
Apache 2.0
Version 1.1.1