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:
| Field | Type | Description |
|---|---|---|
id | string | UUID (generated by OpenRegister) |
namespace | string | App namespace that owns the template (e.g. docudesk) |
name | string | Human-readable template name |
content | string | Twig/HTML content |
format | string | Page format for PDF output (A4, A3, Letter, Legal) |
orientation | string | Page 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:
| Field | Type | Description |
|---|---|---|
content | string | Template content to preview (inline mode) |
data | object | Sample 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 numberrestoreVersion()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.
| Method | Description |
|---|---|
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.
| Method | Description |
|---|---|
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.
| Method | Description |
|---|---|
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.
| Method | Description |
|---|---|
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:
| Setting | Description |
|---|---|
template_register | UUID of the OpenRegister register |
template_schema | UUID of the OpenRegister schema for templates |
template_version_schema | UUID of the schema for version objects |
Dependencies
| Dependency | Purpose |
|---|---|
OpenRegister | Object storage for templates and versions |
TemplateRenderer | Twig sandboxed rendering |
ObjectService | OpenRegister CRUD for objects |