Fieldcode Manual

Tip: You can use filters for better results

A document template is an ordinary document file, such as a Word file (.docx), that contains placeholders in curly braces, such as {d.ticket.cne}. When Fieldcode generates a document, it replaces each placeholder with data from the ticket and produces the finished file, for example a service report showing the customer’s address, the parts used, photos and a signature.

You design the layout yourself: logo, tables, fonts and colours work exactly as in any other Word document. Fieldcode changes only the placeholders, so everything else appears in the output as you designed it.

You can build a template in Microsoft Word, LibreOffice Writer or any other word processor that saves in .docx or .odt format. Fieldcode accepts .odt, .ods, .odp, .docx, .xlsx, .pptx and .odg files, so a template can also be a spreadsheet or a presentation. This page covers word processor documents.

With placeholders, a template can:

  • insert single values, such as the work order number, customer name or device serial number
  • format dates and times
  • pick a specific entry out of a list, such as the work time or a photo with a particular tag
  • repeat a table row for every item in a list, such as the parts used
  • insert images, such as photos and the customer’s signature

Each of these is explained in the sections below, followed by a fully annotated example template.

A placeholder is the path to a value in the ticket data, written between curly braces and starting with d., for example {d.ticket.device.serial}. The d stands for the data Fieldcode sends when it generates the document.

Each dot in the path steps one level deeper into the data, much like folders in a file path. {d.ticket.device.serial} reads as: in the data, open the ticket, then the device, then retrieve the serial number.

Keep these rules in mind when you type a placeholder:

  • Paths are case-sensitive. {d.ticket.device.Serial} will not find the serial number.
  • Empty values leave an empty space. If the ticket has no value for a field, the placeholder is removed and nothing is printed in its place.
  • The value takes the placeholder’s styling. Font, size, colour and bold applied to the placeholder are applied to the value, so format the whole placeholder the same way.
  • Several placeholders can share one line or cell. Normal text, spaces and line breaks between them are kept. The address block in the example template combines five placeholders:
{d.ticket.affected.addressData.address.street} {d.ticket.affected.addressData.address.number}
{d.ticket.affected.addressData.address.city}, {d.ticket.affected.addressData.address.state}
{d.ticket.affected.addressData.address.zip}
  • Headers and footers work too. A placeholder in the header, such as the work order number, is filled in on every page.

The table lists the paths needed most often. Copy a path into your template exactly as shown. The first rows are taken from the example template.

Edit
FieldPathDescription
Tenant/Reseller company name{d.tenantResource.name.company}The company name of the tenant or reseller
Project name{d.ticket.project.name}The name of the ticket's project
CNI{d.ticket.cni}The ticket number assigned by Fieldcode
CNE{d.ticket.cne}A unique identifier you can assign to the ticket, such as a work order number
Customer name (combined){d.signatures.customerName}The customer's first and last name in one value
Customer company{d.ticket.affected.addressData.name.company}The customer's company name
Customer first name{d.ticket.affected.addressData.name.firstName}The customer's first name
Customer last name{d.ticket.affected.addressData.name.lastName}The customer's last name
Customer street{d.ticket.affected.addressData.address.street}The street of the service location
Customer address number{d.ticket.affected.addressData.address.number}The house number of the service location
Customer city{d.ticket.affected.addressData.address.city}The city of the service location
Customer state{d.ticket.affected.addressData.address.state}The state of the service location
Customer postal code{d.ticket.affected.addressData.address.zip}The postal code of the service location
Customer phone{d.ticket.affected.addressData.contact.phone1}The customer's main phone number
Additional address information{d.ticket.affected.addressData.address.note}Extra details for the address, such as a floor or access notes
Ticket category{d.ticket.categoryConstant.enumeration}The ticket category, as its fixed technical value
Description{d.ticket.request.description}The description of the service request
Device installation date{d.ticket.device.installationDate}The date the device was installed. Add formatD to print it in a readable form.
Device type{d.ticket.device.type}The type of the device being serviced
Device serial number{d.ticket.device.serial}The serial number of the device being serviced
Device model{d.ticket.device.model}The model of the device being serviced
Engineer's work note{d.ticket.lastIntervention.reporting.workNote}The work note from the latest intervention report
Engineer name{d.signatures.engineerName}The name of the engineer who signed the report

