Reference → PDF Templates — Reference

PDF Templates — Reference

The PDF Templates surface is the platform's PDF-generation plane. It owns the branded layout definitions the platform uses to render structured documents — invoices, receipts, proposals, contracts, reports — into PDF files on demand. The surface covers per-template layout authoring, variable substitution rules that bind a template to the data it renders, branding tokens (logo, color, font, address block), and the generation flow that turns a template plus a data record into a downloadable file.

This page is a reference for platform engineers and integrators who need to understand the surface before extending it, scripting against it, or wiring a workflow that emits a PDF (an order-paid hook, a contract-signed hook). Customer-facing how-tos live in the customer docs set; this page describes the shape of the surface, not the steps to drive it.


Overview

PDF templates live under the Settings → PDF Templates view in SG-Admin. The view renders three primary panels — the template list, the per-template authoring view (layout + variable bindings), and the preview generator that emits a sample PDF against a fixture record — and exposes write operations for creating, editing, cloning, and retiring templates.

The platform ships built-in templates for each PDF use case the platform itself emits: invoices, receipts, order confirmations, refund notices, and contract drafts. The built-ins are enabled by default and bound to the corresponding system events (an order paid → an invoice PDF; a refund issued → a refund-notice PDF). Built-ins can be edited but not deleted — disabling a built-in stops the emit without removing the template definition.

Custom templates are operator-defined and live alongside the built-ins. A custom template names a data source (the record type it expects), defines a layout (page size, header, footer, body sections), binds variable placeholders to fields on the data source, and exposes a generation endpoint that accepts a record id and returns the rendered PDF.

Where it lives in SG-Admin:

  • Sidebar: SG-Admin → Settings → PDF Templates
  • URL prefix: /sg-admin/settings/pdf-templates
  • View templates: application/views/Admin/Settings/pdf-templates-*.php
Branding tokens (logo, brand color, font) live on the adjacent Settings → Branding view and are inherited by every PDF template unless overridden — see Related references at the bottom of this page.
┌──────────────────────────────────────────────────────────────────────┐│ SG-Admin → Settings → PDF Templates [+ New custom] │├──────────────────────────────────────────────────────────────────────┤│ Built-in templates ││ Name Data source Page size Active ││ ────────────────── ─────────────────── ───────── ────── ││ Invoice Order A4 on ││ Receipt Order A4 on ││ Refund Notice Refund A4 on ││ Contract Draft Contract Letter on ││ ││ Custom templates ││ Name Data source Page size Active ││ ────────────────── ─────────────────── ───────── ────── ││ Proposal v3 Proposal A4 on ││ Monthly Report Report A4 on ││ Packing Slip Order 4x6 on ││ Annual Statement Account A4 off ││ ││ [⋯ Edit] [⋯ Preview PDF] [⋯ Clone] [⋯ Disable] │└──────────────────────────────────────────────────────────────────────┘

Actions

The PDF Templates surface exposes the following operations. Each is described by what it does to the template store and to the resulting PDFs, not by its internal method name.

List and search

Returns the templates visible to the current operator. Built-ins and customs are returned in two panels. Each entry shows name, data source, page size, and active state. Supports filtering by data source and by active / disabled.

Create custom template

Opens an empty authoring view. Required fields: name, data source (the record type the template renders), page size (A4, Letter, custom dimensions), orientation, and an initial layout. Optional fields: description, category, default font override, default margin override, and an event binding (the system event that should emit this template automatically).

Edit template

Loads an existing template into the authoring view. The view exposes three panels: layout (header / footer / body section structure), bindings (variable placeholders mapped to fields on the data source), and styling (font, color, spacing). Submit persists all three panels in one save.

Clone

Creates a copy of a template with a new name. Useful for building variants — a Proposal v3 plus a Proposal v3 — French version, or a standard invoice plus a packing-slip variant on a different page size. The clone is a new record; subsequent edits to the source do not propagate.

Disable

Marks a template inactive. Generation requests against a disabled template return a structured rejection. Event-bound built-ins emit nothing while disabled — the platform reverts to a minimal text receipt for the underlying event.

Delete (custom only)

Permanent removal. Built-ins cannot be deleted, only disabled. Deleting a custom also removes its event bindings.

Preview

