Pro edition
Template
At a glance
Section titled “At a glance”NextPDF\Pro\Template parses a JSON template definition into a typed value
object and binds an associative data array to its placeholders with
type-aware formatting. It produces a structured binding result; it does not
render a PDF itself.
Availability & licensing
Section titled “Availability & licensing”This capability ships in NextPDF Pro (nextpdf/pro) and activates with a
Pro-tier license envelope. A deployment without that entitlement does not load the capability’s classes. No additional runtime
capability flag gates this module beyond the tier license.
Compare editions and get a license.
Install
Section titled “Install”composer require nextpdf/pro:^3Conceptual overview
Section titled “Conceptual overview”A template is a JSON document describing a page setup and a list of
positioned placeholders. TemplateParser validates the JSON and produces an
immutable TemplateDefinition. Validation is strict: it checks the page
size against an allow-list (A3–A6, B4, B5, Letter, Legal, Tabloid),
orientation (P or L), and each placeholder’s name, type, and numeric
coordinates, and it rejects duplicate placeholder names.
TemplateDataBinder binds a data array (matched case-insensitively to
placeholder names) and formats each value by PlaceholderType:
- Text / Image / Barcode — value passed through as a string.
- Date — formatted with the placeholder’s format (default
Y-m-d), accepting strings, Unix timestamps, orDateTimeInterface. - Number —
number_formatwith decimals from the format (default 2). - Currency — number formatted with the format string as a prefix
(default
$). - Conditional —
"true"or"false"based on truthiness.
The result is a BindingResult carrying the bound values, the list of
missing required fields, and any formatting warnings. Turning bound values
into a rendered PDF is the caller’s responsibility, using the Core document
and writer APIs and the optional backgroundPdf reference.
Why it works this way
Section titled “Why it works this way”The parser is the single authoritative gate. It turns untrusted JSON into an
immutable, fully typed TemplateDefinition, and binding then runs as a pure
function of that value. Every field that later reaches a formatting sink is
allow-listed and length-bounded at parse time. Page size, orientation, number
precision, and control characters all fail here, not mid-render. String dates
are matched against a fixed set of canonical formats, so a value like now or
+1 year cannot make output depend on the wall clock. The module stops
deliberately at a BindingResult and leaves rendering, path resolution, and
background compositing to the caller, which keeps the trust boundary explicit.
Design background: Invoices and e-invoicing.
Behavior contract
Section titled “Behavior contract”- Input. A JSON string (
TemplateParser) and a data array (TemplateDataBinder). - Output.
TemplateDefinitionfrom parsing;BindingResultfrom binding. - Validation.
validate()returns a list of human-readable errors and never throws;parse()throwsInvalidArgumentExceptionwhen validation fails. - Missing data. A placeholder with no data and an empty default is
reported in
missingFields; one with a non-empty default uses the default. - Determinism. Parsing and binding are pure functions of their inputs.
Public API surface
Section titled “Public API surface”| Type | Kind | Key members |
|---|---|---|
NextPDF\Pro\Template\TemplateParser | final class | parse(string $json): TemplateDefinition, validate(string $json): list<string> |
NextPDF\Pro\Template\TemplateDataBinder | final class | bind(TemplateDefinition $template, array $data): BindingResult |
NextPDF\Pro\Template\TemplateDefinition | final readonly class | string $name, string $pageSize, string $orientation, array $placeholders, string $backgroundPdf, getPlaceholder(string $name): ?TemplatePlaceholder, requiredFields(): list<string> |
NextPDF\Pro\Template\TemplatePlaceholder | final readonly class | name, PlaceholderType $type, coordinates, default, format |
NextPDF\Pro\Template\BindingResult | final readonly class | array $bindings, array $missingFields, array $warnings |
NextPDF\Pro\Template\PlaceholderType | enum | Text, Image, Barcode, Date, Number, Currency, Conditional; requiresFormatting(): bool |
Code sample — Quick start
Section titled “Code sample — Quick start”<?php
declare(strict_types=1);
use NextPDF\Pro\Template\TemplateDataBinder;use NextPDF\Pro\Template\TemplateParser;
$json = '{"name":"Invoice","pageSize":"A4","orientation":"P","placeholders":' . '[{"name":"total","type":"currency","x":400,"y":700,"width":120,' . '"height":18,"format":"$"}]}';
$template = (new TemplateParser())->parse($json);$result = (new TemplateDataBinder())->bind($template, ['total' => 1299.5]);
foreach ($result->bindings as $bound) { echo $bound->placeholder->name, ' => ', $bound->formattedValue, "\n";}Code sample — Production
Section titled “Code sample — Production”<?php
declare(strict_types=1);
use NextPDF\Pro\Template\TemplateDataBinder;use NextPDF\Pro\Template\TemplateParser;
function bindOrReject(string $json, array $data): array{ $parser = new TemplateParser();
$errors = $parser->validate($json); if ($errors !== []) { throw new InvalidArgumentException(implode('; ', $errors)); }
$template = $parser->parse($json); $result = (new TemplateDataBinder())->bind($template, $data);
if ($result->missingFields !== []) { throw new RuntimeException( 'missing required fields: ' . implode(', ', $result->missingFields), ); }
return $result->bindings; // hand to the renderer}Edge cases & gotchas
Section titled “Edge cases & gotchas”- An unparseable date string produces a warning and the original string is kept, rather than throwing.
- The currency format string is used as a literal prefix (for example
"$"or"EUR "), not a locale identifier. backgroundPdfis a path reference carried on the definition; this module does not open, validate, or composite it — that is the renderer’s job.- Placeholder names are matched case-insensitively; duplicate names in the JSON are a validation error.
Performance
Section titled “Performance”Parsing is one JSON decode plus structural validation; binding is linear in
placeholder count. See performance_budget.
Security notes
Section titled “Security notes”JSON is decoded with JSON_THROW_ON_ERROR and validated against fixed
allow-lists before a TemplateDefinition is constructed. The module performs
no file or network I/O; the backgroundPdf path is not dereferenced here, so
path handling and access control belong to the renderer.
Conformance
Section titled “Conformance”This module has no direct PDF-specification surface: it parses a JSON template and formats values. The page-size and orientation vocabularies are NextPDF conventions, not normative PDF constructs.
Core fallback / alternative
Section titled “Core fallback / alternative”There is no Core template-definition layer. For fully imperative document construction, use the open-source Core document and writer APIs directly. See /modules/core/document/.
Enterprise boundary note
Section titled “Enterprise boundary note”This module defines and binds templates. It does not perform mail-merge orchestration, batch job scheduling, or rendering; those concerns are out of scope and are handled elsewhere.
Publication boundary
Section titled “Publication boundary”This page documents externally observable behavior and the supported public API surface only. Internal namespace paths, helper classes, mechanism tables, runbook filenames, and ticket prefixes are out of scope.