Generating Label PDFs
- Introduction
- Templates
- Layouts
- Data List
- Default Data
- Built-In Data
- Images
- Settings
- Injecting Values
- Arranging and Styling Text
Introduction¶
T3 label PDFs are generated using several different sources that control how the labels will appear:
• Templates
• Layouts
• Data List
• Default Data
• Built-In Data
• Images
• Settings
Templates¶
A template defines the overall layout and physical structure of the label, including its dimensions, margins, padding, and page arrangement such as rows, columns, and spacing.
Learn more about label templates
Layouts¶
Layouts control what will be printed on each label and how it is arranged. When you are configuring a label, this is where most of the effort will be dedicated.
Learn more about layouts and layout elements
Data List¶
The data list controls how many unique labels are generated, and what data is inserted into each label.
Each item in the data list represents one label. If you wanted to print a set of 5 labels that didn't need any special data into each, you would just create an empty list of length 5:
If you wanted to insert two values, say firstName and lastName into each label, you could specify that as follows:
Package data returned from the T3 API is structured as follows:
[
{
"package": {
"hostname": "ca.metrc.com",
"label": "1A4400001234000000005678",
"item": {
"name": "Bubba Kush",
...
},
"isInTransit": false,
"isOnHold": false,
"isOnRecall": false,
...
}
},
{
"package": {
"hostname": "ca.metrc.com",
"label": "1A4400001234000000005679",
"item": {
"name": "1g Wedding Cake Preroll - 5pk",
...
},
"isInTransit": false,
"isOnHold": false,
"isOnRecall": false,
...
}
}
]
How to add these values to a label is covered in Injecting Values
Default Data¶
Default data is used in two situations: - You want to inject a value into all labels, but don't want to repeat it in every data list entry. (Example: facility address, shared between labels) - Items in your data list are missing values, and you want to fall back to a specific value
Default data is passed in the commonContentData field and is accessed under the common.* namespace in value templates (e.g. {{ common.facilityAddress }}).
Default data is usually not needed.
Built-In Data¶
Built-in data is provided by T3 out of the box. It includes text and images that are commonly used by cannabis businesses, and is accessed under the t3.* namespace.
Examples: - State-specific warning images (e.g. {{ t3.images['ca_cannabis_warning.png'] }}) - State-specific warning disclosures (e.g. {{ t3.text.ca_cannabis_warning_disclosure }}) - Generic cannabis images - Poison Control Center contact information ({{ t3.text.poison_control_center_phone }})
You don't have to manage any of these yourself — they're available in every label generation request.
Images¶
Images can be inserted into labels and rendered using an IMAGE layout element.
The following is an example of how image data might be passed:
This image can now be used as follows in a layout element:
Settings¶
Label settings configure how your labels will appear. Settings used most often:
- How many copies of each label should be printed
- Reversing the print order
- Rotating your layout sideways by 90 degrees
- Enabling/disabling watermark, for trial/error that doesn't count against your monthly quota
- Enabling/disabling debug, for drawing boundaries around each layout element
Injecting Values¶
Most layout elements support a value template — a string that tells T3 what to render inside the element. Value templates are processed with Jinja, so you can interpolate values from your data, use conditionals, and apply filters.
Interpolating a value:
Values can come from four namespaces:
- Per-label data — each entry in your
labelContentDataList. If the entry is{"package": {"label": "1A44..."}},{{ package.label }}renders1A44.... common.*— values shared across every label, passed in Default Data.images.*— base64-encoded images you supplied, accessed by filename. For example,{{ images['logo.png'] }}.t3.*— Built-In Data provided by T3.
Conditionals:
Filters:
For a deeper walkthrough, see the tutorial's section on injecting values.
Arranging and Styling Text¶
TEXT and TABLE elements support a range of formatting options:
- Font:
paragraphFontName(e.g.Helvetica,Times-Bold,Courier),paragraphFontSize,paragraphSpacing. - Alignment:
horizontalParagraphAlignment(LEFT,CENTER,RIGHT),verticalParagraphAlignment(TOP,CENTER,BOTTOM). - Overflow handling:
paragraphTextResizeStrategy: ALLOW_OVERFLOW(default) — text overflows the element.SHRINK_TEXT— font size is reduced until the text fits.TRUNCATE_TEXT— letters are removed from the end until the text fits; an ellipsis is appended.
Tables are defined with HTML and share the same font settings as TEXT elements. A basic example:
<table>
<tr><td><b>THC</b></td><td>{{ package.metadata.totalThc }}</td></tr>
<tr><td><b>CBD</b></td><td>{{ package.metadata.totalCbd }}</td></tr>
</table>
For the full list of options, see Label Layouts → Textual Elements.
Next Steps¶
- Build a label from scratch with the Tutorial.
- Full reference for the two halves of a label: Label Templates and Label Layouts.
- Print your PDFs reliably across thermal, inkjet, and laser printers.
- Walk through the CSV-driven Retail ID example.
- Call the T3 API Label endpoints directly to generate labels from your own tooling.
- Start your free 30-day T3+ trial