Renders the template against a fixture record and returns the resulting PDF. The fixture record can be a real record (picked from the data source's list) or a synthetic fixture the surface ships with. Used as a sanity check before save and as an integration aid for downstream workflows that need to verify the rendered output.

Generate against a record

The runtime endpoint. Accepts a template id and a record id; returns the rendered PDF. The endpoint enforces that the record type matches the template's data source. Generation is logged in the Activity Log so an integration can audit when a given record was rendered.

Re-render on data change

For long-lived PDFs that should reflect the latest data (a regenerable contract, a refreshable monthly report), the surface exposes a re-render endpoint that emits the same PDF id against the latest data. Used by integrations that want the file URL to remain stable while the bytes update.

GENERATE REQUEST template_id + record_id│▼┌──────────────────────────────────────┐│ 1. Resolve template + record │ miss → reject│ (record type must match) │└─────────────────┬────────────────────┘▼┌──────────────────────────────────────┐│ 2. Walk layout │ header → body → footer│ For each placeholder ││ look up binding ││ fetch field from record ││ substitute value │└─────────────────┬────────────────────┘▼┌──────────────────────────────────────┐│ 3. Apply styling │ inherit brand tokens│ (template override > site brand) │ override per template└─────────────────┬────────────────────┘▼┌──────────────────────────────────────┐│ 4. Rasterize to PDF │ page-size + orientation└─────────────────┬────────────────────┘▼return application/pdflog generation event

Data model

A template record carries the following fields. Field names below are the conceptual shape — the on-disk column names match closely but are not contractually stable across releases.

FieldTypeNotes
idintegerPrimary key.
kindenumbuilt-in or custom.
namestringDisplay name.
descriptiontextOptional.
data_sourcestringRecord type slug — order, refund, contract, proposal, report, account, etc.
page_sizeenumA4, Letter, Legal, 4x6, or custom.
page_dimensionsobjectWidth / height when page_size = custom.
orientationenumportrait or landscape.
layoutobjectHeader / footer / body section definitions.
bindingsobjectVariable-placeholder map onto data-source fields.
stylingobjectFont, color, spacing, brand-token overrides.
event_bindingstringOptional. System event slug that auto-emits this template.
activebooleanWhen false, generation requests reject.
created_attimestampFirst save.
updated_attimestampTouched on edit.
Variable substitution: the bindings map declares placeholders like {{order.number}} or {{customer.name}} and maps each to a field path on the data source. At generation time, the renderer walks the layout, looks up each placeholder in the bindings, fetches the value from the record, and substitutes it. Missing values render as empty by default; the binding entry can mark a placeholder as required, in which case generation fails fast with a structured error naming the missing field.

Branding tokens: the styling block inherits from the site-wide Branding settings (logo, brand color, font, address block) unless the template overrides them. This means a brand-color change under Settings → Branding propagates into every PDF template that uses the default token, without touching template configuration.

INVOICE TEMPLATE · Data source: order┌──────────────────────────────────────────────────────────────────────┐│ [LOGO] INVOICE ││ {{site.name}} #{{order.number}} ││ {{site.address_block}} Issued {{order.date}}│├──────────────────────────────────────────────────────────────────────┤│ Bill to ││ {{customer.name}} ││ {{customer.address_block}} │├──────────────────────────────────────────────────────────────────────┤│ Item Qty Unit Total ││ ──────────────────────────── ───── ───────── ────────── ││ {{ for line in order.lines }} ││ {{line.title}} {{q}} {{u}} {{t}} ││ {{ endfor }} │├──────────────────────────────────────────────────────────────────────┤│ Subtotal {{order.subtotal}}││ Tax {{order.tax}} ││ Total {{order.total}} │├──────────────────────────────────────────────────────────────────────┤│ {{site.footer_block}} │└──────────────────────────────────────────────────────────────────────┘

Permissions

Access to the PDF Templates surface is gated at two layers.

Layer 1 — admin gate. Every action under SG-Admin passes through the platform's standard admin access check at request entry. An unauthenticated request never reaches the PDF Templates surface.

Layer 2 — per-action capability. Within SG-Admin, each PDF Templates action checks a capability associated with the calling operator's role. The default role configuration ships with three roles — Administrator, Editor, Viewer — and the capability map is:

CapabilityAdministratorEditorViewer
List templatesyesyesyes
Previewyesyesyes
Create customyesyesno
Edit built-inyesnono
Edit customyesyesno
Cloneyesyesno
Disableyesnono
Delete customyesnono
Bind to system eventyesnono
Generate against a recordyesyesno
Custom roles defined under Settings → Roles override the default map. The capability slugs are stable; the role slugs are configurable.

Self-protection rules. The surface refuses to disable a built-in that is currently the only template bound to a payment event without an explicit override; the override surfaces the consequence (the platform will emit minimal text receipts until a replacement template is bound).

Audit. Every write — create, edit, clone, disable, delete, event-bind change — emits an Activity Log entry. Every generation request also logs an entry (template id, record id, acting operator or system event source, timestamp). Activity Log retention is governed by the site's general settings.


Related references

  • Settings — Reference. Owns the Branding tokens (logo, brand color, font, address block) that PDF templates inherit, plus the role definitions and Activity Log retention.
  • Orders — Reference. Provides the order data source consumed by invoice, receipt, and packing-slip templates.
  • Refunds — Reference. Provides the refund data source consumed by the refund-notice template.
  • Contracts — Reference. Provides the contract data source for contract-draft templates.
  • Documents — Reference. Generated PDFs that need to persist on the site (a regenerable contract, a stored monthly report) are stored as records on the Documents surface and carry the same gate semantics.
  • Forms — Reference. Form submissions that emit a PDF (a custom proposal-builder form) bind into a custom template here.
For the corresponding customer-facing walkthrough — branding the invoice template, building a custom proposal layout, switching to a packing slip on a 4x6 sheet — see the Settings section of the customer docs at /docs/settings/pdf-templates.
On this page