Custom fields created in the Custom Fields Designer can be placed in a template like any other field. In the paths above, replace customField with the Custom field name of your field.

Use the custom field name, not the label. The name is the field’s unique database name and cannot contain spaces or special characters, so it always works in a path. The label is only what users see in forms and is ignored by the template.

Edit
FieldObjectPathDescription
Custom ticket fieldTicket{d.ticket.customField}The value of a custom field added to a ticket's overview tab
Custom device fieldDevice{d.ticket.device.customField}The value of a custom field added to a ticket's device tab
Custom report fieldReport{d.ticket.lastIntervention.reporting.customField}The value of a custom field from the latest intervention report
Custom checklistChecklist{d.ticket.lastIntervention.reporting.checklist.customField}All selected answers, separated by commas
Custom checklist, first itemChecklist{d.ticket.lastIntervention.reporting.checklist.customField[0]}The first answer of a checklist custom field, if it was selected

For a checklist-style field, add a number in square brackets to print one specific answer.

Counting starts at 0 In placeholders

The first item is number 0, not number 1. So [0] stands for the first answer in the checklist, [1] for the second, [2] for the third, and so on. Each placeholder prints its answer only if that answer was selected during reporting. Otherwise it prints nothing.

For example, a checklist offers the answers Filter replaced, Fan cleaned and Firmware updated. The engineer selects the first and the third. [0] prints Filter replaced, [1] prints nothing, and [2] prints Firmware updated.

To print all selected answers on one line, separated by commas, use the field without a number:

{d.ticket.lastIntervention.reporting.checklist.customField}

To list the selected answers below each other instead, give each answer its own line. Because unselected answers print nothing, they would leave empty lines, so add a drop tag to each line to remove them:

{d.ticket.lastIntervention.reporting.checklist.customField[0]}{d.ticket.lastIntervention.reporting.checklist.customField[0]:ifEM:drop(p)}
{d.ticket.lastIntervention.reporting.checklist.customField[1]}{d.ticket.lastIntervention.reporting.checklist.customField[1]:ifEM:drop(p)}
{d.ticket.lastIntervention.reporting.checklist.customField[2]}{d.ticket.lastIntervention.reporting.checklist.customField[2]:ifEM:drop(p)}

In the example above, this prints Filter replaced and Firmware updated directly below each other, with no gap for Fan cleaned.

Add one line for every answer the checklist offers. Press Enter at the end of each line, not Shift+Enter. The drop tag removes a whole paragraph, and lines separated with Shift+Enter belong to the same paragraph, so they would all be removed together. Dropping is explained in more detail in Hiding empty content.

Dates and times are stored in a technical format, such as 2026-10-14T14:26:20-04:00. To print them in a readable form, add the formatD formatter to the end of the placeholder, separated by a colon:

{d.ticket.lastIntervention.reporting.durations[constant.enumeration='WORKTIME'].start:formatD('L')}

The letters between the quotes are the pattern. They decide whether the date, the time or both are printed. The example template uses the same value, the start of the work time, twice: once with 'L' to print the date, and once with 'LTS' to print the time.

Common patterns

These patterns print dates and times in English (US) style, with the month before the day. The examples show a work start of 2:26:20 PM on the 14th of October 2026.

Edit
PatternPrintsExample
LDate, short10/14/2026
LLDate, written outOctober 14, 2026
LTTime2:26 pm
LTSTime with seconds2:26:20 pm
LLLDate and timeOctober 14, 2026 2:26 PM
LLLLWeekday, date and timeWednesday, October 14, 2026 2:26 PM

Fixed patterns

To print dates in another layout, such as day before month, build the pattern from these codes instead:

Edit
CodeMeaningExample
DDDay, two digits14
MMMonth, two digits10
MMMMMonth nameOctober
YYYYYear2026
ddddWeekdayWednesday
HHHour, 24-hour clock14
mmMinutes26

