Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This page contains examples of syntax that can be used for configuration of various data merge scenarios within Document Templates.

Info

Document template merging is performed by the third-party product Aspose Words. 

Full official template syntax documentation can be found online here

Note

The functions and formatting strings listed in this page are case sensitive

Basic Objects Insertion

Document template data source objects may be inserted into a document template using either of the following methods:

  • Double-clicking the object in the data source list to the left of the document 

  • Entering the field tag into the document using the proper format

The following example substitutes <<[siteOwnerName]>> with the site owner name at the time of document generation, a list of available objects in the data source can be found in Standard Document Template Fields:

Code Block
languagetext
Site Owner: <<[siteOwnerName]>>

Note: when selecting a field by double-clicking in the data source list, the selected field will be inserted into the document at the current location of the cursor.

Signature Images

As of release 2022.1, the currentUser data source contains a signatureImage merge field, allowing insertion of the current user's signature image into a document.

Two options are available for insertion of signature images into document templates:

  • at the time of document generation, or

  • at the time of document finalization.

Signatures are inserted into document templates using the signatureImage merge field in the currentUser data source.

Prerequisite: Adding Signature Images to User Accounts

The current user's signature image must have been previously added to nVIRO their user profile for this function to work. This can be added using the Upload Image button on the internal user’s User Details page in Admin > Users. ( Support for signature images, and who can manage them, is configurable and available options will vary based on implementation. )Assuming that signature image support is enabled in a given implementation, there are two options for insertion of signature images: at the time of document generation or at the time of document finalizationSignatures can either be added using the Upload Image button on the internal user’s User Details page in Admin > Users, or on the User Profile screen for self-service management by an internal user.

Inserting a Signature Image at Time of Document Generation

To insert a signature image from the user profile at the time of document generation:

  • Insert a Textbox into the document at the location where the signature is to appear.

  • Within the textbox, insert the following code block:

Code Block
<<image [currentUser.signatureImageIMAGETAG] -fitSizeLim>>

Insert for current user

The signature image from for the user profile will current user (person generating the document) can be inserted into the document at the time of document generation.

Code Block
<<image [currentUser.signatureImage] -fitSizeLim>>

Insert for Submission Staff

The same steps can be used to add the signature image for submission staff (available in the submission data source):

Code Block
<<image [submissionStaffSiganturesubmissionStaffSignature] -fitSizeLim>>

The signature image from the user profile of the processor of an application will be inserted into the document at the time of document generation.

Inserting a Signature Image at Time of Document Finalization

Alternatively, the user profile signature image can be added at the time of document finalization. This method adds the image to the PDF version of the document [but not to the Word version] and can be used as a form of ‘electronic signature’ by the person who finalizes the document.

To insert a signature image at the time of document finalization:

  • Insert a Textbox into the document at the location where the signature is to appear.

  • Within the textbox insert the following code block:

Code Block
[[FinalUserSignature]]

QR Code Generation

As of release 2023.1, a QR code can be generated within document template, a custom text is processed and is displayed in a form of QR image.

To generate a QR image at the time of document generation:

  • Insert a Textbox into the document at the location where the QR code is to appear.

  • Within the textbox, insert the following code block:

Code Block
<<image [TemplateExtensions.StringToQRImageBytes("String to be converted into a QR code",150,150)]>>

To create a complex text string such as a URL with data from the document, use variables to build out the string which will be passed into the StringToQRImageBytes() function. To create a variable use the following and insert it at the beginning of the document template:

Code Block
<<var [v_path =  environmentSettings.applicationUrl + “site/permits/edit/” + id+”/detail”]>>

Then follow the steps above to create a text box and within the text box the text will look as follow:

Code Block
<<image [TemplateExtensions.StringToQRImageBytes(v_path,150,150)]>>

Loops

Loops can be used to find information pertaining to a contact with a particular affiliation type/role code, it can also be used to return the list of violation associated with an evaluation. It is possible to limit the returned values based on certain criteria.

A foreach loop is inserted automatically into the template if an object name (Bold fields name) is double-clicked. Foreach loops are in the following format: 

Code Block
languagetext
<<foreach [field in fields]>>Text or [Fields] here<</foreach>>

Lists returned by loops may be included in the document body or in tables as desired.  Lists may also be filtered to select specific records or to sort / order by specific fields.

