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.
-a4f65fdab421038daee2ee8a96a0242a.png)
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
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
- Got to the asset manager
- Click on the (+) button to create a new PDF asset
-6671f7d5df2b0c3244766273cb7610aa.png)
- 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.
-3e272f8f71afe8b197916a5082b45d31.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. | Description | Price |
|---|---|---|
| 1 | Service A description | 40,00 € |
| 2 | Service B description | 25,00 € |
Filters
Built-in Liquid filters
For the official filters, check out the Liquid documentation.
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
-b130ffd740d3fd8424a245995ea203ad.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

Header, footer, page numbers (Headless browser)
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 datetitle- Document titleurl- Document locationpageNumber- Current page numbertotalPages- Total pages in the document
Example usage
<span class="pageNumber"></span> of <span class="totalPages"></span>
See also Puppeteer PDFOptions.headerTemplate
Header, footer, page numbers, watermarks (Prince XML)
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"
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'
}
]);