Any .json file not named form.json, autocomplete.json, or presets.json
uses this format (project.ypf doesn't count here - it isn't a .json file) -
referenced from
process.js via overlay(filename[, page]).
No special significance of its own; a project with no process.js
composites nothing.
{
"blocks": [
{ "id": "dealer_name", "type": "text", "text": "{dealer_name}", "x_mm": 10, "y_mm": 10, "width_mm": 80, "height_mm": 8 }
]
}
Common block keys
| Key | Required | Type | Meaning |
|---|---|---|---|
id |
yes | string | Unique across every partial included in one generation run. |
type |
yes | string | text | image | box | scanCode | grid | pdf | overlay. |
x_mm / y_mm |
yes | number | Top-left corner, mm from the page's top-left. |
width_mm / height_mm |
yes | number | Bounding box, mm. |
condition |
no | string | Bare expression (no {...} wrapper), evaluated by a restricted arithmetic/comparison engine - not full JavaScript, no method calls. Falsy hides the block. |
z_index |
no | int | Default 0. Higher paints on top. |
rotation_deg |
no | number | Default 0. Content-only rotation around the block's own center - never affects x_mm/y_mm/width_mm/height_mm. |
scale_x / scale_y |
no | number | Default 1. Content-only scale around the block's own center, applied before rotation. Negative flips the content; magnitude != 1 stretches it. |
There is no page key - the overlay(filename, page) call that included
this file decides that.
Color values. Every key below marked "Hex or ref" takes a plain string,
either "#RRGGBB" or "inputs:field_id" - the latter resolves that field's
(or one of the five My Details color fields') value at generation time. An
unresolved/invalid reference falls back to black.
text
| Key | Required | Type | Meaning |
|---|---|---|---|
text |
no | string | Template: literal text, or {...}-wrapped real JavaScript for anything dynamic. A bare field name ({sale_price}) resolves directly. \n wraps as a multi-line paragraph. |
style.font_size |
no | number | Default 12. |
style.font_weight |
no | string | normal* | bold. |
style.font_family |
no | string | See Assets Overview. |
style.color |
no | Hex or ref | Default #000000. No background-fill style - layer a box block underneath instead. |
style.align / style.valign |
no | string | left*/top* | center | right/bottom | stretch | justify (align only, only meaningful with wrap: true). stretch is ignored once wrap is true. |
style.overflow |
no | string | visible* | hide. |
style.wrap |
no | boolean | Default false. Real word-wrap instead of single-line/manual-\n rendering - trades away pixel-exact positioning and stretch for it. |
style.stroke_width / stroke_color / stroke_style |
no | number/Hex or ref/string | Glyph outline, in points. stroke_style: inside | middle* | outside. |
image
| Key | Required | Type | Meaning |
|---|---|---|---|
source |
no | string | "assets:filename.png" - path relative to the project folder. Or "inputs:field_id" - field id, value is a file path. Works the same whether the field is an image-type field (a photo picker), a signature-type field, or a drawing-type field (a captured signature/drawing is written to a file the same way). A drawing field's own background_asset is never part of its submitted value - to show that reference image too, add a separate image block with source: "assets:..." pointing at the same file, positioned to match, with the drawing field's own block layered on top. |
fit |
no | string | contain* | cover | stretch. fill is an older spelling of stretch, still accepted when reading. |
align / valign |
no | string | left | center* | right and top | center* | bottom. Under fit: contain, positions the image within its box. Under fit: cover, acts as a crop anchor instead - left/top keeps that edge flush, cropping the opposite edge's overflow. No effect under stretch. |
filters |
no | string | CSS-flavored filter chain, e.g. grayscale() contrast(120%) colorize(#ff0000). See Image Filters. |
A missing asset or unfilled field omits the block, not an error.
box
| Key | Required | Type | Meaning |
|---|---|---|---|
fill_color / stroke_color |
no | Hex or ref | Omitted for none. |
stroke_width_mm |
no | number | Default 0. |
corner_radius_mm |
no | number | Default 0, independent of stroke. |
stroke_style |
no | string | inside | middle* | outside. |
scanCode
| Key | Required | Type | Meaning |
|---|---|---|---|
data |
no | string | Same template syntax as text. |
format |
no | string | qr_code* or any barcode symbology the app supports. |
color / background_color |
no | Hex or ref | Module color / optional fill. |
show_value |
no | boolean | Human-readable text under the code. Default false. |
Always rendered centered - QR/2D formats render square, 1D barcodes as a wide strip.
grid
| Key | Required | Type | Meaning |
|---|---|---|---|
columns |
yes | int | Cells per row. |
data |
no | string | Bare JS expression evaluating to an array. See Grid. |
column_widths |
no | array | Weight (number), "20mm", or "30%" per column. |
min_rows / max_rows |
no | int | No default bound. |
source_field / column_keys |
no | string / array | Declarative alternative to data. |
style (grid default) and a per-cell object share these keys (real CSS
names, hyphenated):
| Key | Meaning |
|---|---|
background-color, color, font-family, font-size (default 11), font-weight |
Cell text styling. background-color/color are Hex or ref. |
padding |
mm. Default 1. |
text-align / vertical-align |
left*/middle* defaults. |
border-color / border-width |
border-color is Hex or ref. Grid-level: outer table border. Per-cell: that cell gets its own border box instead of the shared line. |
border-horizontal-color / border-vertical-color |
Hex or ref. Interior row/column separator lines, grid-level. Per-cell: overrides that direction's own border color (no per-cell -width counterpart - the cell's own border-width covers both directions). |
min-height |
mm floor on a cell's height. |
Row height is content-driven and never clips to height_mm; a grid never
splits across pages.
pdf
| Key | Required | Type | Meaning |
|---|---|---|---|
source |
yes | string | "assets:filename.pdf" (page 1) or "assets:filename.pdf:3" (page 3) - path relative to the project folder, optionally with a page number. Or "inputs:field_id" - swaps in whatever assets:...[:page] value that key in inputs resolves to, typically set by process.js itself (there's no form field type that captures a PDF file). |
fit |
no | string | contain* | cover | stretch. |
overflow |
no | string | visible* | hide. Only has a visible effect under fit: cover - contain/stretch never exceed their box. |
Renders one page of another PDF file as block content - a simpler
alternative to composing a whole page in JSON. The Overlay Editor's
Properties panel has an Auto Size button that sets width_mm/
height_mm to that page's own real size.
overlay
| Key | Required | Type | Meaning |
|---|---|---|---|
overlay |
yes | string | Path to another layout partial, relative to the project folder. |
overflow |
no | string | visible* | hide. Unconditional here (no fit concept - nested content always renders at its own native size). |
Places another partial's own blocks as one unit, positioned/rotated/
scaled like any other block - the visual alternative to a hand-written
overlay() call in process.js for a
sub-layout repeated at several positions. The referenced file's own
bounding-box top-left lands at this block's x_mm/y_mm;
rotation_deg/scale_x/scale_y rotate/scale the whole placed group as
one rigid unit. Can nest (a referenced file can itself contain overlay
blocks), up to 10 levels deep - deeper, or a file that circularly
references itself, fails generation with an error naming the loop. The
Overlay Editor's Properties panel has the same Auto Size button as
pdf, computing the union bounding box of the referenced file's own
blocks instead of a PDF page's size.
Constraints
Every block id must be unique across every partial actually included in
one generation run.