For more details on how loops are used check Using Loops in Document Templates.

Logical Operators

The following logical operators can be used to combine or modify Boolean (true/false) expressions, such as those used in <<if>> statements:  

Operator

Meaning

Description

Syntax Example

&&

And

Returns True (or returns value) if both statements are true

<<if[responded == "Yes" && rsvp == "1"]>> 

||

Or

Returns True (or returns value) if either statement is true

<<if[responded == "Yes" || rsvp =="1"]>>

!

Not

Returns True (or returns value) if the statement is false

<<if[!string.IsNullOrEmpty(comment)]>>

Checking for Null Values

In some situations, code in a document template might reference objects that don't exist, causing the template to fail with an error. This can often be prevented by surrounding the code by an if statement that performs a check to make sure that the object in question exists.

For example, the following statement:

Code Block
languagetext
<<if[violations!=null]>>text to display if true<</if>>

can be read as "if violations is not equal to null..." (or in other words, "if a violation exists..."). This prevents the code within the if statement from running if there are no violations.

You can see this statement in action in the example code that appears in the "Breaking Out of a Loop" section. In that code, this statement is used to check for the existence of violations, and the following statement is used to check for the existence of the regulationReference object:

Code Block
languagetext
<<if[regulationReference!=null]>>text to display if true<</if>>

Note that, as with all if statements, both of these statements need to have a corresponding close tag (<</if>>).

Another way to check for Null or empty fields is a function IsNullOrEmpty which checks for null or an empty string (""). or IsNullOrWhiteSpace which checks for null, empty, or consists only of white-space characters. To use the function use the following syntax:

Code Block
languagetext
<<if[!string.IsNullOrEmpty(regulationReference)]>>text to display if true<</if>>

The above code will check the existence of the regulationReference object and return True if the regulationReference object is not null or does not contain empty string ("")

Warning message if data is missing

This example displays a warning message if the organization for the agency contact (Submission Staff Organization) is missing:

Code Block
languagetext
<<if[string.IsNullOrEmpty(submissionStaffOrg)]>>Submission Staff Organization is missing<<else>><<[submissionStaffOrg]>> Section<</if>>

This example displays a warning message if the organization for the agency contact (Submission Staff Organization) is missing:

Preventing blank lines caused by missing data

When checking for null values, it's important to account for the display of text when data actually is missing. For example, when displaying the site address, if the line that checks for the presence of siteAddress2 adds in a new line, the address block will contain a blank line between siteAddress1 and the fields below it (such as siteCity, siteState, siteZip), as shown here:

To prevent this, make sure that a new line added by a null-check statement appears before the closing <</if>> tag. This is most easily accomplished by showing paragraph marks in Word (Ctrl+Shift+8) and manually moving the paragraph mark so that it appears before the closing <</if>> tag, as shown in the following image. Note that, in each null-check statement, the paragraph mark indicated by the red arrow appears before the closing <</if>> tag (underlined in blue):

Format Objects 

Aceoffix allows users to format objects to better control the document outcome and maintain consistency. Date, Text, and Numbers can be formatted. Formatting fields can be done by using a colon ":" after the object closing bracket "]" as follows:

Code Block
languagetext
<<[FieldName]:“Formatting String”>>

Formatting Dates

Dates can be formatted in a variety of ways. The example below shows a few different date-formatting options.

Code Block
languagetext
<<[permitIssueDate]:“yyyy.MM.dd”>> <<[exampleDateWithTime]:”M/d/yyyy h:mm tt”>> <<[exampleDateWithTime]:”D”>>
Info

Note that month formatting should always be capitalized (e.g., "M", "MM", or "MMMM") and the year should always be small caps (eg., "yy", or "yyyy"). 

Below are some predefined date and time format which can be used within document template.

Format

Date Output

<<[DateTime.Now]:"d">>

12/31/2019 

<<[DateTime.Now]:"D">>

Tuesday, December 31, 2019

<<[DateTime.Now]:"F">>

Tuesday, December 31, 2019 1:45 PM

<<[DateTime.Now]:"M">> or <<[DateTime.Now]:"M">>

December 31

<<[DateTime.Now]:"Y">> or <<[DateTime.Now]:"y">>

December 2019

