Template Builder User Guide

Version 3.0 | Published October 04, 2023 ©

Template Scripting

If dynamic or advanced customization of the fill-in form is needed, Viz Pilot Edge allows this through template scripting.

Scripts are written in TypeScript, and access the template via a provided Script API named vizrt.

It allows users to customize how templates look and behave, as well as fill in values from external sources. This section describes how to use the script editor, and access the values of the fields supported in Template Builder.

Info: Check out the Quick Start Examples for some quick hands-on experience.

Note: For testing API endpoints, please use the following:

  • HTTP://<PDS-HOST>:8177/testing/fakepremierleague/

  • HTTP://<PDS-HOST>:8177/testing/fakepersonsearch/

These are the following topics:

The Script Editor

The script editor is available in the "Fill-in Form" tab of Template Builder.

images/download/attachments/125459362/image2022-3-17_15-24-27.png

It can be used docked or undocked from the Template Builder. While undocked, you can adjust the size of the window for a smoother experience.

There is a search option to search within the script code, and you can access it by clicking the icon images/download/thumbnails/125459362/SearchWithinScriptEditor_-_Copy.JPG within the script editor.

images/download/attachments/125459362/DockedScriptEditor.JPG

The script editor also provides error messages depending on the problem. It will show compile or run time errors.

Compile Error

images/download/attachments/125459362/CompileTimeErrorReporting.JPG

Runtime Error

images/download/attachments/125459362/RunTimeErrorReporting.JPG

When trying to catch a runtime error, it is recommend that you name a function with a string value. By naming a function, this name is used in the error message to indicate where the error came from.

In the following example, if you catch an error, the string used under "user defined name" is shown in the error message:

images/download/attachments/125459362/MicrosoftTeams-image_%283%29.png

In this case, you can just add the string value in your function error report so it shows in the error message:

images/download/attachments/125459362/MicrosoftTeams-image_%284%29.png

Initialization

There are two global events that can be used to initialize the Fill-in Form:

  • onCreate: Called when template is opened in Viz Pilot Edge.

    Note: This event is not triggered when creating a new data-element from an existing one.

    Example:

    vizrt.onCreate = () => {
    // For example set startup values, initialize fields visibility, etc.
    Initialize()
    }
  • onLoad: Called when an existing data-element is loaded in Viz Pilot Edge. The normal steps are to initiate/refresh data each time you open a data-element.

    Note: This event can potentially modify the data-element when opening, which means it must be saved before being draggable/sendable to a NRCS.

    Example:

    vizrt.onLoad = () => {
    // For example reset or refresh values, etc.
    ResetForm()
    }

Info: These events must be defined in the Template Builder's script, but they are not triggered in Template Builder.

Field Access

When using the scripting tool in the template, the individual fields must be accessed through the global name space vizrt.fields (for example, vizrt.fields.$singleline.value).

Note: Writing $singleline.value instead of vizrt.fields.$singleline.value will not work, and will give a Compile Error.

The script executes when a graphic element is opened or created with the scripted template in Viz Pilot Edge.

In Template Builder, the script is also re-loaded and restarted when there are changes made to it.

By typing vizrt.fields, the editor's autocomplete will show you the available fields to choose from.

images/download/attachments/125459362/image2021-12-3_14-53-10.png

You can read and write field values, as well as react to value changes from outside the script.

You can also access the properties error, hidden, readOnly, and tip of the vizrt fields.

images/download/attachments/125459362/image2021-12-3_14-52-19.png

  • onChanged: A property on fields that you can set as a function, and if you do so, this function is called whenever the value of the fields changes, and gets the new value as an argument . If this is not set, it is null.

    Note: Changes done to field values by the template script will not trigger the onChanged function to be called.

  • readOnly: Read and write boolean access, to whether the field should be editable in the form or not. If false , the field and its input elements are editable in the UI. If true , they are read-only and greyed out in the UI, but are accessible, saved and loaded as part of the payload.

  • hidden: Read and write boolean access, to whether the field should be editable in the form or not. If false , the field and its input elements are present and visible in the UI. If true , they are hidden from the UI but are accessible, saved and loaded as part of the payload.

  • error: Read and write string access, to an error to display for this field. It overrides other error messages associated with the field when non-empty (e.g. errors due to input length or regex constraints specified in the field definition).

  • tip: Read and write string access, to a tip to use for this field. It overrides the tip specified in the field definition when non-empty.

Note: Dashes cannot be used in Typescript with the dot syntax, instead you can use vizrt.fields["$01-week"] syntax to be able to access it.

Typescript lets you access fields using known names (for example, vizrt.fields["$field_2"]), but does not allow expressing the field names using variables (for example, vizrt.fields["$field_" + num]), as it is unable to determine whether the field name is valid and what type the field is. To overcome this, the type checking associated with vizrt.fields can be locally ignored by using the any type. You may do so inline using for example (vizrt.fields as any)["$field_" + num], or storing it as a new variable, as shown in the example below.

images/download/attachments/125459362/image-2023-9-15_8-43-11.png

Note: Be aware that when using an object cast to any, the script editor will not be able to help you catch errors like setting a boolean value to a string field, or even trying to access a field that does not exist. .

Accessing Concepts & Variants from Scripting

To access the information from concept and variants fields, because they contain dashes, you must use square brackets, as shown in the example below.

images/download/attachments/125459362/image-2023-7-17_14-56-44.png

//When the Concept is changed, get its value and put it in a text field with field name info1
vizrt.fields["$-concept-variant-choice"].$concept.onChanged = () =>
{vizrt.fields.$info1.value =vizrt.fields["$-concept-variant-choice"].$concept.value }
 
