Talisman
Talisman is a logicless streaming templating system and language for Node.js, created by Digital Design Labs.
Installing
npm install talismanjs --save
Streams FTW
Streams are awesome, and so Talisman is built to be used as a streaming template system. This means Talisman renders templates to a stream, which you can then pipe to a writable stream, like process.stdout
or http.ServerResponse
.
Why Streaming?
Templating systems will often wait to compute last byte of a page before sending the first one. This manifests for users as a blank white screen, while they wait for our application to query the database and perform other required IO, before generating HTML for the page.
By contrast, Talisman sends as much data as it can as soon as it can; so the user gets something up on their screen quickly. This improves the perceived performance of your application, and also means their browser can start fetching external resources sooner. This reduces overall page load time, as JavaScript, CSS, and images can be downloaded on the client in parallel with the database work being done on the server.
Syntax
Talisman uses a simple syntax, based around two concepts: blocks and variables.
Variables
Talisman allows you to define variable placeholders which will be later populated with data. They are enclosed by {{double}} {{curly}} {{braces}}
. Variables can be strings, streams, Buffers, or Promises for any of these.
// This will output:// Hello World!talisman;
Variables are automatically HTML escaped before they are displayed. You can request a variable be displayed raw by using a triple-brace instead of a double-brace, e.g. {{{varName}}}
.
// This will output:// Your name is <strong>World</strong>.// The markup was <strong>World</strong>.talisman;
Blocks
A block defines a section of template text. Blocks can used as loops (by assigning iterators to them); as condtionals (by removing them when some condition is met) or simply as a way of defining a scope. A block is inherently none of these; its behaviour depends on how you treat it. Like HTML, blocks may nest, but may not overlap.
// This will output:// <h1>Shopping List<h1>// <ul>// <li>Celery</li>// <li>Apples</li>// <li>Walnuts</li>// <li>Grapes</li>// </ul>const template = "<h1>Shopping List</h1>\n<ul>\n" + "{#row}<li>{{item}}</li>\n{/row}" + "{#norows}<li>I'm afraid we're fresh out of waldorfs...</li>\n{/norows}" + "</ul>"; const data = item: "Celery" item: "Apples" item: "Walnuts" item: "Grapes"; talisman;
Other Markers
There are two other markers supported, though you are unlikely to need to use them.
{/* */}
defines a comment. Anything placed between these markers will be removed by Talisman during rendering.{{CDATA[ ]}}
defines a block of non-template text. Anything between the square brackets will be ignored by Talisman, and rendered as-is.
Masks
Variables can have masks applied to them. Masks are small synchronous functions which transform the content in some way during rendering.
// This will output:// <h1>Price List<h1>// <ul>// <li>Celery: $1.00</li>// <li>Apples: $1.50</li>// <li>Walnuts: $1.25</li>// <li>Grapes: $0.75</li>// </ul>const template = "<h1>Price List</h1>\n<ul>\n" + "{#row}<li>{{item}}: {{price|format}}</li>\n{/row}" + "</ul>"; const data = item: "Celery" price: 1 item: "Apples" price: 15 item: "Walnuts" price: 125 item: "Grapes" price: 75; talisman;
Masks may also be chained, e.g. {{name|parseAsMarkdown|lowercase}}
Loading templates from files
In the examples so far, we have used createFromString()
, but usually you would load templates files from disk.
talisman;
You can also load templates into variables on another templates.
<!-- main.html -->{{pageTitle}}{{content}}
<!-- article.html -->{{pageTitle}}Posted: {{date|dateFormat}}{{bodyContent|makeParagraphs}}
talisman;
This would render:
<!-- main.html -->Talisman is awesome!<!-- article.html -->Talisman is awesome!Posted: 2016-06-20T10:23:00.000ZMy article bodyHas multiple lines
Minification
Minification is awesome. You can minify content from Talisman by piping the content through a transform stream.
const talisman = ;const Minifier = ; talisman;
The minify-html-stream
project currently is basic and very cautious. You can make it better.
Simple Demos
git clone https://github.com/digitaldesignlabs/talisman.gitcd talismannpm inpm run-script demo console
There is also a browser-based demo
npm run-script demo browser
License
Published under the MIT License.