Liquid Template language use in NERM

Throughout parts of our documentation and application, we note that the Liquid Template language is able to be used to dynamically show data values - but we do not have the best documentation around how to use it within NERM. This post is to help fill that purpose but will not be exhaustive. I encourage you to make your own posts or comment on this one with your use cases for Liquid!

To start, current documentation:

  • You can some of the basic syntax for using Liquid within NERM under Admin > Templates > Notifications > Select a notification and you can see some of the available Liquid syntax on the right side.
  • Liquids documentation can be found here: Liquid template language (shopify.github.io). The specific top-level keys used here may not be the same for NERM (IE: product.name or customer.id serve no purpose) but NERM is able to utilize all of the available tags, filters, and control flow syntax shown in these docs.
  • Not documentation, but a pretty good playground for testing logic: Run liquid code now (geekplayers.com) . You won’t be able to use the specific NERM syntax, but all other tags and filters appear to work nicely.

Where can Liquid be used

Liquid in NERM can currently be used in three spots:

  • Pages
  • Notifications
  • API Actions

What is available in Liquid for NERM:

There are a few different “top-level” objects available, with their respective available values:

  • attribute
    • using the top-level attribute key will pull data from the Profile first (if available) and then the Request
  • api_tokens
    • name - label of the token
    • token - actual token value: ‘1234abcd’
  • base_url - https://tenant.nonemployee.com/
  • comments
    • comment - the comment value
    • commenter - the name of the User who left the comment
  • profile / any profile type attribute
    • id
    • uid
    • name
    • status
    • [attribute_uids] - ex: profile.first_name
  • request
    • id
    • created_at
    • current_action - returns the Label of the Action. ex: RequestAction
    • status
    • comments (see above)
  • requester / approver / any user type attribute
    • id
    • name
    • managers - returns a user object
    • avatar - returns the URL of the image used for the users avatar
    • email
    • title
    • login
  • workflow
    • name - configured label of the workflow

This keys, or objects, are able to access the others, if they are available. For example, Workflow Sessions (Requests) contain the context for attribute values that may contain Profile or User objects. Those can be accessed from the Request like {{attribute.profile_select.first.name}}

Generic Syntax

Objects and variables in Liquid use the double curly braces {{ }} to display values.

To use logic and iteration, you use “curly brace percentage delimiters”: {% %}. These will not output anything to the screen.

When using tags for iteration or control flows, you must end the tag like:

{% if condition %}
{% endif %}

Objects like users, profiles, requests, etc. are actually array-type objects and can be iterated through to get to their components. Consider these to follow the same sort of syntax of their JSON counterparts. For example, Profile JSON looks like:

{
    "profiles": [
        {
            "id": "d5e050d2-c011-4788-ae7f-b8bfd1aea991",
            "uid": "d46367fd30cf4ea29097770cb1f0c115",
            "name": "Profile One",
            "profile_type_id": "bcc54856-7d6a-11ec-b7b3-0a97532da8af",
            "status": "Active",
            "updated_at": "2024-07-11T20:26:47.706-04:00",
            "created_at": "2024-07-11T20:26:47.739-04:00"
        },
        {
            "id": "bb8d34f0-0b7c-4699-8c6b-115afaed07ea",
            "uid": "446e9eafc7184a46bb1c12d4b68cf7e4",
            "name": "Profile Two",
            "profile_type_id": "bcc54856-7d6a-11ec-b7b3-0a97532da8af",
            "status": "Active",
            "updated_at": "2024-07-11T20:26:46.399-04:00",
            "created_at": "2024-07-11T20:26:46.409-04:00"
        }
    ]
}

Somewhat intuitively, you can see where the liquid syntax comes from. If you want to get the ID of the second profile above you would do (pseudo code): from the profiles, select the second one and return the ID.

Actual Liquid would look like: {{profile.[1].id}}.

Filters for displaying objects are used inline of object curly braces, separated by pipes: {{ object | filter1 | filter2 | filter3 }}. For example, if you want to downcase values and remove whitespace you would do {{attribute.attribute_uid | downcase | strip }}

Looping / Iteration

There are a few different Iteration options available for Liquid, but the most commonly used would be a For loop. You can loop for a given range or easily loop through an entire array. Basic syntax is:

Range:
{% for i in (0..10) %}
  {{ i }}
{% endfor %}

Array:
{% for variable in array %}
  {{ variable }}
{% endfor %}

Example 1: Lets say you are in a workflow session and want to display all of the comments in a table. You could use the below syntax

{% for com in request.comments%}
  {{ com.comment }}   |   {{ com.commenter }}<br>
{% endfor %}

image

You do not have to use a loop to get to a value though. You can use tags like first and last or just by using numbered elements [0]. So, you can select a specific object from a Profile or Request array, or even nest further into the selected objects values:

{{ attribute.assignment_person.[0].id }}
{{ attribute.assignment_department.first.population.first.id }}

Variables

As you get into more complex uses of Liquid in NERM, you might find it hard to read due to long attribute uids or multiple nests. Using variables may help on cutting down on arduous labels.
Example, Display an Assignment’s Sponsors data on a Notification from the Person profile:

Original syntax:
{{ profile.person_assignment.first.sponsor.first.id }}
{{ profile.person_assignment.first.sponsor.first.name }}
{{ profile.person_assignment.first.sponsor.first.email }}
{{ profile.person_assignment.first.sponsor.first.title }}

Variable:
{% assign sponsor = profile.person_assignment.first.sponsor.first %}
{{ sponsor.id }}
{{ sponsor.name }}
{{ sponsor.email }}
{{ sponsor.title }}

Liquid blocks

The Liquid tag allows you to enclose multiple of tags and operations within one set of delimiters to allow for more concise logic blocks
Example, displaying a colored banner on a Profile page based on the value of a drop-down:

Original Syntax:
{% case profile.dropdown %}
{% when 'One' %}
  {% assign display = true %}
  {% assign color = 'green' %}
{% when 'Two' %}
  {% assign display = true %}
  {% assign color = 'yellow' %}
{% when 'Three' %}
 {%  assign display = true %}
 {%  assign color = 'red' %}
{% else %}
 {%  assign display = false %}
{%  endcase %}
{%if display %}<p style="background-color:{{color}};">The dropdown is {{profile.dropdown}}</p>{% endif %}

Liquid tag:
{% liquid
case profile.dropdown
when 'One'
  assign display = true
  assign color = 'green'
when 'Two'
  assign display = true
  assign color = 'yellow'
when 'Three'
  assign display = true
  assign color = 'red'
else
  assign display = false
endcase %}
{%if display %}<p style="background-color:{{color}};">The dropdown is {{profile.dropdown}}</p>{% endif %}

Liquid versioning

We are currently on version 5.4.0 of Liquid

Thanks for reding this post! Its somewhat of a re-type of some of my scribblings in sublime text, so I will be reviewing and adding data to this over time… But, please, comment and ask any questions or make your own posts about Liquid!

3 Likes