//When the Variant is changed, get the value and put it in a text field with field name info2
vizrt.fields["$-concept-variant-choice"].$variant.onChanged = () =>
{vizrt.fields.$info2.value =vizrt.fields["$-concept-variant-choice"].$variant.value }

External Sources

Whether on template load, or as a reaction to a field change, you can initiate HTTP, HTTPS or REST calls to fetch values from third party or external services.

This can easily be done via the browser's built-in fetch API: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API.

See the Quick Start Examples section for a short example of a REST call triggered by an onChanged event.

Image Metadata

Every image has some amount of metadata attached to it, and with this field you are able to access this metadata by using the script editor.

You can upload images and the corresponding metadata to asset source servers. By accessing an image's metadata, you can auto-fill the name field within a template or alternatively display or hide an image that might be copyrighted.

Note: Image scripting metadata currently works for images retrieved from the following asset source servers: Vizone, Vos, GH and OMS.

How to Use the Image Metadata

If you are using a newly created template, simply choose any image, and then query that image's metadata in the script editor by querying the image's metadata map. With an existing template, which already contains an image that was created before the 2.4 version of Template Builder and Pilot Edge, then simply click on the current image and re-select it from the asset selector, or alternatively select another random image and then select back the original one. Once this is done, you can proceed by querying the image's metadata map.

This example checks if imageName has a metadata key named test and then tries to get the value of that metadata key. You can use the script syntax shown below:

let hasMetadataKey: boolean = vizrt.fields.$imageName.metadata.has("test") //true if the metadata contains the key test
let metadataValue: string = vizrt.fields.$imageName.metadata.get("test") //it is set to the value it has in the metadata, otherwise it is undefined

The following example shows a more realistic code example of the scripting metadata functionality. An image field named image1 tries to get the metadata value for description and put it into a text field called img1_txt in case it is found, otherwise a message shows explaining it was not found.

if (vizrt.fields.$image1 != undefined && vizrt.fields.$image1.metadata != undefined) {
let keyName = "description"
   let a = vizrt.fields.$image1.metadata.get(keyName) // get the metadata value that has the given key
   if (a != undefined) {
    vizrt.fields.$img1_txt.value = a // if the value is not undefined, then set it into a string field within the template
} else {           
vizrt.fields.$img1_txt.value = "The key '" + keyName + "' was not found inside the metadata map"
// Alternatively, set it to nothing: vizrt.fields.$img1_txt.value = ""
}
}

This code example will react to any image changes. When the image2 field gets assigned a new image, it tries to get the description from the metadata associated with the new image, into the text field img2_txt. If the description does not exist, a message displays explaining it was not found.

vizrt.fields.$image2.onChanged = () => {
if (vizrt.fields.$image2.metadata != undefined) {
let keyName = "description"
    let a = vizrt.fields.$image2.metadata.get(keyName) // get the metadata value that has the given key
    if (a != undefined) {
    vizrt.fields.$img2_txt.value = a // if the value is not undefined, then set it into a string field within the template
} else {           
vizrt.fields.$img2_txt.value = "The key '" + keyName + "' was not found inside the metadata map"
// Alternatively, set it to nothing: vizrt.fields.$img2_txt.value = ""
}
}
}

To access the entire unprocessed/unparsed metadata file, use wholeMetadataString. This can be useful for debugging, or for finding the keys available in the metadata:

let rawMetadata:string = vizrt.fields.$imageName.metadata.get("wholeMetadataString")

Image Metadata XML

An image's metadata is stored within asset source servers in XML format, and the XML metadata structure should follow a simple field-value (key-value) structure. This is to guarantee that all the metadata is correctly mapped and made accessible through the script editor.
However, since many image metadata XMLs are disorderly, a parser has been created to handle most XML structures, although this has some consequences that should be made aware of. All these example scripts are based on an image field named "image1".

Empty field-value pairs get added accordingly:

<field name="car"/>
<field name="color">
<value/>
</field>
 
// Accessing these can be done using:
 
let a = vizrt.fields.$image1.metadata.get("car")
let b = vizrt.fields.$image1.metadata.get("color")
 
// Both a and b will be ""

Nested structures get stored based on their hierarchy, with "/" being the parent-child separator:

<field name="access-rights">
<field name="user-rights">
<value>true</value>
</field>
</field>
 
// To access the user-rights value:
 
let a = vizrt.fields.$image1.metadata.get("access-rights/user-rights")
 
// a will then be set to true.

Any fields with duplicate names get assigned a unique name with an incrementing suffix:

<field name="file-link-id">
<value>id123</value>
</field>
<field name="file-link-id">
<value>id456</value>
</field>
<field name="file-link-id">
<value>id789</value>
</field>

Access duplicate names like this using the incrementing suffix:

let a = vizrt.fields.$image1.metadata.get("file-link-id")
let b = vizrt.fields.$image1.metadata.get("file-link-id(2)")
let c = vizrt.fields.$image1.metadata.get("file-link-id(3)")
 
a will be "id123"
b will be "id456"
c will be "id789"

Read Only Fields

Some fields are currently supported only for read-access by the scripting API. These are the following:

  • Duplet

  • Triplet

  • Map

  • Image

  • Video


For the Image and Video fields, the script is able to access some properties (their height, width, etc.) from the file.

The following example shows how to retrieve the image height:

vizrt.fields.$ImageInfo.value = "No image info";
 
vizrt.fields.$image.onChanged =() => {
vizrt.fields.$ImageInfo.value = 'Image changed';
 
var v = vizrt.fields.$image.value;
if(v != undefined && v.height != undefined)
vizrt.fields.$ImageInfo.value = v.height.toString();
else
vizrt.fields.$ImageInfo.value = "No image info";
}

Note: Because images and videos can be undefined, they must be checked before they are used.

Unsupported Fields

As of now, all List and Table fields are unavailable from the scripting API.