Skip to content
getnextpdf.com

Pro edition

Template — Deep Reference

This deep reference documents the accepted JSON template schema, every validation rule, and the exact per-type formatting behavior of the data binder. The module parses a template definition, then binds caller data to typed placeholders. It emits formatted strings; it does not draw PDF objects.

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 runtime capability flag gates this module. Compare editions and get a license.

The module exposes two entry-point services and four immutable value objects. Every symbol below is public and stable.

SymbolParametersDefault behaviorReturnsThrows or fails withNotes
TemplateParser::parsestring $jsonValidates, then builds the definitionTemplateDefinitionInvalidArgumentException when any validation error is presentDelegates to validate first.
TemplateParser::validatestring $jsonCollects all structural errors in one passlist<string> (empty when valid)Never throws; a JSON decode failure is returned as a messageAuthoritative gate for length and precision bounds.
TemplateDataBinder::bindTemplateDefinition $template, array<string,mixed> $dataMatches placeholders case-insensitively and formats by typeBindingResultNever throws; anomalies become warnings or missing fieldsUses a placeholder default value when the key is absent.
TemplateDefinition::__constructstring $name, string $pageSize, string $orientation, list<TemplatePlaceholder> $placeholders, string $backgroundPdf = ''Stores the parsed definitionTemplateDefinitionTypeError on an argument type mismatchFinal readonly value object.
TemplateDefinition::getPlaceholderstring $nameCase-insensitive lookup by nameTemplatePlaceholder|nullNo failure; returns null when absent
TemplateDefinition::requiredFieldsnoneCollects names of placeholders that have no default valuelist<string>No failureA non-empty default marks a placeholder optional.
TemplatePlaceholder::__constructstring $name, PlaceholderType $type, float $x, float $y, float $width, float $height, string $defaultValue = '', string $format = ''Stores one placeholder regionTemplatePlaceholderTypeError on an argument type mismatchCoordinates are points from the top-left.
TemplatePlaceholder::matchesstring $keyCase-insensitive name comparisonboolNo failure
BindingResult::__constructlist<BoundPlaceholder> $bindings, list<string> $missingFields, list<string> $warningsStores the binding outcomeBindingResultTypeError on an argument type mismatchFinal readonly value object.
BindingResult::isCompletenoneReports whether every required field was boundboolNo failureTrue when missingFields is empty.
BindingResult::countnoneCounts successfully bound placeholdersintNo failure
BoundPlaceholder::__constructTemplatePlaceholder $placeholder, string $formattedValue, mixed $rawValuePairs a placeholder with its formatted valueBoundPlaceholderTypeError on an argument type mismatchFinal readonly value object.
PlaceholderTypeenum cases Text, Image, Barcode, Date, Number, Currency, ConditionalString-backed placeholder taxonomyenum instanceValueError from from() on an unknown valuetryFrom() returns null instead.
PlaceholderType::requiresFormattingnoneReports whether the type consumes a format stringboolNo failureTrue for Date, Number, Currency.
final class TemplateParser
{
public function parse(string $json): TemplateDefinition;
public function validate(string $json): array;
}
final class TemplateDataBinder
{
public function bind(TemplateDefinition $template, array $data): BindingResult;
}

Accepted JSON shape:

{
"name": "string (required, non-empty)",
"pageSize": "A3|A4|A5|A6|B4|B5|Letter|Legal|Tabloid",
"orientation": "P|L",
"backgroundPdf": "optional path string",
"placeholders": [
{ "name": "string", "type": "text|image|barcode|date|number|currency|conditional",
"x": number, "y": number, "width": number, "height": number,
"defaultValue": "optional", "format": "optional" }
]
}

Validation rules, all surfaced by validate as messages and aggregated by parse into one exception:

  • Missing or empty name.
  • pageSize outside the allow-list, or orientation not P or L.
  • Missing placeholders, or a non-array value.
  • Per placeholder: missing or empty name; invalid type; missing or non-numeric x, y, width, height; duplicate name (case-insensitive).
  • defaultValue: non-string, longer than 4096 bytes, or carrying an ASCII control character.
  • format: non-string, longer than 256 bytes, or carrying an ASCII control character.
  • A number placeholder format that is not a non-negative integer, or that exceeds 30.

Binding semantics (TemplateDataBinder::bind):

  • Data keys are lower-cased for case-insensitive matching against placeholder names.
  • An absent key with a non-empty default binds the default; an absent key without one is reported in missingFields.
  • Text, image, and barcode values are cast to string unchanged.
  • Date binding accepts a DateTimeInterface, an integer Unix timestamp, or a string in one of four explicit formats. The default output format is Y-m-d.
  • Number binding uses number_format(value, decimals, '.', ','). The decimal count comes from format, defaults to 2, and is bounded to the range 0 through 30.
  • Currency binding prefixes the formatted number with format, defaulting the prefix to $.
  • Conditional binding emits "true" or "false" from a boolean cast.
  • backgroundPdf is never opened or dereferenced by this module. It is an opaque string handed to the renderer.
  • A non-numeric value bound to a Number or Currency placeholder produces a warning; the value is string-cast, not rejected.
  • Date strings are parsed strictly. Relative and natural-language tokens (“now”, “+1 year”, “tomorrow”) match no accepted format, so they warn and the raw value passes through unchanged.
  • An integer date value is read as a Unix timestamp via the @ epoch form.
  • A Number format precision outside 0 through 30 that reaches the binder is rejected with a warning; the binder falls back to the default precision of 2.
  • No cryptographic operation occurs in this module, so there is no FIPS-mode specific behavior.

No direct PDF-specification surface exists. Page-size and orientation vocabularies are NextPDF conventions, and the module emits formatted values, not PDF objects. The strict string-date allow-list accepts the Internet date/time profile of ISO 8601 defined in RFC 3339 §5.6, alongside a Y-m-d calendar date and two local date-time forms. NextPDF documents the capability to read these formats; it claims no certification against RFC 3339 or ISO 8601.

  • TemplateParser and TemplateDataBinder are stateless. A single instance is reusable and safe to share across bindings.
  • The four value objects are final readonly; construct them through the parser rather than by hand for production input.
  • validate reports every structural error in one pass, while parse calls validate first and throws on the aggregated message. Use validate for form-style feedback and parse for fail-fast ingestion.
  • The length and precision bounds are enforced at the parser as the authoritative gate. TemplateDataBinder re-checks the number precision as a sink-side guard against number_format memory amplification.

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.