Asynchronous templates for the browser and server (LinkedIn fork)
Core template rendering functionality providing callback-based and streaming output with asynchronous execution and error handling.
Renders a template with callback-based output, supporting both template names and compiled template functions.
/**
* Renders a template with callback-based output
* @param nameOrTemplate - Template name (string) or compiled template function
* @param context - Data context for template rendering
* @param callback - Callback function receiving (error, output)
*/
function render(
nameOrTemplate: string | TemplateFunction,
context: any,
callback: (err: Error | null, output?: string) => void
): void;Usage Examples:
const dust = require('dustjs-linkedin');
// Register a template first
const compiled = dust.compile('Hello {name}!', 'greeting');
dust.loadSource(compiled);
// Render by name
dust.render('greeting', { name: 'Alice' }, (err, output) => {
if (err) throw err;
console.log(output); // "Hello Alice!"
});
// Render with compiled function directly
const templateFn = dust.compileFn('Goodbye {name}!');
dust.render(templateFn, { name: 'Bob' }, (err, output) => {
if (err) throw err;
console.log(output); // "Goodbye Bob!"
});
// Complex context data
dust.render('greeting', {
name: 'Charlie',
items: ['apple', 'banana'],
user: { active: true, role: 'admin' }
}, (err, output) => {
if (err) throw err;
console.log(output);
});Returns a readable stream for template output, enabling streaming responses and real-time data processing.
/**
* Returns a readable stream for template output
* @param nameOrTemplate - Template name (string) or compiled template function
* @param context - Data context for template rendering
* @returns DustStream instance with event emitter interface
*/
function stream(
nameOrTemplate: string | TemplateFunction,
context: any
): DustStream;
interface DustStream {
/** Attach data event listener for rendered chunks */
on(event: 'data', callback: (chunk: string) => void): DustStream;
/** Attach error event listener for rendering errors */
on(event: 'error', callback: (error: Error) => void): DustStream;
/** Attach end event listener for rendering completion */
on(event: 'end', callback: () => void): DustStream;
/** Emit events to listeners */
emit(type: string, data?: any): boolean;
/** Pipe stream to writable stream */
pipe(writable: any): any;
}Usage Examples:
// Stream to stdout
dust.stream('greeting', { name: 'David' })
.on('data', chunk => process.stdout.write(chunk))
.on('end', () => console.log('\n-- Done --'))
.on('error', err => console.error('Error:', err));
// Pipe to HTTP response
app.get('/template', (req, res) => {
res.setHeader('Content-Type', 'text/html');
dust.stream('page', { user: req.user })
.pipe(res);
});
// Collect streamed data
let result = '';
dust.stream('greeting', { name: 'Eva' })
.on('data', chunk => result += chunk)
.on('end', () => {
console.log('Complete output:', result);
});Functions for registering templates in the cache and loading compiled template source.
/**
* Registers a compiled template in the cache
* @param name - Template name for later reference
* @param compiledTemplate - Compiled template function
*/
function register(name: string, compiledTemplate: TemplateFunction): void;
/**
* Loads and executes compiled template source code
* @param source - String of compiled JavaScript template code
* @returns Template function
*/
function loadSource(source: string): TemplateFunction;Usage Examples:
const dust = require('dustjs-linkedin');
// Manual template registration
const templateFn = dust.compileFn('Hello {name}!');
dust.register('manual-greeting', templateFn);
// Load compiled source
const compiledSource = dust.compile('Goodbye {name}!', 'farewell');
const loadedTemplate = dust.loadSource(compiledSource);
// Templates are now available by name
dust.render('manual-greeting', { name: 'Grace' }, console.log);
dust.render('farewell', { name: 'Henry' }, console.log);Low-level chunk methods for custom template logic and rendering operations.
/**
* Core chunk methods for template rendering control
*/
interface ChunkMethods {
/** Map over chunk with callback function */
map(callback: (chunk: Chunk) => any): Chunk;
/** Apply output transformation */
tap(tap: Function): Chunk;
untap(): Chunk;
/** Render variable reference with filters */
reference(elem: any, context: Context, auto?: string, filters?: string[]): Chunk;
/** Render template section (loops, conditionals) */
section(elem: any, context: Context, bodies: Bodies, params?: Params): Chunk;
/** Conditional rendering - exists */
exists(elem: any, context: Context, bodies: Bodies): Chunk;
/** Conditional rendering - not exists */
notexists(elem: any, context: Context, bodies: Bodies): Chunk;
/** Render template block */
block(elem: Function, context: Context, bodies: Bodies): Chunk;
/** Render partial template */
partial(elem: string | Function, context: Context, partialContext?: Context, params?: Params): Chunk;
/** Call helper function */
helper(name: string, context: Context, bodies: Bodies, params?: Params, auto?: string): Chunk;
/** Handle promise/thenable objects */
await(thenable: any, context: Context, bodies: Bodies, auto?: string, filters?: string[]): Chunk;
/** Handle stream objects */
stream(stream: any, context: Context, bodies: Bodies, auto?: string, filters?: string[]): Chunk;
/** Capture template output */
capture(body: Function, context: Context, callback: (output: string, chunk: Chunk) => any): Chunk;
/** Set error state */
setError(err: Error): Chunk;
}Optional custom template loading function for dynamic template resolution.
/**
* Custom template loader function (optional)
* Called when template not found in cache
*/
dust.onLoad?: (
name: string,
callback: (err: Error | null, template?: string | TemplateFunction) => void
) => void;
// Alternative signature with options
dust.onLoad?: (
name: string,
options: any,
callback: (err: Error | null, template?: string | TemplateFunction) => void
) => void;Usage Examples:
// File-based template loader
const fs = require('fs');
const path = require('path');
dust.onLoad = (name, callback) => {
const templatePath = path.join('./templates', name + '.dust');
fs.readFile(templatePath, 'utf8', (err, source) => {
if (err) return callback(err);
try {
const compiled = dust.compile(source, name);
callback(null, compiled);
} catch (compileErr) {
callback(compileErr);
}
});
};
// Now templates load automatically from filesystem
dust.render('user-profile', { user: userData }, (err, output) => {
// Will automatically load ./templates/user-profile.dust
console.log(output);
});
// HTTP-based template loader
dust.onLoad = (name, callback) => {
const templateUrl = `https://templates.example.com/${name}.dust`;
fetch(templateUrl)
.then(response => response.text())
.then(source => {
const compiled = dust.compile(source, name);
callback(null, compiled);
})
.catch(callback);
};/**
* Template cache storage
* Keys: Template names, Values: Compiled template functions
*/
const cache: { [templateName: string]: TemplateFunction };Usage Examples:
// Check if template is cached
if (dust.cache['my-template']) {
console.log('Template is cached');
}
// Clear specific template from cache
delete dust.cache['old-template'];
// Clear all templates from cache
dust.cache = {};
// List all cached templates
console.log('Cached templates:', Object.keys(dust.cache));All rendering functions handle errors through callbacks or stream error events:
// Callback error handling
dust.render('template-name', context, (err, output) => {
if (err) {
console.error('Rendering error:', err.message);
console.error('Stack:', err.stack);
} else {
console.log('Success:', output);
}
});
// Stream error handling
dust.stream('template-name', context)
.on('error', err => {
console.error('Stream error:', err.message);
})
.on('data', chunk => console.log(chunk))
.on('end', () => console.log('Complete'));Common error types:
onLoad handlerInstall with Tessl CLI
npx tessl i tessl/npm-dustjs-linkedin