Combine the codes with any separator you like. For example, formatD('DD.MM.YYYY') prints 14.10.2026 and formatD('HH:mm') prints 14:26.

After uploading, check the dates and times in a test document against the ticket. This confirms they appear in the expected time zone and layout. The time zone is set when you upload the template, as described in Saving, uploading and testing.

Durations

Durations, such as the work time and drive time, are stored as a number of seconds. A work time of 1 hour, 30 minutes and 30 seconds is stored as 5430. To print a duration in minutes, hours, or as a clock time, add calculation formatters to the placeholder.

The examples use the work time. For the drive time, replace WORKTIME with DRIVE.

Seconds, for example 5430:

{d.ticket.lastIntervention.reporting.durations[constant.enumeration='WORKTIME'].duration}

Minutes, for example 91:

{d.ticket.lastIntervention.reporting.durations[constant.enumeration='WORKTIME'].duration:div(60):round(0)}

Hours, for example 2:

{d.ticket.lastIntervention.reporting.durations[constant.enumeration='WORKTIME'].duration:div(3600):round(0)}

Hours:Minutes, for example 01:30. Two placeholders with a colon between them:

{d.ticket.lastIntervention.reporting.durations[constant.enumeration='WORKTIME'].duration:div(3600):floor():padl(2,'0')}:{d.ticket.lastIntervention.reporting.durations[constant.enumeration='WORKTIME'].duration:mod(3600):div(60):floor():padl(2,'0')}

Hours:Minutes:Seconds, for example 01:30:30. Three placeholders with a colon between each:

{d.ticket.lastIntervention.reporting.durations[constant.enumeration='WORKTIME'].duration:div(3600):floor():padl(2,'0')}:{d.ticket.lastIntervention.reporting.durations[constant.enumeration='WORKTIME'].duration:mod(3600):div(60):floor():padl(2,'0')}:{d.ticket.lastIntervention.reporting.durations[constant.enumeration='WORKTIME'].duration:mod(60):floor():padl(2,'0')}

The clock-time formats combine two or three placeholders, one for each part, separated by a colon typed as normal text. Each formatter does one calculation, from left to right:

Edit
FormatterWhat it does
div(60)Divides by 60, turning seconds into minutes. div(3600) turns seconds into hours.
mod(3600)Keeps only what is left over after full hours. mod(60) keeps what is left over after full minutes.
round(0)Rounds to a whole number, up or down.
floor()Rounds down to a whole number, so 1.5 hours counts as 1 full hour.
padl(2,'0')Adds a leading zero to single digits, so 1 becomes 01.

round(0) rounds to the nearest whole number, so 1 hour and 30 minutes prints as 2 hours. Use the clock-time formats when the exact time matters.

Some data is a list of entries rather than a single value. A filter in square brackets picks one entry from the list. For example, an intervention report stores its times as a list of durations, with one entry for drive time and one for work time:

durations
 ├─ entry: constant.enumeration = DRIVE,    duration = 900
 └─ entry: constant.enumeration = WORKTIME, start = 2026-10-14T14:26:20, end = 2026-10-14T15:26:20

To print the start of the work time, add a filter directly after the list name:

{d.ticket.lastIntervention.reporting.durations[constant.enumeration='WORKTIME'].start}

This reads as: from the durations, take the entry whose constant.enumeration is WORKTIME, then print its start. Everything after the closing bracket continues the path inside that entry, and formatters such as :formatD('L') still go at the very end.

Use straight quotes in filters

Word may change ' into curly quotes (‘ ’) as you type, and a filter with curly quotes matches nothing. If Word changes a quote, press Ctrl+Z straight away to undo it, or paste the whole placeholder from a plain-text editor.

Keep these rules in mind:

  • Values are case-sensitive. 'WORKTIME' matches, 'Worktime' does not.
  • Filter on the enumeration, not the display text. Each entry also has a displayText, such as “Worktime”, but it can change with the language. The enumeration value stays the same.
  • No match prints nothing. If the ticket has no matching entry, the placeholder is removed and the space stays empty.
  • Several matches print the first one. Use a value that identifies exactly one entry.
  • Position works too. [0] picks the first entry in a list, [1] the second, as with checklist answers.

