Navigating to job card templates
To configure job card templates, follow these steps:- Select the “Settings” module from the left navigation menu.
- Click “Modules” and select “Jobs” to open the Job Settings page.
- Choose Job Card Templates.

- The job card templates listing page will appear, displaying all existing templates.
Creating a new job card template
To create a new job card template:- On the job card templates listing page, click + New Template.

- A new job card template dialog box will appear.
- Fill in the following details:
- Template Name (Mandatory): Enter a unique name for the job card template.
- Job Category (Mandatory): Select the relevant job category from the dropdown menu.
- Template Description (Mandatory): Provide a brief description of the template.
- Format (Mandatory): Choose the document size from the available options:
- A3
- A4
- A5
- Letter
- Legal
- Tabloid
- Orientation (Mandatory): Select either Landscape or Portrait.
- Border Settings (Mandatory): Define the margins for the job card layout:
- Top Border (e.g., 10mm)
- Right Border (e.g., 10mm)
- Bottom Border (e.g., 10mm)
- Left Border (e.g., 10mm)
- Click Proceed to move to the template editor.

- Table: Add tables to organize and display information in a structured manner.
- Field Components – Easily search for and insert default system fields like:
- Work Order Number
- Job Priority
- Job Description
- Customer Email
- Assigned to FE and more.


Editing a job card template
To modify an existing job card template:- Navigate to the job card templates listing page.
- Click the pencil icon next to the specific template.

- The template editor will open.
- Make the necessary changes.
- Click Save to update the template.
Deleting a job card template
If a job card template is no longer needed, follow these steps to delete it:- Navigate to the job card templates listing page.
- Click the delete icon next to the template you want to remove.

