A Comprehensive Guide to Using doT.js
doT.js is a minimalistic yet powerful JavaScript templating engine designed for Node.js and browsers. Known for being extremely fast and concise, doT.js emphasizes performance, especially in environments like V8 and Node.js. It is a dependency-free library with only 120 lines of code, making it a lean and efficient choice for rendering dynamic content. This post will cover everything you need to know to start using doT.js, including installation, syntax, and real-world examples.
Why Choose doT.js?
doT.js was created to provide a fast and easy-to-use templating engine that works well in both server-side (Node.js) and client-side environments. Here are some reasons to consider it:
Performance: doT.js is one of the fastest template engines available.
No Dependencies: It is lightweight, without external dependencies.
Customizable: You can adjust delimiters and use features like runtime and compile-time evaluation.
Flexibility: Works in both logic-less mode and with full logic, making it adaptable for different use cases.
Key Features
No dependencies (120 LOC)
Blazing fast performance
Custom delimiters for flexibility
Runtime & compile-time evaluation
Partials and include support
Conditionals and iterators for dynamic logic
Encoding to avoid XSS vulnerabilities
Whitespace control (strip or preserve)
Streaming-friendly
Installation
For Node.js
You can install doT.js using npm:
npm install dot
Once installed, require it in your code:
const doT = require('dot');
For Browsers
Simply include the JavaScript file in your HTML file:
<script src="doT.js"></script>
Basic Usage
To begin using doT.js, you first need to compile a template and then render it with data.
1. Compile a Template
const templateFunction = doT.template("<h1>Hello, {{=it.name}}</h1>");
{{=
it.name
}}
is used to interpolate the name
property from the provided data.
2. Render the Template with Data
const result = templateFunction({ name: "World" });
console.log(result); // <h1>Hello, World</h1>
doT.js Syntax and Delimiters
By default, doT.js uses the following delimiters:
{{ }}
: for evaluation (JavaScript logic){{= }}
: for interpolation (inserting variables){{! }}
: for interpolation with encoding (to prevent XSS){{# }}
: for compile-time evaluation or partials{{## #}}
: for compile-time defines{{? }}
: for conditionals{{~ }}
: for array iteration
You can modify these delimiters by adjusting doT.templateSettings
.
Conditional Rendering
const conditionTemplate = doT.template("{{? it.show }}Hello, {{=it.name}}{{?}}");
console.log(conditionTemplate({ show: true, name: "Alice" })); // "Hello, Alice"
console.log(conditionTemplate({ show: false, name: "Bob" })); // ""
{{?
it.show
}}
checks if the show
property is true
. If so, the text will be displayed; otherwise, it remains hidden.
Array Iteration
const listTemplate = doT.template("<ul>{{~it.items :item:index}}<li>{{=item}}</li>{{~}}</ul>");
const result = listTemplate({ items: ["Item 1", "Item 2", "Item 3"] });
console.log(result); // <ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>
{{~it.items :item:index}}
iterates over the items
array, rendering each item inside a <li>
tag.
Advanced Features
Compile-Time vs Runtime Evaluation
Compile-time evaluation can improve performance when rendering static content, or when including partials like headers or footers that don't change frequently.
Compile-Time Example:
const headerTemplate = doT.template("{{#def.header}}<h1>{{=it.title}}</h1>{{#def.footer}}", null, { header: "<header>Header</header>", footer: "<footer>Footer</footer>" });
const result = headerTemplate({ title: "Welcome" });
console.log(result); // <header>Header</header><h1>Welcome</h1><footer>Footer</footer>
Custom Delimiters
If you need to use custom delimiters, you can modify doT.templateSettings
.
doT.templateSettings = {
evaluate: /\[\[([\s\S]+?)\]\]/g,
interpolate: /\[\[=([\s\S]+?)\]\]/g,
};
Now, instead of using {{ }}
, you can use [[ ]]
.
Partials Support
Partials are useful for reusing common parts of a template, like headers or footers. You can define partials using {{#def}}
syntax.
Precompiling Templates for Production
You can precompile templates for performance optimization. This feature is especially useful when deploying in Node.js or for client-side rendering in browsers.
const dots = require("dot").process({ path: "./views" });
const render = require('./views/mytemplate');
console.log(render({ foo: "Hello, world" }));
Examples
Here are additional samples based on the existing DoT.js template structure.
<div class="user-profile">
{{? it.isLoggedIn }}
<h3>Welcome, {{=it.username}}!</h3>
{{? it.showEmail}}<p>Email: {{=it.email}}</p>{{?}}
{{? it.showAddress}}<p>Address: {{=it.address}}</p>{{?}}
<a href="/logout" class="logout-btn">Logout</a>
{{??}}
<p>You are not logged in.</p>
<a href="/login" class="login-btn">Login</a>
{{?}}
</div>
This template dynamically checks if a user is logged in and optionally displays their email and address if available. If the user is not logged in, it shows a login button.
<div class="product-list">
{{~ it.products :product}}
<div class="product-item">
<h4>{{=product.name}}</h4>
<p>Price: ${{=product.price}}</p>
{{? product.isDiscounted}}
<p>Discount: {{=product.discount}}%</p>
{{?}}
<a href="/product/{{=product.id}}" class="view-product">View Product</a>
</div>
{{~}}
</div>
This template loops through a list of products and shows the product name and price. If a product is discounted, it displays the discount percentage.
<div class="blog-post">
<h2>{{=it.title}}</h2>
<p>{{=it.content}}</p>
{{? it.tags.length > 0}}
<ul class="tags">
{{~ it.tags :tag}}
<li>{{=tag}}</li>
{{~}}
</ul>
{{?}}
</div>
A blog post template displays the title and content. If there are tags associated with the post, it renders a list of tags.
doT.js is a lightweight, fast, and flexible templating engine, ideal for developers looking to optimize both server-side and client-side rendering. Whether you're working on a simple app or need a high-performance solution for rendering dynamic content, doT.js offers powerful features that can be customized to fit your needs. From compile-time evaluation to runtime flexibility, this templating engine can handle a wide range of use cases with minimal setup and blazing-fast performance.
Happy coding with doT.js!
Subscribe to my newsletter
Read articles from Nirmal Sankalana directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by