Common filters

Edit
ListFilterPicks
durations[constant.enumeration='WORKTIME']The work time, with start and end
durations[constant.enumeration='DRIVE']The drive time
attachments[tags.documentTags='ATTACHMENT_TAG']The attachment with that tag, such as a before or after photo

Attachment filters pick an attachment by the document tag it was given in Fieldcode. Replace ATTACHMENT_TAG with one of your own tags. You create these in the Admin panel under Value Sets, in the value set called Attachment type. Use the tag in the filter exactly as it is stored there, including capital letters and underscores.

How to place a photo in the template is covered in Images and signatures.

A parts table prints one row for every part used on the ticket, however many there are. You build it once with two template rows, and Fieldcode repeats them for each part.

Edit
Part numberNameQuantityStatus
{d.items[i].partNumber}{d.items[i].name}{d.items[i].quantity}{d.items[i].status}
{d.items[i+1].partNumber}{d.items[i+1].name}{d.items[i+1].quantity}{d.items[i+1].status}
  • The [i] row is the pattern for each part. It is repeated once per part, with that part’s values.
  • The [i+1] row marks where the repetition ends. It is removed from the finished document.
  • The header row has no placeholders, so it appears once at the top.

With two parts on the ticket, the table above prints:

Edit
Part numberNameQuantityStatus
PSU-650Power supply 650W1Used
CBL-SATASATA cable2Used

How to add a parts table

  1. Insert a table with one header row and two more rows.
  2. Type the column titles in the header row.
  3. In the second row, type a placeholder in each column using [i], such as {d.items[i].name}.
  4. Copy the second row into the third row and change every [i] to [i+1].

Keep these rules in mind:

  • Keep the two rows together. The [i] and [i+1] rows must sit directly below each other, with the same columns.
  • Use the index in every placeholder. Each placeholder in the two rows needs [i] or [i+1], otherwise it is not repeated.
  • Style the [i] row. Its fonts, borders and shading are applied to every printed row. Styling in the [i+1] row does not appear.
  • No parts, no rows. If no parts were used, both rows are removed and only the header row remains.

Images work differently from text. Instead of typing the placeholder into the page, you insert a stand-in picture and put the placeholder in that picture’s Alt Text. When the document is generated, Fieldcode swaps the stand-in for the real photo or signature, in the same position and at the same size.

How to add a photo

  1. Insert any picture where the photo should appear. A plain grey square works well, because it is easy to recognise as a stand-in.
  2. Resize the picture to the space the photo may take up. The real photo is fitted inside this frame.
  3. Right-click the picture and select Edit Alt Text (View Alt Text in some versions of Word).
  4. Make sure Mark as decorative is not ticked. Word clears the Alt Text of decorative pictures.
  5. Paste the placeholder into the Alt Text field, for example:
{d.attachments[tags.documentTags='ATTACHMENT_TAG'].source:imageFit(contain)}

Replace ATTACHMENT_TAG with the tag of the photo you want, as explained in Filtering data. The :imageFit(contain) at the end scales the photo to fit inside the frame without stretching it or cutting anything off.

In other word processors, look for the picture’s alternative text or description field.

Place images in table cells

Putting each stand-in picture in its own table cell keeps photos aligned and stops them from moving other content when they are swapped in.

How to add a signature

Signatures are added the same way: insert a stand-in picture where the signature should appear, size it, and paste this placeholder into its Alt Text:

{d.signatures.signaturesV2.customerSignature.data:prepend('data:image/png;base64,'):imageFit(contain)}

The signature is stored as raw image data. The :prepend('data:image/png;base64,') part adds the label that marks it as a PNG image, so it can be displayed. Copy the placeholder exactly as shown.

To print the signer’s name under the signature, add a text placeholder such as {d.signatures.customerName} below the picture. The engineer’s name is available as {d.signatures.engineerName}.

If a photo or signature is missing, the stand-in picture shows an empty frame with a cross. To remove it instead, see Hiding empty content.

