Skip to content

Product Labels ​

A label template (Administration › Šablony, type štítek) prints labels for stock items: the name, the price, codes and a barcode, one label per page on a roll printer (Zebra) or several on an A4 sheet. It is a Twig text template rendered to HTML and then to a PDF at the template's size.

Variables ​

VariableTypeDescription
itemLabelsPrintedLabel[]One label object per printed item, with how many copies (quantity)
groupedProductLabelsPrintedLabel[]One per product, the copies of its items summed
sheetLabelSheetWhat the labels print on: the page's width and height in mm, the row and column an A4 sheet starts at, the printerType
shopShopThe shop, as in other templates: shop.name, shop.url, shop.phone, …
repositoryThe storefront's repositories, e.g. a product attribute: repository.attribute.findOneBy({id: 4})

A template prints each copy itself, e.g. {% for copy in 1..label.quantity %}…{% endfor %}. What a label object holds (name, variant, codes, barcode content, price, QR code) is in PrintedLabel. The price is there only when the shop prints prices on labels (its setting Typ ceny na štítky); print it with {{ label.price.current|price }}.

Barcodes and QR codes ​

Write a barcode as a tag; it becomes an image before the PDF is made:

TagCode
<img-code128 src="…" width="1" height="30">Code 128 (any text)
<img-ean13 src="…" width="1" height="30">EAN-13 (13 digits)
<img-codeI25 src="…" width="1" height="30">Interleaved 2 of 5 (digits)
<img-qr src="https://…" width="80">QR code (width in px)

width is the width of one bar (default 2), height the bars' height in px (default 30). The -png forms (<img-code128-png>, …) make a PNG instead of an SVG. A value the code cannot hold gives an empty image, not an error. Size the image with CSS (height: 8mm; max-width: 100%).

Page size ​

The page is the template's width and height in mm, without margins. One label per page: make each label fill the page (html, body { height: 100% } and the label height: 100%; 100vh is not the page's height in the PDF) and break after it (break-after: page, except the last). An A4 sheet: lay out the grid yourself and start at sheet.row and sheet.column. The size is sheet.width × sheet.height (mm) when a layout needs it in numbers.

What a label may use ​

In the label studio a label renders in a restricted environment, and a text that renders there renders the same when printed. It reaches only the variables above: not the iterator global, and not {% cache %}. Twig's own tags, filters and functions work as everywhere (include, embed and source have no other templates to load). Of the shop's own filters every one but ndump, gravatar, image_proxy and setAnalyticsName; of its own functions only QR, isPracovniDen, pristiPracovniDen and rand. Objects' methods and properties as in other templates (no static methods). Output is not escaped automatically: escape product texts with |e. A variable or attribute that does not exist is an error with its line (printing would print nothing for it): test an optional one with is defined, or give it a default with ??.

Example ​

twig
<style>
    * { box-sizing: border-box; margin: 0; padding: 0; }
    html, body { height: 100%; }
    body { font-family: Arial, Helvetica, sans-serif; }
    .label { height: 100%; padding: 1.5mm 2mm; display: flex; flex-direction: column; justify-content: space-between; break-after: page; }
    .label:last-child { break-after: auto; }
    .barcode img { height: 8mm; max-width: 100%; }
</style>
{% for label in itemLabels %}
    {% for copy in 1..label.quantity %}
        <div class="label">
            <strong>{{ label.productName|e }}</strong>
            {% if label.variantName is not empty %}<div>{{ label.variantName|e }}</div>{% endif %}
            {% if label.price %}<div>{{ label.price.current|price }}</div>{% endif %}
            <div class="barcode"><img-code128 src="{{ label.barcodeContent|e }}" width="1" height="30"></div>
            <small>{{ label.visibleCode|e }}</small>
        </div>
    {% endfor %}
{% endfor %}