Examples of Using QLingo

QLingo is a flexible scripting language used in uPlan, uCreate, and Circle to create dynamic, personalized content based on recipient data.

This topic provides practical examples - such as string manipulation, date formatting, barcode generation, and multilingual logic - that demonstrate how to work with recipient data using QLingo expressions.

You can copy and paste the example code below into uPlan, uCreate’s Rule Editor View (QLingo), or Circle’s Plan Object Editor, and then modify it as needed.

Notes:

  • Use // for single-line or end-of-line comments, and /* ... */ for multi-line comments. Comments are supported only in uPlan.

  • Since QLingo editors support copy/paste from any text editor, you can maintain your own code snippet library in a plain text file for easy reuse.

  • Be cautious when copying code from formatted sources - smart quotes (curly quotation marks) may replace standard quotes, which can cause syntax errors in QLingo.

The examples below assume a recipient (primary) data source with the following schema:

Field

Description / Example Value

FNAME

First name (e.g., John, Stacy, Suzi)

INITIAL

Middle initial (e.g., S, G, [empty], Jesse)

LNAME

Last name (e.g., Smith, Brown, Green)

BARCODE

USPS barcode digits (e.g., 123456789012345678901234508077)

FULLNAME

Full name string (e.g., Mr. and Mrs. Montgomery M. Montgomery or Mr. Montgomery M. Montgomery and Ms. Penelope Washington

MYDATE

Date field (e.g., 7/4/2025 or 4/7/2025 depending on operating system setup)

PREFLANG

Preferred language (e.g., EN for English, SP for Spanish, FR for French)

Build a Full Name using concatenation

A simple way to display a full name is to place the three ADORs (FNAME, INITIAL, and LNAME) next to each other in the design. Then, enable the “Suppress Trailing Spaces on Empty Objects” option. This hides any extra spaces left by an empty middle initial.

However, in some circumstances having a single Full Name field is handy. The schema includes a Full Name but if it is left empty, it is possible to use this code in a plan variable or ADOR.

The following is an example of using concatenation in QLingo to build a full name:

Copy
if (Trim(|->[INITIAL]) = "")
/* comment: if the initial field is empty, concatenate first name, space, last name, while a + (plus sign works, it is best to use to ampersands for concatenation */ 
|->[FNAME] & " " & |->[LNAME]
else
/* Concatenate first name, space, FIRST CHARACTER OF INITIAL (in case there is more than one character), a period followed by a space, and last name */
|->[FNAME] & " " & SubString(|->[INITIAL], 0, 1) & ". " & |->[LNAME]

Add a line break at "and" in a long Full Name

In some designs, a person's full name is stored in a single field (FullName), rather than being split into First, Middle, and Last Name fields. This can result in overly long text.

While the design may wrap text at spaces or punctuation marks by default, it is preferred to insert a line break at the word "and", but only if the name is long enough to require it.

The following code checks whether the Full Name contains 50 or more characters. If it does, it searches for the word " and " and replaces it with "\nand" to force a line break before "and." If the name is shorter, it is displayed as-is.

Copy
If(Length(|->[FullName]) => 50) // if the full name field is 50 or more characters
{ // if yes/true: look for "and" then replace it with itself proceeded by line break 
FindAndReplace(|->[FULLNAME], "  and ", "\nand") // \n is a new line or soft return, \r is a paragraph break

else
{ // if no/false: then leave the field value as is 
|->[FULLNAME]
}

Convert a USPS postal zip code digits to a barcode

To generate a USPS Intelligent Mail barcode from a ZIP code, use the XMPBarcode function. This function requires the input value to be exactly 25, 29, or 31 digits long.

Change the Barcode ADOR to a Graphic ADOR, and then place the Graphic ADOR inside a graphic frame with no fitting methods, and preferably anchor it to the upper-left corner of the box.

The barcode will be drawn directly on the document.

Copy
XMPBarcode("USPSIntelligentMail", |->[BARCODE], "")

Season calculation

This example shows how to determine the season (for the Northern Hemisphere) based on the month of a given date.

  • Winter: December, January, February

  • Spring: March, April, May

  • Summer: June, July, August

  • Autumn: September, October, November

Define a variable called MyMonth to extract the month from a date field (e.g., MYDATE). You can use either of the following methods:

Copy
// Option 1: FormatDate returns a string, so convert it to a number
AsNumber(FormatDate(|->[MYDATE], "M"))

// Option 2: GetMonth returns a number directly (recommended)
GetMonth(|->[MYDATE])

If MYDATE is not already a date field, wrap it with AsDate():

Copy
GetMonth(AsDate(|->[MYDATE]))

Now, define a Text ADOR called Season using the following logic:

Copy
If(@{MyMonth} < 3 or @{MyMonth} = 12) // check if month is 1, 2 or 12
{ // if yes, say Winter
"It is Winter"
} // the not, then check less than 6 
Else If(@{MyMonth} < 6) 
{ // if 3, 4 or 5, say Spring
"It is Spring"
} // if not, then check less than 9
Else If(@{MyMonth} < 9) 
{ // if yes, say Summer
"It is Summer"
} // if not, it must be Autumn
Else 
{
"It is Autumn"
}

This logic uses MyMonth to determine the numeric month, and assigns the appropriate season based on the month range.

Season calculation with language support

This example expands on the basic season logic by adding multilingual support based on the recipient’s preferred language (PREFLANG). The logic uses GetMonth to determine the month and a combination of If and Switch statements to return the season in English, Spanish, or French.

Create a variable called MyMonth to extract the numeric month from the MYDATE field:

Copy
GetMonth(AsDate(|->[MYDATE]))

Next, create a Text ADOR called Season and use the following logic:

Copy
If(@{MyMonth} < 3 OR @{MyMonth} = 12) { // Winter
  Switch(UCase(|->[PREFLANG])) {
    CASE "EN": "It is Winter"
    CASE "SP": "Es invierno"
    CASE "FR": "C'est l'hiver"
    DEFAULT: "It is Winter"
  }
}
Else If(@{MyMonth} < 6) { // Spring
  Switch(UCase(|->[PREFLANG])) {
    CASE "EN": "It is Spring"
    CASE "SP": "Es primavera"
    CASE "FR": "C'est le printemps"
    DEFAULT: "It is Spring"
  }
}
Else If(@{MyMonth} < 9) { // Summer
  Switch(UCase(|->[PREFLANG])) {
    CASE "EN": "It is Summer"
    CASE "SP": "Es verano"
    CASE "FR": "C'est l'été"
    DEFAULT: "It is Summer"
  }
}
Else { // Autumn
  Switch(UCase(|->[PREFLANG])) {
    CASE "EN": "It is Autumn"
    CASE "SP": "Es otoño"
    CASE "FR": "C'est l'automne"
    DEFAULT: "It is Autumn"
  }
}

UCase() ensures the language code is compared in uppercase.

DEFAULT ensures a fallback to English if the language is unrecognized.