An empty placeholder prints nothing, but its label, table row or picture frame stays in the document. A drop tag removes that element when the value is empty:

{d.ticket.lastIntervention.reporting.workNote:ifEM:drop(row)}

This reads as: if the work note is empty (ifEM), drop the table row (drop(row)). The drop tag prints nothing itself. Place it anywhere inside the element it should remove.

What you can drop

Edit
ElementRemovesWhere to put the tag
pA paragraphAnywhere in the paragraph
rowA table rowIn any cell of the row
colA table columnIn one cell of the column
tableA whole tableIn any cell of the table
imgA pictureIn the picture's Alt Text, after the image placeholder

Dropping a paragraph

To remove a line with a label when its value is empty, add the drop tag at the end of the line:

Customer company: {d.ticket.affected.addressData.name.company}{d.ticket.affected.addressData.name.company:ifEM:drop(p)}

Dropping table rows

To remove a table row when its value is empty, add the drop tag to any cell in the row. In the example template, the Engineer’s Notes row disappears when there is no work note:

Edit
Engineer's Notes:{d.ticket.lastIntervention.reporting.workNote}{d.ticket.lastIntervention.reporting.workNote:ifEM:drop(row)}

Add a number to drop several rows at once. drop(row, 2) removes the row with the tag and the row below it. Placed in the Parts title row, this tag removes the title and the column headers when no parts were used:

{d.items:len:ifEQ(0):drop(row, 2)}

Here len counts the parts and ifEQ(0) checks whether there are none.

Dropping pictures and signatures

If a ticket has no photo with the tag, or no signature, the stand-in picture is replaced by an empty frame with a cross through it. To remove the picture instead, add a drop tag to the same Alt Text, directly after the image placeholder:

{d.attachments[tags.documentTags='ATTACHMENT_TAG'].source:imageFit(contain)}{d.attachments[tags.documentTags='ATTACHMENT_TAG'].source:ifEM:drop(img)}

Only that picture is removed, so other photos in the same table row stay in place.

For a signature, check the signature data without the prepend part:

{d.signatures.signaturesV2.customerSignature.data:prepend('data:image/png;base64,'):imageFit(contain)}{d.signatures.signaturesV2.customerSignature.data:ifEM:drop(img)}

This matters because prepend adds text to the value, so a check that includes it never sees the signature as empty.

Rules

  • Put the tag inside the element. A drop tag only removes the paragraph, row, table or picture it sits in.
  • End each line with Enter, not Shift+Enter. drop(p) removes a whole paragraph. Lines separated with Shift+Enter belong to the same paragraph, so they are all removed together.
  • Check the raw value. Leave out formatters such as prepend or formatD in the check, so an empty value is recognised as empty. An image formatter such as imageFit in the check can even stop the template from loading.
  • keep works the other way. keep instead of drop keeps the element only when the check is true, and removes it otherwise.
  •  

Known limitations

  • ODS templates only support dropping/keeping col, row, img, and sheet.
  • XLSX templates only support dropping/keeping row and col.
  • PPTX templates only support dropping/keeping col, row, img, p, shape, chart, and table.
  • HTML templates only support dropping/keeping table, col, row, p, div, and span.

Save the template as a .docx file (Word) or an .odt file (LibreOffice Writer), then upload it in the Admin panel under Projects and More → Templates. The full upload steps are described in Template Settings.

Three settings in the document template form affect how your template is filled:

  • Object – The object the document is created from. For a service report like the example template, select the ticket.
  • Format – The file type of the finished document. The default is PDF.
  • Timezone – The time zone used for dates and times. For ticket documents, the default is the ticket’s time zone.

How to test a template

  1. Upload the template and click Save.
  2. Check the preview in the document template form. Select a ticket from the list of most recent tickets, or use the search to find a specific one. For a report of completed work, choose a ticket that has already been reported, with the status RESOLVED or CLOSED, so that the report data is filled in.
  3. Test with a ticket that has all the data the template uses, such as parts, tagged photos, a signature and logged work time. A test ticket works well for this.
  4. Test again with a ticket that is missing some of that data, to check that empty content is hidden as intended.

