Template-based PDF generation
Customizable PDF generation for Questionnaire and QuestionnaireResponse using the $render operation.
Overview
This feature introduces the capability to generate custom PDF representation for Questionnaire and QuestionnaireResponse resources. It is facilitated through the $render
operation. This document explains how to use this operation and provides examples on how to create custom print templates.
Implementation Details
The $render
operation allows you to select how you want your form to look in print. Different representations can be defined using SDCPrintTemplate resources. You can use the default template, or define additional ones for specific forms. The $render
operation can be applied to both Questionnaire and QuestionnaireResponse resources.
A template is an HTML document utilizing a templating language for dynamic content rendering. It uses Selmer templating system.
The response of $render
is the result of rendering the selected HTML template with the data from the specified Questionnaire or QuestionnaireResponse. To actually convert it to PDF, you could use window.print()
on the frontend, or a library like Puppeteer on the backend.
Using the $render Operation
Questionnaire
To render a Questionnaire, use the following endpoint:
The 'template-id' parameter specifies the id of the SDCPrintTemplate resource to be used for rendering. repeated-items-count
specifies the number of repetitions for fields marked as repeats
. If this parameter is not provided, the default value is 1.
QuestionnaireResponse
To render a QuestionnaireResponse, use the following endpoint:
Default Template
Aidbox comes with a predefined template default-template
which serves as a universal template for both Questionnaire and QuestionnaireResponse. This template renders all types of widgets in the simplest form of presentation with minimal styles. You can use it as a sample for implementing your own templates.
Creating a Custom Template
Here's how to create your own custom print template:
Let's consider a basic example for clarity: there is a form with three fields (see Figure 1). The task is to create a print version where a table will be generated. In the left column of the table, the title and response from the textarea field will be placed, in the right column - the response from the datetime field, and the field with the signature should not be displayed at all.
![](https://docs.aidbox.app/~gitbook/image?url=https%3A%2F%2F3650793924-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-LHqtKiuedlcKJLm337_%252Fuploads%252Fgit-blob-4d2a88f12ce695fae88a37c314a5f8a4f4a5bb3e%252Fform-for-pdf.png%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=fe827479&sv=1)
Let's create a custom print template with id test
. When writing a template, we can use variables from the render context. In the template we will implement a loop where we will check the linkId of each widget and depending on that, add a specific HTML fragment. For the Signature widget, we do not specify any condition at all, as it should not be displayed.
Now let's render our form using the template we've just created:
![](https://docs.aidbox.app/~gitbook/image?url=https%3A%2F%2F3650793924-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-LHqtKiuedlcKJLm337_%252Fuploads%252Fgit-blob-c61e77f65cd632077d1409ee9c5c948d30722864%252Frendered-form.png%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=439e91f8&sv=1)
Template Render Context
When rendering a template, the template engine has the following variables in the context:
items - A vector containing all the widgets. It is important to note that the widgets are in the same order as they appear in the form. The structure is almost flat, meaning that widgets do not contain children, with the exceptions being Choice Matrix, Grid, and Group Table widgets.
title - The title of the Questionnaire. For QuestionnaireResponse, the title of the associated Questionnaire is used.
repeated-count - The specified number of repetitions for widgets that have the
repeats
property set.is-q - A boolean value that is true if $render was called for a Questionnaire resource.
is-qr - A boolean value that is true if $render was called for a QuestionnaireResponse resource.
Including Other Templates to Your Template
To avoid repetitions in templates, we supported a custom tag include-resource
. Its principle of operation is similar to the Selmer built-in include
tag, but it allows referencing templates declared as an SDCPrintTemplate resource by specifying the resource id as the tag argument. For an example of usage, consider the our default-template
, which reuses the default-widget
template.
FAQ
Q: Why am I Getting 404? A: Verify that all IDs provided in the request are correct. That includes template, Questionnaire, and QuestionnaireResponse IDs. If any of the IDs cannot be found, either because they do not exist or belong to another Organization, the operation will return 404.
Q: Can I use the same template for both Questionnaire and QuestionnaireResponse? A: Yes, the same SDCPrintTemplate can be used for rendering both Questionnaire and QuestionnaireResponse resources, provided it is designed to accommodate the structure of both resource types. However, if you want to create your own template that is suitable for both Questionnaire and QuestionnaireResponse, you will need to consider the differences in the FHIR standard between these resources.
To differentiate between the resource types in the template, you can use two boolean values in the context: is-q
and is-qr
. These values can be used to conditionally render specific sections or elements based on the resource type being processed.
Q: What does "ERROR: template not found template-id" mean in a rendered form? A: This message appears when you use the include-resource
tag in your template and refer to a non-existent template. Double-check that the template with the specified template-id exists.
Last updated