-
Notifications
You must be signed in to change notification settings - Fork 0
Template Syntax
FlexRender templates are YAML files that define image layouts using a tree of typed elements. This page covers the template structure, all 10 element types, common properties, and supported units.
For template expressions (variables, loops, conditionals), see Template-Expressions. For flexbox layout properties, see Flexbox-Layout. For a complete property reference with examples for every element type, see Element-Reference. For visual examples with rendered images, see Visual-Reference.
template: # Required: metadata
name: "my-template" # Template name (string)
version: 1 # Template version (int)
culture: "ru-RU" # Culture for number/date formatting (optional)
fonts: # Optional: font definitions
default: "assets/fonts/Inter-Regular.ttf"
bold: "assets/fonts/Inter-Bold.ttf"
canvas: # Required: canvas configuration
fixed: width # Which dimension is fixed
width: 300 # Canvas width in pixels
background: "#ffffff" # Background color
text-direction: ltr # Text direction: ltr (default), rtl
layout: # Required: array of elements
- type: text
content: "Hello!"| Property | Type | Default | Description |
|---|---|---|---|
name |
string | "" |
Template name for identification |
version |
int | 1 |
Template version number |
culture |
string? | null |
Culture for number/date formatting (e.g., "ru-RU", "en-US"). When set, built-in filters use this culture instead of InvariantCulture. Priority: RenderOptions.Culture > template.culture > InvariantCulture |
| Property | Type | Default | Description |
|---|---|---|---|
fixed |
FixedDimension | width |
Which dimension is fixed: width, height, both, none
|
width |
int | 300 |
Canvas width in pixels |
height |
int | 0 |
Canvas height (0 = auto when not fixed) |
background |
string | "#ffffff" |
Background color in hex |
rotate |
string | "none" |
Post-render rotation |
text-direction |
TextDirection | ltr |
Text direction: ltr, rtl
|
-
width-- width is fixed, height expands to fit content (default) -
height-- height is fixed, width expands to fit content -
both-- both dimensions are fixed -
none-- both dimensions expand to fit content
| Value | Effect |
|---|---|
"none" |
No rotation |
"left" |
270 degrees (90 CCW) -- swaps width/height |
"right" |
90 degrees CW -- swaps width/height |
"flip" |
180 degrees |
"<number>" |
Arbitrary degrees (e.g., "45") |
Rotation is applied after rendering. For thermal printers: use "right" to rotate a wide receipt into a tall image.
Fonts are defined as key-value pairs. The key is a reference name used in font: properties, and the value is the font source:
fonts:
default: "assets/fonts/Inter-Regular.ttf" # Local file
bold: "assets/fonts/Inter-Bold.ttf" # Local file
icon: "embedded://MyApp.Fonts.icons.ttf" # Embedded resource
remote: "https://example.com/font.ttf" # HTTP URLColors are specified in hex format:
-
#rrggbb-- 6-digit hex (e.g.,"#ff0000"for red) -
#rgb-- 3-digit hex shorthand (e.g.,"#f00"for red)
Renders text content with font, size, color, alignment, and wrapping options.
- type: text
content: "Hello, {{name}}!"
font: bold
size: 1.2em
color: "#000000"
align: center
wrap: true
overflow: ellipsis
maxLines: 2
lineHeight: "1.5"| Property | Type | Default | Description |
|---|---|---|---|
content |
string | "" |
Text content, may contain {{variable}} expressions |
font |
string | "main" |
Font reference name from fonts section |
size |
string | "1em" |
Font size (px, em, %) |
color |
string | "#000000" |
Text color in hex |
align |
TextAlign | left |
Text alignment: left, center, right, start (logical), end (logical) |
wrap |
bool | true |
Whether text wraps to multiple lines |
overflow |
TextOverflow | ellipsis |
Overflow handling: ellipsis, clip, visible
|
maxLines |
int? | null |
Maximum number of lines (null = unlimited) |
lineHeight |
string | "" |
Line height for multi-line text |
lineHeight values:
| Format | Example | Behavior |
|---|---|---|
| Empty string | "" |
Use font-defined default spacing |
| Plain number | "1.8" |
Multiplier of fontSize |
| Pixel units | "24px" |
Absolute pixel value |
| Em units | "2em" |
Relative to element's fontSize |
A container that lays out children using the flexbox algorithm. See Flexbox-Layout for detailed layout properties.
- type: flex
direction: row
wrap: wrap
gap: 10
justify: space-between
align: center
padding: "20"
background: "#f5f5f5"
children:
- type: text
content: "Left"
- type: text
content: "Right"| Property | Type | Default | Description |
|---|---|---|---|
direction |
FlexDirection | column |
Main axis: row, column, row-reverse, column-reverse
|
wrap |
FlexWrap | nowrap |
Wrapping: nowrap, wrap, wrap-reverse
|
gap |
string | "0" |
Gap shorthand (sets both rowGap and columnGap) |
columnGap |
string? | null |
Gap between items along the main axis |
rowGap |
string? | null |
Gap between wrapped lines |
justify |
JustifyContent | start |
Main axis alignment |
align |
AlignItems | stretch |
Cross axis alignment |
alignContent |
AlignContent | start |
Wrapped lines alignment |
overflow |
Overflow | visible |
Content clipping: visible, hidden
|
children |
element[] | [] |
Child elements |
Renders an image from a file, URL, base64 data, or embedded resource.
# From file
- type: image
src: "logo.png"
width: 100
height: 50
# From HTTP
- type: image
src: "https://example.com/logo.png"
# From embedded resource
- type: image
src: "embedded://MyApp.Resources.logo.png"
# From base64
- type: image
src: "data:image/png;base64,iVBOR..."| Property | Type | Default | Description |
|---|---|---|---|
src |
string | "" |
Image source: file path, http://, embedded://, base64 data URL |
width |
int? | null |
Image container width (null = natural width) |
height |
int? | null |
Image container height (null = natural height) |
fit |
ImageFit | contain |
How the image fits within bounds |
Image fit modes:
| Mode | Description |
|---|---|
fill |
Stretch to fill bounds (may distort) |
contain |
Scale to fit within bounds preserving ratio (may have empty space) |
cover |
Scale to cover bounds preserving ratio (may be cropped) |
none |
Use image's natural size without scaling |
Renders a QR code. Requires FlexRender.QrCode.Skia.Render (or FlexRender.QrCode) and .WithQr() on the builder for Skia, or FlexRender.QrCode.ImageSharp.Render for ImageSharp.
- type: qr
data: "{{paymentUrl}}"
size: 120
errorCorrection: M
foreground: "#000000"| Property | Type | Default | Description |
|---|---|---|---|
data |
string | "" |
Data to encode in the QR code |
size |
int | 100 |
QR code size in pixels (width = height) |
errorCorrection |
ErrorCorrectionLevel | M |
Error correction level |
foreground |
string | "#000000" |
Foreground (module) color in hex |
Error correction levels:
| Level | Recovery Capacity |
|---|---|
L |
~7% recovery |
M |
~15% recovery (default) |
Q |
~25% recovery |
H |
~30% recovery |
Renders a barcode. Requires FlexRender.Barcode.Skia.Render (or FlexRender.Barcode) and .WithBarcode() on the builder for Skia, or FlexRender.Barcode.ImageSharp.Render for ImageSharp.
- type: barcode
data: "{{sku}}"
format: code128
width: 200
height: 80
showText: true
foreground: "#000000"| Property | Type | Default | Description |
|---|---|---|---|
data |
string | "" |
Data to encode |
format |
BarcodeFormat | code128 |
Barcode format |
width |
int | 200 |
Barcode width in pixels |
height |
int | 80 |
Barcode height in pixels |
showText |
bool | true |
Show encoded text below barcode |
foreground |
string | "#000000" |
Bar color in hex |
Barcode formats:
| Format | Description |
|---|---|
code128 |
Alphanumeric, high density |
code39 |
Alphanumeric, widely supported |
ean13 |
13 digits, retail |
ean8 |
8 digits, compact retail |
upc |
12 digits, North American retail (UPC-A) |
Renders a horizontal or vertical line (solid, dashed, or dotted).
- type: separator
style: dashed
color: "#cccccc"
thickness: 1| Property | Type | Default | Description |
|---|---|---|---|
orientation |
SeparatorOrientation | horizontal |
Direction: horizontal, vertical
|
style |
SeparatorStyle | dotted |
Line style: dotted, dashed, solid
|
thickness |
float | 1 |
Line thickness in pixels |
color |
string | "#000000" |
Line color in hex |
Horizontal separators stretch to full width and use thickness as height. Vertical separators stretch to full height and use thickness as width.
Renders tabular data with configurable columns, optional headers, and support for both dynamic (data-driven) and static rows. The table element is expanded into a flex-based layout during template expansion -- no changes to the layout or rendering engines are needed.
# Dynamic table from data array
- type: table
array: items
as: item
columns:
- key: name
label: "Product"
grow: 1
- key: price
label: "Price"
width: "80"
align: right| Property | Type | Default | Description |
|---|---|---|---|
array |
string | "" |
Path to data array for dynamic rows |
as |
string? | null |
Variable name for current item |
columns |
column[] | required | Column definitions |
rows |
row[] | [] |
Static rows (alternative to array) |
headerFont |
string? | null |
Font for header row |
headerColor |
string? | null |
Text color for header row |
headerSize |
string? | null |
Font size for header row |
headerBackground |
string? | null |
Background color for header row |
Column properties:
| Property | Type | Default | Description |
|---|---|---|---|
key |
string | required | Data field name for this column |
label |
string? | null |
Header text (null = no header for this column) |
width |
string? | null |
Explicit column width (px, %, em) |
grow |
float | 0 |
Flex grow factor |
align |
TextAlign | left |
Text alignment: left, center, right
|
font |
string? | null |
Font override for cells in this column |
color |
string? | null |
Text color override |
size |
string? | null |
Font size override |
format |
string? | null |
Format string for cell values |
Static row properties:
| Property | Type | Default | Description |
|---|---|---|---|
values |
map | required | Column key to value mapping |
font |
string? | null |
Font override for this row |
color |
string? | null |
Text color override |
size |
string? | null |
Font size override |
Iterates over an array in the data, creating child elements for each item. See Template-Expressions for details.
- type: each
array: items
as: item
children:
- type: text
content: "{{@index}}. {{item.name}}: {{item.price}}"| Property | Type | Required | Description |
|---|---|---|---|
array |
string | Yes | Path to array in data (e.g., "items", "order.lines") |
as |
string | No | Variable name for current item |
children |
element[] | Yes | Template elements to render per item |
Conditional rendering based on data values. Supports 13 comparison operators. See Template-Expressions for details.
- type: if
condition: isPremium
then:
- type: text
content: "Premium member"
else:
- type: text
content: "Standard member"| Property | Type | Required | Description |
|---|---|---|---|
condition |
string | Yes | Path to value for condition check |
then |
element[] | Yes | Elements when condition is true |
elseIf |
if element | No | Nested else-if condition |
else |
element[] | No | Elements when all conditions are false |
Renders SVG vector graphics in templates. Supports external files (src) or inline markup (content).
Requires
FlexRender.SvgElement.Skia.Render(orFlexRender.SvgElement) package:.WithSkia(skia => skia.WithSvgElement())
# From file
- type: svg
src: "assets/icons/logo.svg"
width: 120
height: 40
# Inline SVG
- type: svg
content: '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" fill="#4CAF50"/></svg>'
width: 48
height: 48| Property | Type | Default | Description |
|---|---|---|---|
src |
string? | null |
Path to SVG file. Loaded via resource loaders (file, HTTP, embedded). Mutually exclusive with content. |
content |
string? | null |
Inline SVG markup string. Mutually exclusive with src. |
width |
int? | null |
Target render width in pixels. null = use SVG intrinsic width or container. |
height |
int? | null |
Target render height in pixels. null = use SVG intrinsic height or container. |
fit |
ImageFit | contain |
How the SVG fits within its bounds: fill, contain, cover, none. |
Must specify exactly one of src or content (not both, not neither).
All elements inherit these properties from TemplateElement:
| Property | Type | Default | Description |
|---|---|---|---|
padding |
string | "0" |
Inner spacing (px, %, em, CSS shorthand) |
margin |
string | "0" |
Outer spacing (px, %, em, auto, CSS shorthand) |
background |
string? | null |
Background color in hex or gradient (null = transparent) |
opacity |
float | 1.0 |
Element opacity from 0.0 (fully transparent) to 1.0 (fully opaque) |
box-shadow |
string? | null |
Box shadow: "offsetX offsetY blurRadius color" (e.g., "4 4 8 #00000040") |
rotate |
string | "none" |
Element rotation (none/left/right/flip/degrees) |
display |
Display | flex |
Display mode: flex, none
|
grow |
float | 0 |
Flex grow factor |
shrink |
float | 1 |
Flex shrink factor |
basis |
string | "auto" |
Flex basis (px, %, em, auto) |
alignSelf |
AlignSelf | auto |
Per-item alignment override |
order |
int | 0 |
Display order |
width |
string? | null |
Explicit width (px, %, em, auto) |
height |
string? | null |
Explicit height (px, %, em, auto) |
minWidth |
string? | null |
Minimum width constraint |
maxWidth |
string? | null |
Maximum width constraint |
minHeight |
string? | null |
Minimum height constraint |
maxHeight |
string? | null |
Maximum height constraint |
position |
Position | static |
Positioning mode: static, relative, absolute
|
top |
string? | null |
Top inset for positioned elements |
right |
string? | null |
Right inset for positioned elements |
bottom |
string? | null |
Bottom inset for positioned elements |
left |
string? | null |
Left inset for positioned elements |
aspectRatio |
float? | null |
Width/height ratio constraint |
text-direction |
TextDirection? | null |
Text direction override: ltr, rtl (null = inherit from parent/canvas) |
All size-based properties support the following units:
| Unit | Syntax | Description | Example |
|---|---|---|---|
| px |
"100", "100px"
|
Absolute pixels (default if no suffix) | width: "100" |
| % | "50%" |
Percentage of parent container size | width: "50%" |
| em | "1.5em" |
Relative to current font size | size: "1.5em" |
| auto |
"auto", null
|
Automatic sizing (context-dependent) | width: "auto" |
Plain numbers without suffix are treated as pixels. Empty or whitespace strings resolve to auto. Parsing is case-insensitive for unit suffixes.
Both padding and margin accept 1 to 4 space-separated values:
| Format | Meaning |
|---|---|
"20" |
All sides = 20 |
"20 40" |
Top/Bottom = 20, Left/Right = 40 |
"20 40 30" |
Top = 20, Left/Right = 40, Bottom = 30 |
"20 40 30 10" |
Top = 20, Right = 40, Bottom = 30, Left = 10 |
Each value can use a different unit: "10px 5% 2em 20".
Margin additionally supports auto values for centering elements within flex containers. See Flexbox-Layout for auto margin details.
A receipt template demonstrating multiple element types:
template:
name: "receipt"
version: 1
fonts:
default: "assets/fonts/Inter-Regular.ttf"
bold: "assets/fonts/Inter-Bold.ttf"
canvas:
fixed: width
width: 320
background: "#ffffff"
layout:
- type: flex
padding: "24 20"
gap: 12
children:
# Header
- type: text
content: "{{shopName}}"
font: bold
size: 1.5em
align: center
color: "#1a1a1a"
- type: separator
style: dashed
color: "#cccccc"
# Items (dynamic loop)
- type: each
array: items
as: item
children:
- type: flex
direction: row
justify: space-between
children:
- type: text
content: "{{item.name}}"
color: "#333333"
- type: text
content: "{{item.price}} $"
color: "#333333"
- type: separator
style: solid
color: "#1a1a1a"
# Total
- type: flex
direction: row
justify: space-between
children:
- type: text
content: "TOTAL"
font: bold
size: 1.2em
- type: text
content: "{{total}} $"
font: bold
size: 1.2em
# QR code
- type: flex
align: center
children:
- type: qr
data: "{{paymentUrl}}"
size: 120
errorCorrection: M
- type: text
content: "Thank you for your purchase!"
size: 0.85em
align: center
color: "#666666"- Element-Reference -- complete property reference for all element types
- Template-Expressions -- variables, loops, conditionals
- Flexbox-Layout -- layout engine details
- Render-Options -- rendering and format options