Data-driven, archetype-agnostic ticket recipe. The visual anchor is an
ordered placement grid (D-02) — :placement => [%{label, value}], 1 to 4
cells — whose values render in the largest type on the page.
Ships one recipe (D-01): the concrete default is an event/admission ticket (anchor = Section/Row/Seat), but the SAME code renders a boarding-pass shape (Gate/Seat/Group) purely via caller data + labels — zero archetype branching in this file. For example:
# Event ticket
placement: [
%{label: "Section", value: "GA"},
%{label: "Row", value: "H"},
%{label: "Seat", value: "24"}
]
# Boarding pass -- SAME recipe, different data
placement: [
%{label: "Gate", value: "B12"},
%{label: "Seat", value: "14C"},
%{label: "Group", value: "2"}
]Uses the Tiered Composition pattern, mirroring Rendro.Recipes.Certificate:
document/2— Batteries-included; returns a fully assembled`%Rendro.Document{}` ready for `Rendro.render/2`.page_template/1— Layout only; returns the%Rendro.PageTemplate{}.Geometry is derived from `Rendro.PageSize.resolve/2` (A6 default, portrait — the ticket's native physical size, per 118-08/SHOW-01) — zero hardcoded numerics (D-03), so A4, US Letter, and A6 all render correctly.sections/2— Content only; returns a list of%Rendro.Section{}structs mapped to named regions.
The ticket itself is a fixed landscape band anchored at the top of the
page (:main + :stub regions, anchor: :fixed), with an optional
:terms region (anchor: :flow) below it.
Required data keys
:issuer—%{name (required), venue}:title— ticket title, e.g."Indie Night: The Lumen Set":placement— 1 to 4%{label, value}entries (D-02, the anchor):code—%{reference (required, non-blank), label, image}, where:imageis{:path, Path.t()} | {:binary, binary()} | nil
Optional data keys
:subtitle— supporting text under the title:terms— fine-print terms, rendered in the:termsregion
Code area (D-05/D-06/D-07/D-08)
The stub always draws a bordered code box. The human-readable
code.reference ALWAYS renders, even when code.image is supplied. With
no image, the box shows the centered reference — never a faux
barcode/QR pattern. With an image, it is placed fit-contain (aspect
preserving), centered, under the fixed internal logical name
:ticket_code — callers never touch the asset registry.
Jurisdiction / label / formatting overrides (D-16)
:palette, :labels, and :formatters are three orthogonal override maps
merged over recipe-shipped defaults — the same convention as
Rendro.Recipes.Invoice's palette(opts) seam.
Summary
Functions
Assembles and returns a fully composed %Rendro.Document{}. Validates
data (D-04/D-10 errors-as-product) before building the template.
Returns a %Rendro.PageTemplate{} with geometry derived from the page size
option. Default is A6 portrait (the ticket's native physical size). Three
named regions: :main (the D-02 placement-grid anchor), :stub (the
D-05/D-06/D-07/D-08/D-09 code area), and :terms (optional fine print).
Returns a list of %Rendro.Section{} structs mapping ticket content to the
:main, :stub, and :terms regions. Validates data and the
:labels/:formatters opts shape (D-19) before building any section
content.
Functions
@spec document( map(), keyword() ) :: Rendro.Document.t()
Assembles and returns a fully composed %Rendro.Document{}. Validates
data (D-04/D-10 errors-as-product) before building the template.
Examples
iex> data = %{
...> issuer: %{name: "Aurora Live"},
...> title: "Indie Night: The Lumen Set",
...> placement: [%{label: "Seat", value: "24"}],
...> code: %{reference: "AUR-88213-GA"}
...> }
iex> doc = Rendro.Recipes.Ticket.document(data)
iex> doc.page_template
:ticket
@spec page_template(keyword()) :: Rendro.PageTemplate.t()
Returns a %Rendro.PageTemplate{} with geometry derived from the page size
option. Default is A6 portrait (the ticket's native physical size). Three
named regions: :main (the D-02 placement-grid anchor), :stub (the
D-05/D-06/D-07/D-08/D-09 code area), and :terms (optional fine print).
Options
:page_size—:a6(default),:a4,:us_letter, or{width, height}tuple:margin_top/:margin_right/:margin_bottom/:margin_left— margin in pt (default 18):name— template name atom (default:ticket)
Examples
iex> template = Rendro.Recipes.Ticket.page_template()
iex> Enum.map(template.regions, & &1.name)
[:main, :stub, :terms]
@spec sections( map(), keyword() ) :: [Rendro.Section.t()]
Returns a list of %Rendro.Section{} structs mapping ticket content to the
:main, :stub, and :terms regions. Validates data and the
:labels/:formatters opts shape (D-19) before building any section
content.