Skip to main content

Advanced Template Management

DocuDesk extends basic template CRUD with version history, live preview, template duplication, and optimistic locking. All templates are stored as OpenRegister objects and rendered via a Twig sandbox.

Overview

The advanced template management feature provides:

  • CRUD operations — Create, read, update, and delete Twig/HTML templates
  • Version history — Every update creates an immutable version snapshot enabling rollback
  • Diff between versions — Compare any two versions of a template
  • Live preview — Render a template with sample data without persisting the result
  • Duplication — Clone an existing template as a starting point
  • Optimistic locking — Lock a template during editing to prevent concurrent overwrites

API Endpoints

Template CRUD

GET    /apps/docudesk/api/templates
POST /apps/docudesk/api/templates
GET /apps/docudesk/api/templates/{id}
PUT /apps/docudesk/api/templates/{id}
DELETE /apps/docudesk/api/templates/{id}

Template object fields:

FieldTypeDescription
idstringUUID (generated by OpenRegister)
namespacestringApp namespace that owns the template (e.g. docudesk)
namestringHuman-readable template name
contentstringTwig/HTML content
formatstringPage format for PDF output (A4, A3, Letter, Legal)
orientationstringPage orientation (P portrait, L landscape)

Version History

GET  /apps/docudesk/api/templates/{id}/versions
POST /apps/docudesk/api/templates/{id}/versions/{versionId}/restore
GET /apps/docudesk/api/templates/{id}/versions/diff

List versions

Returns all version snapshots for a template, newest first.

[
{
"id": "version-uuid",
"templateId": "template-uuid",
"versionNumber": 3,
"createdAt": "2025-01-15T10:30:00Z",
"content": "<p>Previous content...</p>"
}
]

Restore a version

Restores the template content to a previous version. The current content is automatically saved as a new version before the restore.

Request body:

{ "versionId": "version-uuid" }

Diff two versions

GET /apps/docudesk/api/templates/{id}/versions/diff?from={versionId}&to={versionId}

Returns a line-by-line diff between two version snapshots.


Preview

POST /apps/docudesk/api/templates/preview
POST /apps/docudesk/api/templates/{id}/preview

Renders a template with sample data and returns HTML. No document is persisted.

Request body:

FieldTypeDescription
contentstringTemplate content to preview (inline mode)
dataobjectSample data context for Twig rendering

When using {id}/preview, the template content is loaded from the stored template.


Duplicate

POST /apps/docudesk/api/templates/{id}/duplicate

Creates a copy of the template with (copy) appended to the name. Returns the new template object.


Locking

POST   /apps/docudesk/api/templates/{id}/lock
DELETE /apps/docudesk/api/templates/{id}/lock

Locks a template for the current user to prevent concurrent edits. An attempt to update a locked template by a different user returns HTTP 423 (Locked).

Lock response:

{
"locked": true,
"lockedBy": "admin",
"lockedAt": "2025-01-15T10:30:00Z"
}

Version Control Behaviour

  • A version snapshot is created automatically on every PUT /api/templates/{id} call
  • Up to the last 20 versions are kept per template by default
  • TemplateVersionService::getNextVersionNumber() calculates a monotonically increasing version number
  • restoreVersion() saves the current state as a new version before restoring the target

Twig Sandbox

All template content is rendered inside a Twig sandbox (TemplateRenderer). The sandbox restricts available functions and tags to a safe whitelist, preventing server-side code execution from template content.

Conditional section shorthand is also supported:

[if variable]...content...[/if]

This is converted to {% if variable %}...{% endif %} before rendering.

Services

TemplateService

Core CRUD service for templates stored in OpenRegister.

MethodDescription
getTemplates()List all templates with pagination
getTemplate(id)Get a single template by UUID
createTemplate(data)Validate and create a new template
updateTemplate(id, data)Update a template (triggers version save)
deleteTemplate(id)Delete a template
getTemplatesByNamespace(ns)Filter templates by namespace

TemplateVersionService

Manages version history snapshots in OpenRegister.

MethodDescription
createVersion()Save a version snapshot before update
getVersions()List versions for a template
getVersion()Get a single version by ID
restoreVersion()Restore template to a previous version
getDiff()Return line diff between two version IDs
getNextVersionNumber()Calculate next monotonic version number

TemplatePreviewService

Renders templates with sample data for live preview.

MethodDescription
preview()Render inline template content with data
previewTemplate()Fetch stored template by ID and render with data

TemplateRenderer

Twig sandbox engine used by all rendering paths.

MethodDescription
renderTemplate()Render Twig template string with data context
convertConditionalSections()Convert [if]...[/if] to Twig syntax

Configuration

Templates are stored using the OpenRegister template_register and template_schema settings configured in DocuDesk admin:

SettingDescription
template_registerUUID of the OpenRegister register
template_schemaUUID of the OpenRegister schema for templates
template_version_schemaUUID of the schema for version objects

Dependencies

DependencyPurpose
OpenRegisterObject storage for templates and versions
TemplateRendererTwig sandboxed rendering
ObjectServiceOpenRegister CRUD for objects