Widgets
Widgets are reusable pieces of HTML and logic that you can drop into any template. Think of them as mini-components.
What is a widget, exactly?
A widget is a Handlebars partial. A partial is just a reusable chunk of HTML. When you write {{> InvoiceStatus}} in your template, Handlebars replaces it with the HTML from the InvoiceStatus widget.
Some widgets also come with:
- CSS styles that get bundled with your template
- Helpers (JavaScript functions you can call from your template)
Available widgets
| Widget | What it does | How you use it |
|---|---|---|
| InvoiceStatus | Shows a colored status tag (Paid, Overdue, Draft, etc.) | {{> InvoiceStatus}} |
| DemoBadge | Shows a diagonal "Demo" watermark on the page | {{> DemoBadge}} |
| DateTime | Provides date formatting helpers with timezone support | {{formateShortDateWithOffset date offset}} |
| MarkdownViewer | Renders markdown text as styled HTML | {{> MarkdownViewer (prepareMarkdownViewerData text)}} |
How to use a widget in your template
Two steps:
1. Import it in your index.ts
import "../../widgets/invoice-status";
This runs the widget's code, which registers the Handlebars partial. Without this import, the {{> InvoiceStatus}} tag in your template will silently produce nothing.
2. Use it in your template.hbs
{{> InvoiceStatus}}
That is it. The widget handles the rest.
How widgets are built
Each widget lives in src/widgets/<name>/ and has:
src/widgets/invoice-status/
index.ts # Registers the partial and helpers
template.hbs # The HTML (optional, some widgets build HTML in JS)
styles.css # The styling (optional)
version.json # Auto-managed version
When a widget registers itself, it calls Handlebars.registerPartial():
Handlebars.registerPartial("InvoiceStatus", compiledHTML);
And optionally registers helpers with Handlebars.registerHelper():
Handlebars.registerHelper("computeInvoiceStatus", function(status, ...) {
// return computed data
});
Widget vs template
| Widget | Template | |
|---|---|---|
| What it is | A small, reusable piece | A full document layout |
| Registered as | Handlebars.registerPartial | window.CeresTemplate |
| Can be used by | Any template | Only the main renderer |
| Has its own CSS? | Yes | Yes |
| Has its own build output? | Yes (separate bundle) | Yes (separate bundle) |