In addition to the predefined date and time a custom formatting can be created using a combination of the Date and Time strings listed below:

Date and Time Format String

Date Output

dd

Day: 31

ddd or dddd

Day: Tue or → Tuesday

MM

Month: 12

MMM or MMMM

Month: Dec or → December

yy or yyyy

Year: 19 or → 2019

HH

Military Hour: 14 

hh

Hour: 1

mm

Minutes: 45

ss

Seconds: 55

tt

AM or PM

An example using a combination of the above formats would be <<[DateTime.Now]:"MMMM dd, yyyy">>, which would result in the format December 31, 2020.


If a date isn't formatting using the above DateTime formatting then it might be stored as a different character type.  In order to convert it into a correct DateTime format try the below Convert.ToDateTime() function:

Code Block
languagetext
<<[Convert.ToDateTime(receivableDate)]:"D">>
<<[Convert.ToDateTime(receivableDate).AddDays(30)]:”MMMM dd, yyyy”>>

Formatting Text

Texts can be formatted to be displayed as, upper, lower, first letter caps, or first letter of each word caps.

Code Block
languagetext
<<[siteName]:caps>>

Available formatting strings are shown in the table below:

Text Format String

Text Output

lower

all lower case text

upper

ALL UPPER CASE TEXT

caps

Only First Letter Of Each Word

firstCap

Only first letter of sentence

In addition to using formatting strings, a function can be used to format texts, .ToUpper(), .ToLower().

The .ToUpper() method can be used to display the value of a field in all capital letters. For example, "John Doe" would be displayed as "JOHN DOE".

Code Block
languagetext
<<[permitPermitteeName.ToUpper()]>>


Warning

A null reference exception will be generated if you attempt to call a method on a null field. See the "Checking for NULL Values" topic above to ensure your template will work under all situations. Note that using formatting strings (caps, lower, upper, etc.) will not throw an exception if the object has null value.

Formatting Numbers & Currency

Code Block
languagetext
<<[NumberToFormat]:"string">>

The table below shows a list of ways to format numbers:

Number Format String

Example

Number Input → Output

c or C 

<<[NumberToFormat]:"c">>

300129 → $300,129.00

e or E

<<[NumberToFormat]:"e">>

1052.0329112756 → 1.052033E+003

n or N

<<[NumberToFormat]:"n">>

1234.567 → 1,234.57

<<[NumberToFormat]:"n1">>

1234 → 1,234.0

<<[NumberToFormat]:"n3">>

1234.56 → 1,234.560

<<[NumberToFormat]:"n0">>

1234 → 1,234

p or P

<<[NumberToFormat]:"p">>

1 → 100.00%

<<[NumberToFormat]:"p1">>

-0.39678 → -39.7%

Numbers can also be formatted to be displayed in a different form, such as First, Second Third, etc., below is a list of possible numbering formats:

Number Format String

Example

Output

alphabetic

<<[NumberToFormat]:alphabetic>>

Formats an integer number as an upper-case letter (A, B, C, ...)

roman

<<[NumberToFormat]:roman>>

Formats an integer number as an upper-case Roman numeral (I, II, III, ...)

ordinal

<<[NumberToFormat]:ordinal>>

Appends an ordinal suffix to an integer number (1st, 2nd, 3rd, ...)

ordinalText

<<[NumberToFormat]:ordinalText>>

Converts an integer number to its ordinal text representation (First, Second, Third, ...)

cardinal

<<[NumberToFormat]:cardinal>>

Converts an integer number to its text representation (One, Two, Three, ...)

hex

<<[NumberToFormat]:hex>>

Formats an integer number as hexadecimal (8, 9, A, B, C, D, E, F, 10, 11, ...)

arabicDash

<<[NumberToFormat]:arabicDash>>

Encloses an integer number with dashes (- 1 -, - 2 -, - 3 -, ...)

Below is an example of how to add a date in the format of "2nd day of January, 2020" using numbers formatting:

Code Block
languagetext
<<[DateTime.Now.Day.ToString()]:ordinal>> day of <<[DateTime.Now]:"MMMM, yyyy">>

If using a date field, the following code could be used

Code Block
languagetext
<<[permitIssueDate.GetValueOrDefault().Day.ToString()]:ordinal>> day of <<[permitIssueDate]:"MMMM, yyyy">>

