Handlebars Chart Plugin#
Overview#
The Handlebars chart plugin (@superset-ui/plugin-chart-handlebars) renders query results using a user-authored Handlebars template, enabling fully custom HTML or Markdown output inside a dashboard panel . It is registered as chart type "handlebars" via the HandlebarsChartPlugin class, which lazily loads the main component and wires up buildQuery, controlPanel, and transformProps.
Key Files#
| File | Purpose |
|---|---|
src/Handlebars.tsx | Top-level React component; assembles templateSource from form data |
src/components/Handlebars/HandlebarsViewer.tsx | Compiles & renders the template; registers helpers; wraps output in SafeMarkdown |
src/plugin/controlPanel.ts | Defines the Handlebars Template and CSS Styles editor controls |
src/plugin/transformProps.ts | Passes width, height, formData, and data to the component |
src/plugin/index.ts | Plugin class, metadata, and dynamic chart loader |
Rendering Pipeline#
-
Query — Supports Aggregate (groupby + metrics) and Raw (all columns) modes controlled by a
queryModeradio toggle on the control panel . -
Template assembly —
Handlebars.tsxreadsformData.handlebarsTemplate(defaulting to{{data}}) and optionally wrapsformData.styleTemplatein a<style>tag, then concatenates them into onetemplateSourcestring. -
Handlebars compilation —
HandlebarsViewercallsHandlebars.compile(templateSource)and executes it with{ data }, wheredatais the query result array. Compilation errors surface as a<pre>block. -
SafeMarkdown rendering — The rendered string is passed to
SafeMarkdown, which processes Markdown and sanitizes HTML usingrehype-sanitize(with the GitHub schema as baseline). Sanitization behavior is controlled by theHTML_SANITIZATIONandHTML_SANITIZATION_SCHEMA_EXTENSIONSbootstrap config keys .
Built-in Handlebars Helpers#
All helpers are registered in HandlebarsViewer.tsx. The plugin also pulls in just-handlebars-helpers and handlebars-group-by as third-party helper libraries.
| Helper | Signature | Notes |
|---|---|---|
dateFormat | {{dateFormat date format="MMMM YYYY"}} | Uses dayjs; default format YYYY-MM-DD |
stringify | {{stringify myObj}} | JSON-stringifies plain objects; calls String() otherwise |
formatNumber | {{formatNumber num locale="en-US"}} | Calls toLocaleString; passes through non-numbers |
parseJson | {{parseJson jsonString}} | Parses a JSON string; throws on invalid input |
Control Panel#
Two editor controls are exposed under the Options section:
- Handlebars Template (
handlebars_template) — A code editor (dark theme) with a default template of{{#each data}}{{stringify this}}{{/each}}. Non-empty validation is enforced . - CSS Styles (
styleTemplate) — An optional CSS code editor. An info tooltip warns that raw<style>injection requires HTML sanitization to be properly configured .
HTML Sanitization#
The plugin reads HTML_SANITIZATION (default true) and HTML_SANITIZATION_SCHEMA_EXTENSIONS from the Superset bootstrap data at runtime . These are forwarded to SafeMarkdown, which applies rehype-sanitize using the GitHub HTML schema. Schema extensions merge via array concatenation — new allowlist entries are added to rather than replacing the defaults . When the EscapeMarkdownHtml feature flag is on, react-markdown's native escaping takes precedence over the sanitizer .
To allow additional HTML attributes or tags in template output, configure HTML_SANITIZATION_SCHEMA_EXTENSIONS in superset_config.py.