@templatical/template-tools
v0.57.1
Published
CLI and library for Templatical email templates — validate, render, edit, import, and live-preview
Maintainers
Readme
@templatical/template-tools
CLI and library for Templatical email templates.
npx -y @templatical/template-tools validate .templatical/my-template.jsonCommands
| Command | What it does |
|---|---|
| validate <file> | Structural validation plus the accessibility / structure / link lint |
| render <file> --format mjml\|html | Render to MJML, or to sending-ready HTML |
| edit <file> --op <json> | Apply one operation, or a batch with --ops <file> |
| import <file> | Convert a template from another tool's export format — run import --list-formats to see what's supported |
| live | Open the template in the real editor in a browser |
| live --custom-block <file> [--host <template>] [--fetch [--values '<json>']] | Preview a custom block definition in the real editor, optionally inside a host template, with a state filled from the real endpoint |
| custom-block validate <file> | Check a custom block definition against its schema, its Liquid template, email-client safety and accessibility rules |
| custom-block render <file> | Render a custom block's specimen states to MJML (--format html for HTML, --state <name> for one state) |
| custom-block fetch <file> | Run the definition's dataSourcePreview recipe and print the response |
| schema | Print the block JSON Schema |
| list | List the working templates in .templatical/ |
Add --json to any command for machine-readable output on stdout.
Custom block output
Custom block templates HTML-escape {{ }}, {% echo %}, {% liquid %} echo and {% cycle %} output by default: &, <, >, " and ' become &, <, >, " and '. To render a field as HTML, write {{ body | raw }}. Always quote attribute values and validate URL schemes from untrusted sources; escaping does not validate URLs. The editor canvas also sanitizes rendered blocks; MJML and email output keep the template's HTML. Server-side rendering uses renderToMjml(content, { customBlocks: definitions }); a lower-level resolver uses the same engine:
import * as liquidjs from 'liquidjs';
import { createCustomBlockLiquid } from '@templatical/types';
const liquid = createCustomBlockLiquid(liquidjs);Install @templatical/types and liquidjs in the resolver project. See the Custom blocks guide for the renderer option and factory contracts. Data-source recipes retain an unescaped engine so JSON body quotes are preserved; use {{ key | json }} for JSON values.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success. Lint warnings may still be reported. |
| 1 | The template is invalid — structural errors, or a lint issue of severity error. |
| 2 | Usage error — bad flags, missing or unreadable input. |
| 3 | An optional dependency is missing. The message names the install command. |
Optional dependencies
Nothing is installed into your project by default. These commands can ask for an optional package:
render --format htmlandcustom-block render --format htmlneedmjml(the SDK bundles no MJML compiler).custom-block validatecompiles to HTML whenmjmlis installed and skips that check (with a note) when it isn't.importneeds the converter package for that format. Runimport --list-formatsto see which are resolvable right now — the list grows over time, so this is the only answer that doesn't go stale.
Install them wherever you run the command; they are resolved from your working directory.
Library use
import {
validateTemplate,
runQualityLint,
applyOperations,
checkCustomBlock,
} from "@templatical/template-tools";
import { startBridge } from "@templatical/template-tools/live";applyOperations is the operation engine edit runs, re-exported from @templatical/types with OperationError and getColumnCount. checkCustomBlock runs the same checks as custom-block validate, on a JSON working file or the object a definition module exports; validateCustomBlockDefinition runs only the structural check. The JSON Schema for a custom block definition is at @templatical/template-tools/custom-block-schema.json.
MIT.