When formating numbers which are stored in a string format such as data coming from a program component or a submission, the data type should be converted to numbers before applying formatting strings.

The following code displays a number which stored as a string in currency format.

Code Block
languagetext
<<[Convert.ToDouble(fieldName)]:"C">>

The syntax to format text as a hyperlink is as follows:

Code Block
<<link [url] [display text]>>

The following example formats a merge field as a hyperlink:

Code Block
If you have any questions please visit the <<[environmentSettings.productName]>> support page at <<link [environmentSettings.contactUrl]>>.

The following example implements the display text portion of the link:

Code Block
Here is a hyperlink to <<link [environmentSettings.applicationUrl] [environmentSettings.productName]>>.

Building a link using merge fields and text

If the merge fields available don’t work for a specific link, there is a possibility to build links using variables.

Code Block
<<var [v_path =  environmentSettings.applicationUrl + “admin/docset/edit/” + id + “/documents” ]>>
<<link [v_path] [“View Document Set”]>>

Address formatting with check for missing data

In the following example, if the Site Owner Name field is blank, the Site Owner Organization Name is displayed instead.

Also, if there is an Address Line 2, it is displayed; otherwise, Address Line 2 is omitted. (This also prevents a blank line from being displayed where the Address Line 2 field would be.)  

Code Block
languagetext
<<[siteOwnerName]>><<if[string.IsNullOrEmpty(siteOwnerName)]>> <<[siteOwnerOrgName]>><</if>> <<[siteOwnerAddr1]>><<if[!string.IsNullOrEmpty(siteOwnerAddr2)]>> <<[siteOwnerAddr2]>> <</if>> <<[siteOwnerCity]>>, <<[siteOwnerState]>> <<[siteOwnerZip]>>

Accepted System Variables and Functions

Assigning Variables

On occasion you may wish to save a variable in the document. Examples of this may be to print the variable only when the value changes, or to filter records based on the variable.

Examples of variable assignment:

Code Block
languagenone
<<var [current_yr =  DateTime.Now.Year]>> 
Current Year: <<[current_yr]>> 
   will display for example as
Current Year: 2024
Code Block
languagenone
<<var [current_dt =  DateTime.Now]>> 
Current Date: <<[current_dt]>> 
   will display for example as
Current Date: 6/24/2024 4:44:09 PM

Dates and Times Functions and Calculations

This example gives the current date plus the number of days specified, and returns the date in the format given.
More examples of ways to use DateTime can be found here: here.

Code Block
languagetext
<<[DateTime.Now.AddDays(1)]:"MM/dd/yyyy">>

Performing Date Calculations

To use DateTime methods or functions use.GetValueOrDefault() followed by the method name. For example, to return the Year portion of a DateTime value, perform the following:

Code Block
<<[receivedDate.GetValueOrDefault().Year]

The example shown below determines whether there is a date or null value in the field (in this case, the permit expiration date field). If the field is null, then the ‘missing’ message displays. If the field is not null, then a date of 180 days prior to the value in the field is displayed.

Code Block
languagetext
<<if [permitExpirationDateAsDate.HasValue]>><<[permitExpirationDateAsDate.GetValueOrDefault().AddDays(-180)]:”MM/dd/yyyy”>><<else>>(Permit Expire Date Missing!)<</if>>

To calculate the difference between two dates, .Subtract() can be used as follows:

Code Block
languagetext
<<[permitExpireDate.GetValueOrDefault().Subtract(permitIssueDate.GetValueOrDefault()).ToString("%d")]>>

The above code will return the difference between PermiteExpireDate and PermitIssueDate in days.

In addition to AddDays() method the list below shows more methods that can be used to calculate a date:

Method

Discription

AddDays(int)

Returns a new DateTime that adds the specified number of days to the value of this instance.

AddHours(int)

Returns a new DateTime that adds the specified number of hours to the value of this instance.

AddMilliseconds(int)

Returns a new DateTime that adds the specified number of milliseconds to the value of this instance.

AddMinutes(int)

Returns a new DateTime that adds the specified number of minutes to the value of this instance.

AddMonths(int)

Returns a new DateTime that adds the specified number of months to the value of this instance.

AddSeconds(int)

