Skip to main content

PDF asset

A PDF asset can be used to build PDFs based on HTML Liquid templates. Liquid is an open-source template language created by Shopify.

How it works

You define the PDF structure with the template code, which is HTML + Liquid.
Liquid makes it possible to access data from the context. The context is represented by a JSON object and can contain data from a configuration.

The template code and the context together result in the final HTML, which will be converted to a PDF by choosen technology.

image.png

warning

Textual data which is injected via the context is HTML encoded by default. This means if you want to inject HTML or SVG into the PDF asset, then you have to disable this encoding.
For this, simply use the raw filter (e.g. {{ svg | raw }} or use a {% raw %} ... {% endraw %} section as described here.

The tech under the hood

We currently offer two technologies to generate a PDF from the generated HTML (can be changed in the PDF asset settings tab).

Headless browser

In this approach, a headless browser is started which loads the HTML and creates the PDF.

➕ Pros

  • What you see is what you get - the output matches the preview with no surprises
  • Uses standard web CSS - no special syntax required
  • Fast rendering for simple to medium complexity documents
  • Easy to debug using browser developer tools
  • Supports modern web layouts and flexbox/grid

➖ Cons

  • Limited support for advanced print-specific features
  • No CMYK color profile or PDF/A compliance support
  • Headers and footers have limitations (no page breaks, limited styling)
  • Resource URLs in header & footer must be base64 encoded (see warning below)
  • Less control over pagination and print layout
warning

Resource URLs (e.g. images, fonts, ...) in header & footer won't be resolved by Puppeteer. They need to be embedded via base64 encoding. For more information, see data_uri filter.

Prince XML

With this approach, we use the PrinceXML library to convert the generated HTML to a PDF.

➕ Pros

  • Professional print features including CMYK color profiles, bleed margins, and crop marks
  • Advanced CSS Paged Media support for precise pagination control
  • PDF/A compliance for archival-quality documents
  • Superior handling of complex multi-page layouts
  • Extensive control over PDF metadata and document properties
  • Better for print-ready, production-quality output

➖ Cons

  • Requires knowledge of print-specific CSS
  • The live preview might not accurately reflect the final PDF output
  • You must generate the PDF after making changes to see the actual result
  • Some CSS features may render differently than in browsers
  • Requires understanding of PrinceXML-specific syntax for advanced features

How to create a PDF asset

  1. Got to the asset manager
  2. Click on the (+) button to create a new PDF asset
    new-pdf-asset.png
  3. Select a name, folder, template and click on Create asset.

Template language: Liquid

If you want to inject flexible data into your HTML sections, then simply use the context in combination with several Liquid statements. The most common ones are described in this documentation, for more details visit the official liquid documentation.

Objects

For example, if you define the following Context with a company object and a name property, then you can inject this data into your HTML section as described here.

image.png

Context

{
"company": {
"name": "Acme Solutions Ltd."
}
}

Input

{{ company.name }}

Output

Acme Solutions Ltd.

For-loops

In addition, it's possible to iterate over a list of objects using for-loops.

Context

{
"lineItems": [
{
"position": 1,
"description": "Service A description",
"price": "40,00 €"
},
{
"position": 2,
"description": "Service B description",
"price": "25,00 €"
}
]
}

Input

<table class="main-table">
<thead>
<tr>
<th class="pos-column">Pos.</th>
<th>Description</th>
<th class="price-column">Price</th>
</tr>
</thead>
<tbody>
{% for item in lineItems %}
<tr>
<td>{{ item.position }}</td>
<td>{{ item.description }}</td>
<td class="price-column">{{ item.price }}</td>
</tr>
{% endfor %}
</tbody>
</table>

Output

Pos.DescriptionPrice
1Service A description40,00 €
2Service B description25,00 €

Filters

Built-in Liquid filters

For the official filters, check out the Liquid documentation.

warning

Important: When using divided_by, ensure you're using the correct data type. The divided_by filter produces a result of the same type as the divisor. If you divide by an integer, the result will be an integer. If you divide by a float (a number with a decimal), the result will be a float.

Example:

{% assign netTotalPriceFloat = netTotalPrice | times: 1.0  %}
{% assign sumDiscountPercentage = 100.0 | divided_by: netTotalPriceFloat | times: sumDiscounts | round: 2 %}

Combeenation filters

We extended the Liquid template language with custom filters for Combeenation-specific functionality.

The following filter can be used in combination with Assets:

  • url ... to retrieve the URL of an image, text or file asset

To directly embed images or fonts into the header/footer:

  • data_uri ... to retrieve the base64 encoded data of a URL
    We support the following media types:
    • Images: Png, Gif, Jpg, Svg, Bmp, Webp, Ktx2
    • Fonts: Ttf, Woff, Woff2

For a PDF (e.g. quote) which contains several prices, the following custom filter can be used:

  • money ... to convert any number to a formatted price
    The money filter accepts several parameters which controls the formatted output.
{{ discount.adjustment.price | money:"de-de", "EUR", "symbol" }}   // 4.711,02

Plain text

  • "de-de" ... the locale which affects the formatting of the resulting price
  • "EUR" ... optional currency code according to ISO 4217
  • "symbol" ... is an optional parameter to decide if a currency symbol or code should be used,
    possible values: "symbol", "code"; default: "code"

It's of course also possible to use context parameters, for example currency from the context object instead of "EUR".

Asset access

Two recommended ways to access the image asset in your template code:

  • Direct access (blue arrow): Use the full asset path as a string (e.g. folderName.assetName.) before the above mentioned filter
  • Context-based injection (green arrow): Pass the full asset path via the context. This is preferred when the asset is dynamic and selected during the configuration process

image.png

If the given asset is not valid or is missing, then a corresponding asset error is shown.

Asset
There must be one asset named logo.

Context

{
"company": {
"logo": "MyFolder.Logo"
}
}

Input

<img src="{{ company.logo | url }}" style="height: 2cm" /> <img src="{{ company.logo | url | data_uri }}" style="height: 2cm" />

HTML Output

<img src="https://cbnpeuwstassets.blob.core.windows.net/public/COMBEENATION/0Dxez2x2M09.png" style="height: 2cm" />
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQAAACOCAYAAADHGPqZAAAEtmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMTQyIgogICB0aWZmOkltYWdlV2lkdGg9IjUwMCIKICAgdGlmZjpSZXNvbHV0aW9uVW5pdD0iMiIKICAgdGlmZjpYUmVzb2x1dGlvbj0iMzAwLzEiCiAgIHRpZmY6WVJlc29sdXRpb249IjMwMC8xIgogICBleGlmOlBpeGVsWERpbWVuc2lvbj0iNTAwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTQyIgogICBleGlmOkNvbG9yU3BhY2U9IjEiCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgeG1wOk1vZGlmeURhdGU9IjIw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"
style="height: 2cm"
/>

Output

info

These CSS classes only work in the header & footer! They have no effect inside the body.

Specific CSS classes can be used to inject auto-generated values into the PDF.
To use them, simply create an HTML tag with one of the CSS classes listed below.

Available CSS classes
  • date - Formatted print date
  • title - Document title
  • url - Document location
  • pageNumber - Current page number
  • totalPages - Total pages in the document
Example usage
<span class="pageNumber"></span> of <span class="totalPages"></span>

See also Puppeteer PDFOptions.headerTemplate

For detailed guides on using Prince XML features, see:

How to use a pdf asset

A PDF asset can finally be used to create a PDF based on any data during a configuration. The required data can be dynamically passed via the Context object. As a result, it's possible to create a PDF using Custom Code.

Basically, the PDF is created via the PDF asset and a dynamically passed Context object. This generated PDF is saved as a "configuration file" and be used as described here.

Example "Create and merge PDFs"

info

Function can be used if all assets are in the same bundle and you just want to create a PDF and optionally merge it with others

// creating the context
const myContext = {
company: {
logo: 'MyFolder.MyFinalLogo'
}
};

const urlResult = await CfgnFiles.createPdfFromAssets(
'MyBundle',
[
{
type: CreatePdfTaskTypes.Asset,
assetPath: 'Pdf1'
},
{
type: CreatePdfTaskTypes.PdfAsset,
assetPath: 'quotePdfAsset',
context: myContext
},
{
type: CreatePdfTaskTypes.Asset,
assetPath: 'Pdf2'
}
],
'Output',
'My cool PDF'
);

Example "Create PDF with dynamic convert document endpoint and merge it with static pdfs"

Similar to the previous one, but the dynamic convertDocument endpoint supports all types of convert tasks.

// creating the context
const myContext = {
company: {
logo: 'MyFolder.MyFinalLogo'
}
};

// Example "Creating the PDF based on the context and a PDF asset"
const urlResult = await CfgnFiles.convertDocument([
{
type: DocumentConvertTaskTypes.PdfAsset,
name: 'HtmlToPdfTask',
bundleAliasName: 'MyBundle',
assetPath: 'MyPdfAsset',
context: myContext
}, {
type: CreatePdfTaskTypes.Asset,
name: 'Pdf1Task',
bundleAliasName: 'MyBundle',
assetPath: 'Pdf1'
},
{
type: CreatePdfTaskTypes.Asset,
name: 'Pdf2Task',
bundleAliasName: 'MyBundle',
assetPath: 'Pdf2'
},
{
type: CreatePdfTaskTypes.Merge,
name: 'MergeTask',
inputTaskNames: ['Pdf1Task', 'HtmlToPdfTask', 'Pdf2Task']
},
{
type: DocumentConvertTaskTypes.OutputToCfgnFile,
name: 'OutputPdfTask',
inputTaskName: 'MergeTask',
cfgnFileName: 'Output',
cfgnFileExtension: 'pdf',
cfgnFileDisplayName: 'My cool PDF'
}
]);