Implementation:Spotify Luigi Mustache Templating
| Knowledge Sources | |
|---|---|
| Domains | Web_Visualiser, Templating |
| Last Updated | 2026-02-10 08:00 GMT |
Overview
Mustache.js is a vendored third-party logic-less templating library used by the Luigi web visualiser to render HTML templates for the task dependency graph interface and status displays.
Description
Mustache.js is a popular JavaScript implementation of the Mustache templating specification, a logic-less template system. It is vendored (bundled directly) within the Luigi repository to provide HTML template rendering for the Luigi web visualiser without external dependencies.
The library implements the Mustache specification with the following core features:
- Variable interpolation -- {{name}} tags are replaced with HTML-escaped values from the data context. Triple-mustache {{{name}}} or ampersand {{&name}} syntax outputs unescaped HTML.
- Sections -- {{#section}}...{{/section}} blocks render their content zero or more times depending on the truthiness of the context value. If the value is an array, the block is rendered once per element. If the value is a function, it is called with the raw template text and a rendering function.
- Inverted sections -- {{^section}}...{{/section}} blocks render only when the value is falsy, empty, or an empty array. Used for "no results" or fallback content.
- Partials -- {{>partial}} tags include and render another template, enabling template composition and reuse.
- Comments -- {{! comment }} tags are ignored during rendering.
- Custom delimiters -- {{=<% %>=}} syntax allows changing the tag delimiters to avoid conflicts with other templating systems.
The implementation consists of several internal components:
- Scanner -- A utility class that scans a string and extracts content between tag delimiters.
- Context -- A stack-based context object that supports nested lookups with dot notation (e.g., person.name) and parent context traversal.
- Writer -- The main rendering engine that parses templates into token trees, caches parsed results for performance, and recursively renders tokens against a context. Token types include text (text), variables (name), sections (#), inverted sections (^), and partials (>).
The main API consists of:
- Mustache.render(template, view, partials) -- Renders a template string with data and optional partials.
- Mustache.parse(template) -- Parses a template into tokens (useful for pre-compilation).
- Mustache.escape -- Configurable HTML escaping function.
External Documentation: Mustache.js GitHub Repository
Usage
This library is used internally by the Luigi web visualiser and is not intended to be imported or used directly by Luigi pipeline authors. The Luigi visualiser uses Mustache templates to render task details, dependency graphs, worker status tables, and other dynamic HTML content in the browser-based monitoring interface. The library is vendored to ensure consistent rendering behavior regardless of network availability.
Code Reference
Source Location
- Repository: Spotify_Luigi
- File: luigi/static/visualiser/lib/mustache.js
- Lines: 1-536
Signature
// Main API
mustache.name // "mustache.js"
mustache.version // version string
mustache.tags // default delimiters ["{{", "}}"]
mustache.render = function(template, view, partials) { ... }
mustache.parse = function(template, tags) { ... }
mustache.escape // function(string) - HTML escape function (configurable)
mustache.Scanner // Scanner constructor
mustache.Context // Context constructor
mustache.Writer // Writer constructor
// Writer methods
Writer.prototype.parse = function(template, tags) { ... }
Writer.prototype.render = function(template, view, partials) { ... }
Writer.prototype.renderTokens = function(tokens, context, partials, template) { ... }
// Context methods
Context.prototype.push = function(view) { ... }
Context.prototype.lookup = function(name) { ... }
// Scanner methods
Scanner.prototype.eos = function() { ... }
Scanner.prototype.scan = function(re) { ... }
Scanner.prototype.scanUntil = function(re) { ... }
Import
// Browser global (used by Luigi visualiser)
var html = Mustache.render(template, data);
// CommonJS / Node.js
var Mustache = require('./mustache');
// AMD / RequireJS
define(['./mustache'], function(Mustache) { ... });
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| template | string | Yes | A Mustache template string containing tags like {{name}}, {{#section}}, etc. |
| view | object | Yes | A JavaScript object (or nested object) providing the data context for template rendering |
| partials | object | No | An object mapping partial names to template strings for {{>partial}} inclusion |
Outputs
| Name | Type | Description |
|---|---|---|
| rendered HTML | string | The fully rendered HTML string with all tags replaced by their corresponding values from the view |
| tokens | array | When using parse(), an array of token arrays representing the parsed template structure |
Usage Examples
Basic Usage
// Simple variable substitution (as used in Luigi visualiser)
var template = '<div class="task-info">' +
'<h3>{{task_name}}</h3>' +
'<span class="status {{status_class}}">{{status}}</span>' +
'<p>Worker: {{worker}}</p>' +
'</div>';
var data = {
task_name: 'MyPipelineTask(date=2024-01-15)',
status: 'RUNNING',
status_class: 'running',
worker: 'worker-host-01'
};
var html = Mustache.render(template, data);
Sections and Iteration
// Rendering a list of task dependencies
var template = '<ul class="dependencies">' +
'{{#dependencies}}' +
' <li><a href="#task={{name}}">{{name}}</a> - {{status}}</li>' +
'{{/dependencies}}' +
'{{^dependencies}}' +
' <li>No dependencies</li>' +
'{{/dependencies}}' +
'</ul>';
var data = {
dependencies: [
{ name: 'UpstreamTaskA', status: 'DONE' },
{ name: 'UpstreamTaskB', status: 'RUNNING' },
{ name: 'UpstreamTaskC', status: 'PENDING' }
]
};
var html = Mustache.render(template, data);
Partials
var taskTemplate = '<div class="task">{{>taskHeader}}{{>taskBody}}</div>';
var partials = {
taskHeader: '<h3>{{name}}</h3><span>{{status}}</span>',
taskBody: '<div class="details"><p>Priority: {{priority}}</p></div>'
};
var html = Mustache.render(taskTemplate, {
name: 'ETLJob',
status: 'DONE',
priority: 5
}, partials);