Returns a new DateTime that adds the specified number of seconds to the value of this instance.

AddYears(int)

Returns a new DateTime that adds the specified number of years to the value of this instance.


Info

A negative number (int) can be used in the methods above to subtract from DateTime

String and Texts

Objects which their data type is string can be manipulated using functions or methods a list of methods can be found here, note that not all methods can be used within the document templates.

Return the length of a string

The .Length method returns the length of a string:

Code Block
languagetext
<<[permitPermitteeName.Length]>>

Warning! A null reference exception will be generated if you attempt to call a method on a null field. See the "Checking for NULL Values" topic above to ensure your template will work under all situations.

Trim characters from end of a string

To remove a specified number of characters from the end of a string, use the .Remove() method as shown below:

Code Block
languagetext
<<[permitPermitteeName.Remove(x)]>> <<[permitPermitteeName.Remove(x,y)]>>

In this case, x is the zero-based index of the first character you want to remove. For example, if your string is “ABCDEF” and you want to return “ABC”, x would be 3. (“A” is index 0, “B” is index 1, etc.). This example only works if the length of the string is static. If it is variable, syntax like the following can be used.

Code Block
languagetext
<<if[permitNumber.Length>9]>><<[permitNumber.Remove(10)]>><<else>><<[permitNumber]>><</if>>

To removes all the trailing occurrences of a set of characters specified in an array from the current string, use the .TrimEnd() method as shown below:

Code Block
languagetext
<<[permitPermitteeName.TrimEnd("char to remove".ToCharArray())]>>

To remove all leading and trailing white space from a string use .Trim() method

Code Block
languagetext
<<[permitPermitteeName.Trim()]>>

Trim characters from beginning of a string

To remove all the leading occurrences of a set of characters specified in an array from the current string, use the .TrimStart() method as shown below and replace "char to remove" with the character to remove:

Code Block
languagetext
<<[permitPermitteeName.TrimStart("char to remove".ToCharArray())]>>

When the data in the beginning of a string is variable and you can't predetermine the characters then you can remove variable data from the beginning/end of a string like this, as long as it will always be the same amount of characters to remove:  