- A confirmation dialog box will appear.
- Click Delete to permanently remove the job card template.
Using dynamic variables in job card templates
{{ }}. Expressions that open a block — such as a loop or a condition — also need a closing tag. For example, {{#each checklist}} opens a loop and {{/each}} closes it. A missing closing tag is one of the most common causes of a template not rendering correctly.Before you start Two building blocks appear throughout every pattern in this article.
- A field is any piece of job data you want to display — for example,
{{job_title}}or{{customer.customer_first_name}}. - A helper is a built-in function that lets you loop through a list, compare values, split text, or format a date before it renders.
Patterns
Pattern 1 — Checklist loop and question matching
Pattern 1 — Checklist loop and question matching
{{#each checklist}}, then use {{#stringEqStrict question 'Your Question Name'}} to target the exact question you want. Add one block per question you need to display.Key fields: checklist, question, answerExample 1 — Display a photo answerUse this example when your checklist question captures one or more photos. Zuper stores photo answers as a comma-separated list of image links, so the template splits that list and renders each image individually.
Example 2 — Display a text remarks answerUse this example when your checklist question captures a free-text response. Zuper stores multi-line text answers with a line break between each entry, so the template splits on that break and wraps each line in its own paragraph.
Pattern 2 — Service task and asset inspection: label field lookup
Pattern 2 — Service task and asset inspection: label field lookup
service_tasks / assets, label, valueService task versionWhat each line does:
Asset versionWhat each line does:
Pattern 3 — Asset inspection: pass, fail, and N/A
Pattern 3 — Asset inspection: pass, fail, and N/A
asset_inspection_submission_uid.data, label, value.badge-pass, .badge-fail, and .badge-na in your template’s CSS section to apply colors to each result badge. Copy the example below into your template’s CSS section to get started. Adjust the colors to match your brand.Pattern 4 — Job status: render sections by current status
Pattern 4 — Job status: render sections by current status
{{#eachLastInstance}} helper handles this — it returns only the most recent status entry so the right section renders every time.Key fields: job_status, status_name{{#stringEq status_name "..."}} blocks for any custom statuses in your workflow.Pattern 5 — Dynamic checklist: type-based rendering
Pattern 5 — Dynamic checklist: type-based rendering
checklist, question, answer, typeExample 1 — Display a specific checklist answer as textUse this when you want to show the answer to one specific checklist question as plain text in your document. In this example, the question is “Work completed notes.”
Example 2 — Display a specific checklist answer as an imageUse this when the answer to a checklist question is a photo captured by the field executive. In this example, the question is “Site photo.”
"Site photo" with the exact question text from your checklist.Pattern 6 — Common job variables
Pattern 6 — Common job variables
{{#if field}}...{{/if}} before adding it to your template. This prevents empty gaps in your document when a field has no value on a particular job.Pattern 7 — Date formatting
Pattern 7 — Date formatting
formatDateWithTimeZone to display any date field in a readable format. Always pass timezone as the third argument so dates display in the customer’s local time zone.Syntax: {{formatDateWithTimeZone field "FORMAT" timezone}}timezone is a job-level field that Zuper populates automatically. Omitting it causes dates to display in UTC instead of the customer’s local time zone.Pattern 8 — Custom fields
Pattern 8 — Custom fields
custom_fields, label, value, type, group_nameExample 1 — Display a specific custom field by nameUse this example when you want to display one specific custom field — for example, the invoice amount paid on a job. The template finds the field by matching its exact label and displays its value.
Example 2 — Display all fields of a specific typeUse this example when you want to display all custom fields of a given type — for example, all time fields or all multi-line text fields. The template loops through every custom field and renders each one that matches the type you specify.
Example 3 — Display fields from a specific group by labelUse this example when your custom fields are organized into groups in Zuper — for example, a group called “Payment Details” that contains fields like “Invoice amount paid” and “Payment method.” The template finds the group by name, then looks up the specific field you want by its label.
Pattern 9 — Parent scope with ../
Pattern 9 — Parent scope with ../
../ before a field name to step out one level and pull in fields from the job level — for example, the job title or work order number.FAQs
Why is a field showing as blank in my rendered document?
Why is a field showing as blank in my rendered document?
../ prefix to reach the parent scope. Wrap the field in {{#if field}}...{{/if}} to confirm whether it has a value. If you are inside a {{#each}} block, add ../ before the field name and test again. If the issue continues, contact Support.Why is my job status section repeating multiple times?
Why is my job status section repeating multiple times?
{{#eachLastInstance job_status "status_name"}} and not {{#each job_status}}. Plain {{#each}} repeats the section for every status the job has ever had. {{#eachLastInstance}} shows only the current one. Second, confirm your {{#stringEq status_name "..."}} filter is present and the status name matches exactly what appears in Zuper — including capitalization. A missing or mismatched filter causes the section to show nothing or display the wrong content.What is the difference between {{#stringEq}} and {{#stringEqStrict}}?
What is the difference between {{#stringEq}} and {{#stringEqStrict}}?
{{#stringEq}} performs a loose match and is not case-sensitive. Use it for status name comparisons such as “Completed” or “Scheduled.” {{#stringEqStrict}} performs an exact, case-sensitive match. Use it when matching question names, inspection labels, or result values such as “Pass,” “Fail,” or “N/A.”Can I nest patterns inside each other?
Can I nest patterns inside each other?
How do I display a date in the customer's local time zone?
How do I display a date in the customer's local time zone?
{{formatDateWithTimeZone field "FORMAT" timezone}}. Always include timezone as the third argument — it is a job-level field that Zuper populates automatically. Omitting it causes dates to display in UTC instead of the customer’s local zone. See Pattern 7 for format token examples.Related articles
- Configuring Job Card Templates — Create and manage job card document templates
- Configuring Job Checklist — Set up checklist questions that appear on jobs
- Configuring Service Tasks — Configure service tasks and attach inspection forms
- Configuring Inspection Forms — Create and manage asset-level inspection forms
- Configuring Job Custom Fields — Add and configure job-level custom fields