In each test document, check that:

  • every placeholder has been replaced, and none appears as plain text
  • dates and times show the right values, in the right time zone
  • photos and signatures appear in the right frames
  • the parts table shows one row per part, without the [i+1] row
  • empty rows, paragraphs and pictures are removed where you added drop tags

If something is wrong, correct the template in Word, upload it again and repeat the test.

Most problems come from a placeholder that does not exactly match the data. Find the symptom in the table, then check the likely causes.

Edit
ProblemLikely causeFix
A placeholder appears as plain text in the documentA missing or extra curly brace, a typo in d., or a tag that Fieldcode does not supportCompare the placeholder with the examples on this page, character by character. Remove tags that are not described here.
A value stays emptyThe path is wrong, uses the wrong capital letters, or the ticket has no value for that fieldCopy the path from the field tables. Check in Fieldcode that the ticket actually has the value.
A filtered value stays emptyThe filter contains curly quotes, or the value in quotes does not match exactlyRetype the quotes as straight quotes. Check the spelling and capital letters of the value.
The template is refused when you upload itBroken placeholder syntax, such as a missing closing brace, imageFit inside a drop check, or a feature that Fieldcode does not supportRemove recently added placeholders one at a time and upload again to find the one causing the problem.
A photo or signature shows an empty frame with a crossThe ticket has no attachment with that tag, or no signatureAdd a drop tag, as described in Hiding empty content. Check the tag name in the Attachment type value set.
Times are off by a few hoursThe time zone setting of the document templateCheck the Timezone setting in the document template form.
The parts table shows an extra or empty rowThe [i] and [i+1] rows are not directly below each other, or a placeholder is missing its indexPlace the two rows together and add [i] or [i+1] to every placeholder in them.
Text formatting looks different from the templateOnly part of the placeholder was formattedSelect the whole placeholder, including the braces, and apply the formatting again.
Use straight quotes in filters

Word may change ' into curly quotes (‘ ’) as you type, and a filter with curly quotes matches nothing. If Word changes a quote, press Ctrl+Z straight away to undo it, or paste the whole placeholder from a plain-text editor.

If a placeholder still does not work, delete it and type it again in one go. Editing a placeholder in several steps can leave hidden formatting inside it.

The example template is a complete service report for Swift Tech Services, a fictional company. It uses every technique described on this page, so you can download it, upload it to Fieldcode and see how each part works with your own tickets.

The report is built from one table, divided into the parts below. Each part links to the section of this page that explains it.

  • Work Order – The work order number, as a single placeholder. See Placeholder basics.
  • Logo – An ordinary picture with no placeholder, so it appears unchanged in every report.
  • Service Location – The customer’s name, company and address. The address combines several placeholders on three lines. See Placeholder basics.
  • Service Request – The description of the request, as a single placeholder.
  • Device Details – The device type and serial number, as single placeholders.
  • Parts – One row for every part used, built with the [i] and [i+1] rows. See Repeating rows.
  • Action Taken – The date, work start and work end. A filter picks the work time, and formatD prints the date or time. See Filtering data and Formatting dates, times and durations.
  • Engineer – The engineer’s name and work note, as single placeholders.
  • Photos – The before, after and additional photos, with placeholders in the pictures’ Alt Text and drop tags for missing photos. See Images and signatures and Hiding empty content.
  • Signatures – The engineer’s and customer’s names, and the customer’s signature as a picture with a drop tag. See Images and signatures.

Adapting the example

To turn the example into a template for your own company:

  1. Replace the logo with your own. Right-click it and select Change Picture.
  2. Change the photo tags in the Alt Text, such as BEFORE_PHOTO, to the tags in your Attachment type value set.
  3. Remove the parts you do not need, or add fields from the tables on this page.
  4. Upload the template and test it, as described in Saving, uploading, and testing.
Was this topic helpful?
0 out of 5 stars
5 Stars 0%
4 Stars 0%
3 Stars 0%
2 Stars 0%
1 Stars 0%
5
How can we further improve this topic?
Please provide the reason for your vote. This will help us improve this topic.
Navigation