Code Block
languagetext
<<[coLwSiteInfo.basin.Remove(starting position, #chars to remove)]>>

Or you can use functions like IndexOf() and Length shown in this example that acts as a Left() function (leaving behind only the characters left of the "char to find"): 

Code Block
languagetext
<<[TAG.Remove(TAG.IndexOf("char to find"), (TAG.Length-TAG.IndexOf("char to find"))]>>

Or you can use functions like IndexOf() and Length shown in this example that acts as a Right() function (leaving behind only the characters right of the "char to find"): 

Code Block
languagetext
<<[TAG.Remove(0,TAG.IndexOf("char to find")]>>

Otherwise you might look into doing an Substring and finding the IndexOf() say a dash or something similar.  

Comparing two strings

To compare two strings and return a value if they are a match, use the following:

Code Block
languagetext
<<if[string.Compare(permitteeName,siteName) == 0]>>They are exactly the same<<else>>They are different<</if>>

To account for case difference between two fields such as PERMITTEE and permittee we can use .ToUpper method as follows:

Code Block
languagetext
<<if[string.Compare(permitteeName.ToUpper(),siteName.ToUpper()) == 0]>>They are the same<<else>>They are different<</if>>


Info

.Compare() function is case sensitive and will return Permittee and permittee as different text, to overcome this, .ToUpper or .ToLower function can be used to force both fields becomes the same case then compare.

Comparing the start of a string to a pattern

To compare the start of a string to a pattern, use the StartsWith() method. This example evaluates the first character of coWqc.coWqcCoe. If it is "M", display "Mobile", else "Nashville":

Code Block
languagetext
<<if[(coWqc.coWqcCoe.StartsWith(“M”))]>>Mobile<<else>>Nashville<</if>>

More methods for strings:

Method

Discription

Contains(String)

Returns a value indicating whether a specified substring occurs within this string.

Compare(string,string)

Return 0 for exact match

EndsWith(String)

Determines whether the end of this string instance matches the specified string.

Equals(String)

Determines whether this instance and another specified String object have the same value. (case sensitive)

IndexOf(String)

Reports the zero-based index of the first occurrence of the specified string in this instance.

PadLeft(int)

Returns a new string that right-aligns the characters in this instance by padding them with spaces on the left, for a specified total length.

PadRight(int)

Returns a new string that left-aligns the characters in this string by padding them with spaces on the right, for a specified total length.

Replace(String, String)

Returns a new string in which all occurrences of a specified string in the current instance are replaced with another specified string.


StartsWith(String)

Determines whether the beginning of this string instance matches the specified string.

Trim()

Removes all leading and trailing white-space characters from the current string.

TrimStart(char[])

Removes all the leading occurrences of a set of characters specified in an array from the current string.

TringEnd(char[])

Removes all the trailing occurrences of a set of characters specified in an array from the current string.

Additional if/else Statement Examples

The following example displays Phone and Email contact information if those fields are populated, or placeholder text if one or both of the fields are empty: 

Code Block
languagetext
<<if[string.IsNullOrEmpty(caAssignedStaffPhoneFull)]>>Phone ### <<else>><<[caAssignedStaffPhoneFull]>><</if>> or by e-mail at <<if[string.IsNullOrEmpty(caAssignedStaffEmail)]>>email <<else>><<[caAssignedStaffEmail]>><</if>>

In the following example, a different contact type is displayed if the first isn't available.  The code checks the count of affiliations with a type code of "IWBILL".  If the count = 0 then it instead displays the first affiliation [using .Take(1)] for the type code of "PERMCT":

Code Block
languagetext
<<if[contacts.Where(x => x.affiliationTypeCode == “IWBILL”).Count() == 0]>> <<foreach [contact in contacts.Where(x => x.affiliationTypeCode == “PERMCT”).Take(1)]>> <<[contact.contactAddress1]>> <<[contact.contactCityStateZip]>> <</foreach>> <</if>>

In the following example, an "Unspecified Due Date" message is displayed if the permit due date field is blank:

Code Block
languagec#
<<if [permitDueDate == null]>>“Unspecified Due Date”<<else>><<[permitDueDate]:“dd/MM/yyyy”>><</if>>

This example uses an if/else statement to display data based on a specified region:

Code Block
languagetext
<<var [string region1 = “County1 County2 County3”]>> <<var [string region2 = “Berkeley Charleston Dorchester ”]>> <<if [region1.Contains(siteCounty + “ “)]>> Region 1 <<elseif [region2.Contains(siteCounty + “ “)]>> Region 2 <<else>> No Region <</if>>

Performing if/else statement on a value that may be null

When needing to evaluate a value in an if/else statement that may be null, the following will not work, as both if/else statements appear to be evaluated even though the nested if/else should be ignored:

Code Block
<<if[coWqc.coWqcCoe != null]>><<if[coWqc.coWqcCoe.StartsWith(“M”)]>>Mobile<<else>>Nashville<</if>><<else>>TBD<</if>>

This will return an error:

There was an error generating the document from the data source:Tag 'if' is not well-formed. A conditional expression should return a Boolean value.

One solution is to create a local variable that will always have a value, even if its source is null:

Code Block
<<var [v_coe = “TBD”]>>

When setting this variable, only allow it to be set to the value from the data source if that value is not null or empty:

Code Block
<<if[!string.IsNullOrEmpty(coWqc.coWqcCoe)]>><<var [v_coe = coWqc.coWqcCoe]>><</if>>

Now, since v_coe will never be null, the null check is no longer necessary:

Code Block
<<if[(v_coe.StartsWith(“M”))]>>Mobile<<elseif[(v_coe.StartsWith(“N”))]>>Nashville<<else>><<[v_coe]>><</if>>

Note that variables are only recognized within a doc template section. If for example you wanted to include this block in the header of the document, you would need to define a new variable for this (e.g., "coe2").

Permit Conditions

Permit Conditions allow for conditional text to be dynamically inserted into permit template documents. For more information, please refer to Permit Conditions.

Additional Methods and Functions

Document template accepts other C# methods which can be used for data manipulation, a list of methods that could possibly be used within a document template can be found here.

Data type restrict the use of some methods and might not work correctly, to check the data type of a field use GetTypeCode() function then use the method available to that data type. Check the available methods for some data type by visiting the links below:

String

Decimals

Double

DateTime

Boolean

On this page

Table of Contents


Related Content