inmake DOCS
Docs / Generative / Store template

Store template

The "store-template" rule fragment — composed into the CRM & Studio agents' prompts and served as drop-core://rules/store-template.

OUTPUT CONTRACT: the template source is ONE complete HTML document — <!doctype html> through </html> — stored whole in the record's data field. There is no separate CSS/JS split: put all styles inline on elements or in <style> blocks in the <head>. No external stylesheets, fonts, scripts or CDNs, and NO JavaScript — the document is rendered server-side into invoices/PDFs and outgoing e-mails, where scripts never run.

DATA BINDING: the source is rendered server-side with Handlebars against a flat context. HELPERS — ONLY the following are registered. Using ANY other helper (e.g. eq, add, gt, and, concat, formatDate, capitalize) throws at render time and the WHOLE document fails to render:

  • Built-ins: {{#if x}}…{{else}}…{{/if}}, {{#unless x}}, {{#each list}}…{{/each}} (inside each: {{this}}, {{@index}}, {{@first}}, {{@last}}), {{#with obj}}, {{lookup obj key}}.
  • (multiply a b) — e.g. a line total: {{multiply amount unit_price}}.
  • Block equality: {{#ifEq a b}}…{{else}}…{{/ifEq}} (this is the ONLY comparison available — there is no eq/gt subexpression).

INVOICE CONTEXT — when the template renders an invoice/receipt, these variables exist (flat, at the root):

  • id, number (invoice number), order (order id), invoice_date, payment_type, store, note, currency.
  • Money: price (net of credits), total (gross), credits, price_exvat. All already formatted per store setup.
  • items — array of {name, amount, unit_price, vat}; unit_price is VAT-inclusive; line total = {{multiply amount unit_price}}.
  • vats — per-rate VAT breakdown, array of {rate, base, amount}; it is UNDEFINED when no item carries a rate — always guard with {{#if vats}}.
  • Customer: customer_name, customer_street, customer_zip, customer_city, customer_email, customer_id_number, customer_tax_number.
  • Vendor/business: the same shape under business_* (alias vendor_*).
  • Store setup values flatten to setup_*; order metadata to metadata_*.

NON-INVOICE templates (welcome mail, order confirmation, custom notifications) render against the variables their trigger supplies. Bind ONLY to fields the user names or that appear in the current source — NEVER invent context fields; an unknown variable renders as empty text.

SAMPLE DATA: each template record carries an optional sample — a JSON object of render variables the admin editor previews the source against (its Sample tab). Rendering and mailing NEVER read it; without one the preview falls back to a sample INVOICE context, so a non-invoice template previews with empty variables. Set it with writeStoreTemplate's sample argument (it REPLACES the stored sample whole; data may then be omitted):

  • Shape it exactly like the context the template's sender passes: the same flat keys the source binds ({{name}} → "name", {{#each items}} → an array of objects with the keys used inside the block, {{#if x}} guards → include x so the guarded part shows). Invoice templates use the INVOICE CONTEXT keys above (plus payment_* for a transfer block).
  • Realistic, locale-appropriate values (names, addresses, dates as the sender formats them, absolute https:// URLs) — never real customer data, tokens or secrets.
  • Write a sample whenever you create a template, when you add a binding the current sample lacks, or when the user asks for preview data. Each locale record has its own sample; fill the locale you write.

EMAIL-SAFE RULES (apply whenever e-mail delivery is enabled for this template): e-mail clients ignore most modern CSS — use a table-friendly layout, put critical CSS inline on elements, wrap content in a single container of max-width 600–640px, stick to web-safe font stacks (Arial/Helvetica/Georgia + generic fallback), and reference no external images the current source doesn't already use.

EDIT DISCIPLINE: the CURRENT TEMPLATE SOURCE shown in your context is the ground truth — start from it VERBATIM, change only what the request names, and resubmit the FULL document via writeStoreTemplate. Every other section, style and {{ binding }} must survive byte-for-byte. Never restyle, rebuild or "improve" parts the user did not mention.