Liquid Reference

by Christina Moore Updated Apr 23, 2020

The Liquid markup language can be leveraged in some very powerful ways to enhance business solution workflows in Onit; we recommend our Crash Course on Liquid as a good primer if you're just getting acquainted with the language, but that article just skims the surface of Liquid's potential.

Tip: As always when using Liquid, remember that the Liquid Editor is your friend!

You can test out most of the scripts detailed below against Records in your own App, provided any custom Fields/values (highlighted in the examples below inred) have been created/substituted for and the script is operating within the context of a Record. (i.e., the Liquid Editor won't be useful when evaluating Liquid operating from a notification context. More on context below.)

A Word on Context

It's important to remember that the availability of variables you want to request a value/s from with Liquid depends on the context in which your Liquid is being evaluated.

For example, if you are using Liquid to populate the initial value of a Field on the Launch Form, you won't be able to access that Record's Field values since the Record hasn't been submitted yet. In other words, the context of the Launch Form before submission has access to a limited set of variables.

On the other hand, if you're using Liquid to run a Field Calculation, you will have access to any of the other Field values set on Record submission since Field Calculations don't run until after a Record has been submitted.

Although not an exhaustive list, below we've detailed most of the variables available for the unique contexts of Launch Forms, Field Calculations, and notifications.

Launch Form Variables

The following variables are accessible from a transaction's Launch Form, (i.e., before the Transaction Initiated Business Rule has fired):

  • current_user: The current user
  • now: The current datetime
  • atom_number: The unique number assigned to each transaction on launch

Field Calculation Variables

The following variables are accessible for Field Calculations:

  • All of the Record's Fields
  • atom_number: The unique number assigned to each Record on launch
  • requester: An array of variables about the requester that submitted the transaction
  • phase: The Phase a Record is currently in
  • phase_id: The number assigned to a Phase based on its sequential order
  • roles: This array includes the Role names and the email addresses of users assigned to those Roles on a given transaction

Notification Variables

In addition to the variables available to Calculated Fields (listed above), the following variables are also accessible for notifications:

  • endorsements: An array of variables about the endorsement status of all assigned Approvers on a transaction
  • recipient: The email address of the notification's recipient
  • corporation: An array of variables about the environment the transaction belongs to
  • app: An array of variables about the app the transaction belongs to
  • view_request_url: Outputs a link to access the transaction the notification was sent from.
  • view_url: Outputs a link to access the transaction the notification was sent from, but does not authenticate the user in

Warning: view_request_url will automatically authenticate the user the email is sent to, and anyone that the email is forwarded to, into the environment. Anyone who gains access through this method will be logged in as the user that the email was originally sent to. It is therefore advisable to use the view_url option instead, as this will not allow users to masquerade as others.

You can also prevent this by navigating to the Administration page, then to Corporation Settings, and then to the Security tab and uncheck the "Do not require login" box

Date and Date Math Filters

Add Business Days

By default, this Liquid expression only excludes Saturdays and Sundays. To configure it to also exclude custom holidays, see our Defining Custom Holidays tutorial.

Adds number of business days to current date Field. Business days exclude weekends and holidays.

{{ date_field | add_business_days: 15 }}

Add Days

Adds number of days to current date Field. Days include weekends and holidays.

{{ date_field | add_days: 15 }}

Add Months

Adds number of months to current date Field.

{{ date_field | add_months: 2 }}

Add Years

Adds number of years to current date Field.

{{ date_field | add_years: 2 }}

Calculate Business Days

By default, this Liquid expression only excludes Saturdays and Sundays. To configure it to also exclude custom holidays, see our Defining Custom Holidays tutorial.

Calculate the number of Business Days between now and a date Field. Business days exclude weekends and holidays. Will output negative numbers for dates in the future.

{{ now | calculate_business_days: date_field }}

Date

Filter to format a date Field.

{{ date_field | date: "format" }}

For example: {{ date_field | date: "%a, %b %d, %y" }} = Mon, Jan 12, 19

For a handy tool on formatting dates see here.

The following are commonly used formats.

Text Result
%a Abbreviated day name (Fri)
%A Full day name (Friday)
%b Abbreviated month name (Jan)
%B Full month name (January)
%d Numerical day of the month (1-31)
%D Date in Month/Day/Year format

Display Date

Displays date of date Field in numerical month/day/year format (e.g., 05/24/19).

{{ date_field | display_date }}

Distance of Time in Words

Calculates distance in time between two date Fields and outputs approximated result in words (e.g., about 17 hours). Will output negative numbers for dates in the future.

{{ date_field_1 | distance_of_time_in_words: date_field_2 }}

{{ now | distance_of_time_in_words: date_field }}

Distance of Time in Words to Now

Calculates distance in time from a date Field to now then outputs approximated result in words (e.g., about 17 hours). Will output negative numbers for dates in the future.

{{ date_field | distance_of_time_in_words_to_now }}

In Time Zone

Converts date and time to date and time in specified time zone. For a list of accepted time zones see here.

{{ now | in_time_zone: 'London' }}
{{ date_field | in_time_zone: 'Sydney' }}

Long

Displays date in Month, Day, Year (e.g., April 18, 2019) format.

{{ date_field | long }}

Long Time

Displays date in Month, Day, Year Time (e.g., April 18, 2018 6:30PM) format.

{{ date_field | long_time }}

Short

Displays date in Day, Month, Year (e.g., 18 Apr 2018) format.

{{ date_field | short }}

Short Time

Displays date in Day, Month, Year Time (e.g., 18 Apr 2018 6:30PM) format.

{{ date_field | short_time }}

Subtract Business Days

By default, this Liquid expression only excludes Saturdays and Sundays. To configure it to also exclude custom holidays, see our Defining Custom Holidays tutorial.

Subtracts number of business days to current date Field. Business days exclude weekends and holidays.

{{ date_field | subtract_business_days: 15 }}

Subtract Date

Subtracts number of days from one date Field to another date Field. Days include weekends and holidays.

{{ date_field_1 | subtract_date: date_field_2 }}

Subtract Days

Subtracts number of days from current date Field. Days include weekends and holidays.

{{ date_field | subtract_days: 15 }}

Subtract Months

Subtract number of months from current date Field.

{{ date_field | subtract_months: 2 }}

Subtract Years

Subtract number of years from current date Field.

{{ date_field | subtract_years: 2 }}

Time Ago in Words

Calculates distance in time from a date Field to now then outputs approximated result in words (e.g., about 17 hours). Will output negative numbers for dates in the future.

{{ date_field | time_ago_in_words }}

To Date

Outputs date in Year-Month-Day (e.g., 2019-05-24) format.

{{ date_field | to_date }}

To Time

Outputs date and time in Year-Month-Day Time (e.g., 2019-05-24 08:49:25 -0500) format.

{{ date_field | to_time }}

Currency Filters

Currency

Displays currency Field in currency formatting (e.g., $39,000).

{{ currency_field | currency }}

The currency used will default to USD with a $ sign. You can set a different currency with an optional parameter. For example, this will hardcode Euros:

{{ currency_field | currency: 'EUR' }}

And you can use the output of a field as your parameter as well:

{{ currency_field | currency: matter_currency }}

Math Filters

Ceil

Rounds the input up to the nearest whole number.

{{ number | ceil }}

Divided By

Divides two numerical inputs. If you divide by an integer, the result will be an integer. If you divide by a float (e.g., 1.23) the result will be a float.

{{ number | divided_by: number }}

Floor

Rounds an input down to the nearest whole number.

{{ number | floor }}

Minus

Subtracts two numerical inputs.

{{ number | minus : number }}

Modulo

Divides two numerical inputs and returns the remainder.

{{ number | modulo: number }}
{{ 12 | modulo: 5 }} = 2

Plus

Adds two numerical inputs together.

{{ number | plus: number }}

Round

Rounds an input to the nearest integer or specified number of decimals.

{{ number | round }}

{{ number | round: number}}
{{ 4.6 | round }} = 5

{{ 4.5612 | round: 2 }} = 4.56

Times

Multiples two numerical inputs together.

{{ number | times: number }}

String Filters

Append

Appends characters to a string.

{{ 'string' | append: 'characters' }}
{{ 'abc' | append: 'def' }} = abcdef

Capitalize

Capitalizes the first word in a string.

{{ 'string' | capitalize }}
{{ 'dog' | capitalize }} = Dog

Downcase

Converts a string to lowercase.

{{ ' string' | downcase }}
{{ 'STRING' | downcase }} = string

Escape HTML

Escapes a string by replacing characters with escape sequences.

{{ text | escape_html }}
{{ "Have you read all of 'Onit Documentation'?" | escape_html }} = Have you read all of 'Onit Documentation'?

Escape Once

Escapes a string without changing existing escaped entities. It doesn't change strings that don't have anything to escape.

{{ text | escape_once }}
{{ "Have you read all of 'Onit Documentation'?" | escape_once }} = Have you read all of 'Onit Documentation'?
{{ "Have you read all of 'Onit Documentation'?" | escape_once }} = Have you read all of 'Onit Documentation'?

Left Pad

Creates a new string by concatenating enough leading pad characters to an original string to achieve a specified total length.

{{ text | left_pad: "specified total length", "padding characters" }}
{{ atom_number | left_pad: 15, "0" }} = 000000000381259
{{ atom_number | left_pad: 15, "abc" }} = abcabcabc381259

Right Pad

Creates an new string by appending enough trailing pad characters to an original string to achieve a specified total length.

{{ text | right_pad: '"specified total length", "padding characters" }}
{{ atom_number | right_pad: 15, "0" }} = 381259000000000
{{ atom_number | right_pad: 15, "abc" }} = 381259abcabcabc

Newline to br

Replaces every newline with an HTML line break (<br>).

{{ string_with_newlines | newline_to_br }}
{% capture string_with_newlines %}
Hello
there
{% endcapture %}
{{ string_with_newlines | newline_to_br }} =

<br />

Hello <br />

there <br />

Prepend

Prepends characters to input.

{{ text | prepend: "characters to prepend" }}
{{ "dog" | prepend: "I want a " }} = I want a dog

Strip Newlines

Removes any line breaks from a string.

{{ text | strip_newlines }}
{% capture string_with_newlines %}
Hello
there
{% endcapture %}
{{ string_with_newlines | strip_newlines }} = 

Hellothere

Truncate

Shortens a string down to the number of characters passed as a parameter. If the number of characters specified is less than the length of the string, an ellipsis (...) is appended to the string and is included in the character count.

{{ string | truncate: "length of truncation" }}
{{ "This Onit Documentation will talk about truncation" | truncate: 26 }} = This Onit Documentation...

Unescape HTML

Escapes a string by replacing characters with escape sequences.

{{ text | unescape_html }}
{{ "Close the &#39;blue&#39; door" | unescape_html }} = Close the 'blue' door

Upcase

Capitalizes all characters in a string.

{{ text | upcase }}
{{ "Onit is great" | upcase }} = ONIT IS GREAT

Create a link to the specified atom. *Can only be used in a notification Action*

{{ 'button text' | atom_link: 'id' }}
{{ 'Click me' | atom_link: atom }}

Creates an HTML button with the provided text and link. The link must be preformed and held in a separate Field before being provided to the button_link filter via the Field name.

{{ "button text" | button_link: "url_field_name" }}

For example, a link is generated in the record_link Field. To create a button for this link use the following Liquid:

{{ "Click me" | button_link: record_link }}

To create a button that will approve a Record use the following Liquid:

{{ 'Approve' | button_link: approve_url }}

Similarly, to create a button that rejects a Record use the following Liquid:

{{ 'Reject' | button_link: reject_url }}

Array Filters

First

Returns the first item of an array.

{{ array.first }}
{% assign onit_array = "record, atom, document" | split: ", " %}
{{ onit_array.first }} = record

Join

Combines the items in an array into a single string using the input as a separator.  

{{ array | join: "separator" }}
{% assign onit_array = "record, atom, document" | split: ", " %}
{{ onit_array | join: "and" }} = record and atom and document

Last

Returns the last item of an array.

{{ array.last }}
{% assign onit_array = "record, atom, document" | split: ", " %}
{{ onit_array.last }} = document

Map

Creates an array of values by extracting the values of a named property from another object.

{ % assign [my_variable] = [object] | map: [property in object] }}
{% assign m_forcast = matter_vendor_forecasts | map: "p_year" %}
{% for year in m_forcast %}
{{ year }}
{% endfor %} =

2015

2016

2017

Parse JSON

Parses provided JSON. Useful in interpreting a changes hash.

{{ [json] | parse_json }}
{% assign watched_field_names = "matter-settlement_value_matter_currency,matter-proposed_settlement_matter_currency" | split: "," %} 
{% assign x = changes_hash | parse_json %} 
{% assign result = false %} 
{% for change in x %}   
{% assign changed_field_name = change.first %}   
{% if watched_field_names contains changed_field_name%}      
{% assign result = true %}      
{% break %}   
{% endif %} 
{% endfor %} 
{{result}}

Reverse

Reverses the order of the items in an array. Reverse cannot reverse a string.

{{ array | reverse | join: "," }}
{% assign onit_array = "record, atom, document" | split: "," %}
{{ onit_array | reverse | join: "," }} = document, atom, record

Size

Returns the number of characters in a string or the number of items in an array.

{{ text | size }}
{% assign onit_array = "record, atom, document" | split: ", " %}
{{ onit_array.size }} = 3

Slice

Returns a substring of 1 character beginning at the index specified by the argument passed in. An optional second argument specifies the length of the substring to be returned.

{{ text | slice: "index" }}
{{ "Onit" | slice: 2 }} = i

Sort

Sorts items in an array by a property of an item in the array. The order of the sorted array is case-sensitive.

{{ text | sort | join: "," }}
{% assign onit_array = "record, atom, document" | split: ", " %}
{{ onit_array | sort | join: ", " }} = atom, document, record

Split

Divides an input string into an array using the argument as a separator.

{{ text | split: "separator" }}
{% assign onit_array = "record, atom, document" | split: "," %}

{% for item in onit_array %}
{{ item }}
{% endfor %} =

record atom document

To JSON

Transforms text to JSON.

{{ [text] | to_json }}
{% assign to_json = "{" %}   
{% for field in fields %}   
{% assign field_name = field[0] %}   
{% assign field_value = atom[field_name] | replace: '"', "'" %}   
{% unless field_value contains "Settings" or field_value contains "Preferences" or field_name == 'settings_json' %}   
{% assign to_json = to_json | append: ',"' | append: field_name | append: '" : {"value":"' | append: field_value | append: '"}' %}   
{% endunless %}   
{% endfor %}   
{% assign to_json =to_json | append: "}" %}  
{{to_json | replace_first: ",", "" }}

Uniq

Removes any duplicate elements in an array.

{{ my_array | uniq | join: "," }}
{% assign onit_array = "record, atom, document, atom" | split: "," %}
{{ onit_array | uniq | join: "," }} = 

record, atom, document

URL Encode

Converts any URL-unsafe characters in a string into percent-encoded characters.

{{ text | url_encode }}
{{ "john@onit.com" | url_encode }} = john%40onit.com

Onit Filters

Activity Log

This code places an already formatted view of the activity log into an email.

{% activity_log%}

If you want to limit the number of entries, include a number

{% activity_log 3%}

Anonymous Attachment URL

This Liquid will generate an anonymous URL that will let anyone download the contents of an attachment Field.

Parameters: the field name, the expiration period. The expiration period is expressed in days. The default is 45 days. The parameter accepts a decimal: .5 for 12 hours, .001 for 86 seconds, etc. To prevent expiration enter never instead of an expiration date (e.g., {% anonymous_attachment_url atom, [attachment_field_name], never %} ).

{% capture url %}

{% anonymous_attachment_url atom, [attachment_field_name], [expiration] %}

{% endcapture %}

<a href="{{url}}" download>Anonymous Download Link</a>

Creates an attachment link. The user must be logged into Onit to use this link, it is not anonymous.

{% attachment_link generated_document%}

Combo Display

Access the display value of a combo or MultiSelect Field

{{ atom | combo_display: 'combo_field_name' }}

Combo Value

Access the save value of a combo or MultiSelect Field

{{ atom | combo_value: 'combo_field_name' }}

Create Launch URL

To create anonymous launch with included parameters, use the {% create_launch_url%} tag, along with subtags {% app %} and {% param %}.

{% create_launch_url my_link%}
    {% app 'My App'%}
    {% param name = 'Test Atom'%}
    {% param requester_name = 'Alice'%}
    {% param checkbox = true%}
{% endcreate_launch_url%}

This example constructs a link which is stored in my_link. You can then use my_link in a hyperlink:

<a href = "{{my_link}}">Click Here</a>

Or a button link.

{{ 'Click Here' | button_link: my_link }}

Email to User

Accesses user object with an email

{% assign my_user = 'user_name' | email_to_user %}
{% assign my_user = 'john.gilman@onit.com' | email_to_user %} 
{{my_user.name}} - {{my_user.has_used_password}} =

John Gilman - true

Execute Reaction URL

Create an email button that will trigger an action, and then redirect the user afterwards.

Format as follows:

{{ atom | execute_reaction_url: 'action name', 'redirect type', 'authentication' }}

Redirect Types:

Message: This leaves the user on a blank page that displays the last message given.

Atom: This places the user on the Record detail page (honors suite preferences, if relevant).

Dashboard: This places the user on the App dashboard (honors suite preferences, if relevant).

For example, we have already configured a "Return Message" action and named it "Show me a message". Now we set up a Business Rule that fires a notification action. The notification action includes this:

{% assign button_url = atom | execute_reaction_url: 'Show me a message', 'message' %}
{{ 'Click here' | button_link: button_url}}

When the user receives the notification in their email, they will see the button. When they click on it, they will be taken to a page that is blank, except for the message sent by the "Show me a message" action.

The authentication parameter is not required. If you do set it, there are two options:

  • authenticated_user
  • email_recipient

Authenticated_user: The user must log in before anything else happens. If you leave the parameter out, this is also what happens.

Email_recipient: The action will fire and the user will be redirected to their message without requiring a login.

If you set email_recipient but redirect to atom or dashboard, the user will have to log in before getting redirected, as you might expect. This means a slightly different flow for the two cases:

  • authenticated_user: email button clicked ➙ login ➙ reaction executes ➙ user is placed on the atom
  • email_recipient: email button clicked ➙ reaction executes ➙ login ➙ user is placed on the atom

There are two gotchas here:

  1. If using email_recipient for the authentication, in the Send Notification action, you cannot use "Recipient Roles" as the recipient target of the notification.
  2. If the reaction includes a Return Message action, the message will be returned before the login happens, and in the process of logging the user in and redirecting them, the message gets lost, and the user never sees it.

In User Group

in_user_group allows you to use an email address to determine if the user is a member of a user group. For example, this Liquid

{{ current_user.email | in_user_group: "Private Access" }}

will return true if the current user is a member of the Private Access group, and false if not.

Launch related atom.

{{ 'atom' | launch_related_url: 'related app', 'atom' }}
{{atom | launch_related_url: 'matter_vendors', 'atom'}}

Can only be used in a notification action

List Lookup

Matches and returns value from specified match and output column in list.

{{ [field_from_atom] | list_lookup: '[List Name]', '[column name to match]', '[column name to output]' }}
{{ name | list_lookup: 'T3', 'activity', 'html_instructions' }}

List Lookup Whole Atom

If an atom is part of a Transaction List Provider, you can populate a variable with all of its attributes. For example, let's say you have a TLP that lists your legal entities. In your Matters app, once the legal entity is set, you want to look up its address, phone number, main contact, and so on. Instead of doing 21 different list lookups, you can do one list_lookup_atom:

{% assign entity = legal_entity | list_lookup_atom: 'Legal Entities', 'name' %}

and then output:

{{ entity.address }}
{{ entity.country }}
{{ entity.main_billing_contact }}

... and so on.

Reset Password URL

Filtering the users email with reset_password_url will generate the user's password reset URL. For more information see this tutorial.

{{ name | reset_password_url }}
{% assign url {{ name}} | reset_password_url %} {{ 'Reset Password' | button_link: url }}

User Group for User

user_groups_for_user allows you to output the user’s user group, if any, from the user’s email. For example,

{{ "susan.doe@onit.com" | user_groups_for_user }}

would output: Legal Department

User Preferences for User

Assuming a "User Preferences" App is configured as a User Preferences provider in Advance Builder you can use the filter "user_preferences_for_user" to get any of a user's attributes. You need to pass a user object to the filter, not just an email address, so "current_user" will work. But you can always use "email_to_user" to first get a user object then pass it to the filter.

Use with "current_user"

{% assign my_user = current_user | user_preferences_for_user %} {{my_user.approval_authority}}

Returns "10000"

Use with an email address

{% assign my_user = 'john.gilman@onit.com' | email_to_user | user_preferences_for_user %}
{{ my_user.approval_authority }}

Returns "50000"

Widget Atom Launch

Creates a clickable link that will launch an App without navigating the user away from their dashboard. This only works in the context of a suite portal widget, not an atom portal widget.

{{ 'text' | widget_atom_launch: 'App Name' }}

Creates a link to specified atom. Can be used to render second mover form.

{{ 'text' | widget_atom_link: atom }}

Render full atom view in popup form

{{ 'text' | widget_atom_link: atom }}
{{ task.name | widget_atom_link: task }}

Creates an anchor link that will take the user directly to the launch form in edit mode without rendering the atom view.

{{ 'button text' | wizard_link: atom }}

edit_form can be appended to the end of an atom URL and will render the atom in launch form view.

Wizard URL

Generates a URL to the launch form in edit mode.

{{ atom | wizard_url }}
{% assign my_url = atom | wizard_url %}{{ 'Press Me' | button_link: my_url }}

Working With Participants Liquid References

Display One Participant with a Specific Role

{% assign displayemail = "" %}
{% for endorsement in endorsements %}
{% if endorsement.role == "Attorney"%}
{% if displayemail == "" %}
{{ endorsement.user.email }}
{% assign displayemail = endorsement.user.email %}
{% endif %}
{% endif %}
{% endfor %}

Display How Many People are in a Specific Role

{% for endorsement in endorsements %}
{% if endorsement.role == "Attorney" %}
{% assign count = count | plus: 1 %}
{% endif %}
{% endfor %}

Display All Current Approvers with Status

{% for endorsement in endorsements %}
{% if endorsement.requires_action and endorsement.active %}
{{ endorsement.user.email }} - {{ endorsement.status }}
{% endif %}
{% endfor %}

Display Approvers Still Pending

{% for endorsement in endorsements %}
{% if endorsement.requires_action and endorsement.active and endorsement.status == 'Pending' %}
{{ endorsement.user.email }}
{% endif %}
{% endfor %}

Return the Role and Name of Every Participant on a Record

{% assign all_participants = ''%}
{% for role in roles%}
{% assign participants_in_role = ''%}
{% for participant in role[1]%}
{% assign participants_in_role = participants_in_role | append: participant | append: "; "%}
{% endfor %}
{% assign size = participants_in_role | size | minus: 2 %}
{% assign participants_in_role = participants_in_role | slice: 0, size %}
{% assign all_participants = all_participants | append: '"' | append: role[0] | append: '" Participant(s): ' | append: participants_in_role | append: ". "%}
{% endfor %}
{% assign size = all_participants | size | minus: 1 %}
{{ all_participants | slice: 0, size }}

Hide a Button From All Users Except Those in a Certain Role

{% assign hideButton = true %}
{% for e in endorsements %}
{% if e.role == "Requester Approval" and e.email == current_user.email %}
{% assign hideButton = false%}
{% break %}
{% endif %}
{% endfor %}
{{hideButton}}

Date Calculations Liquid References

Output the number of days between two DateTime Fields

{% assign started_sec = phase_started | date: "%s"%}
{% assign ended_sec = phase_ended | date: "%s"%}
{% assign total_elapsed_seconds = ended_sec | minus: started_sec%}
{% assign days_elapsed_int = total_elapsed_seconds | divided_by: 86400%}
{% assign days_elapsed_mod = total_elapsed_seconds | modulo: 86400%}
{% assign hours_elapsed_int = days_elapsed_mod | divided_by: 3600%}
{% assign hours_elapsed_mod = days_elapsed_mod | modulo: 3600%}
{% assign minutes_elapsed_int = hours_elapsed_mod | divided_by: 60%}
{% assign minutes_elapsed_mod = hours_elapsed_mod | modulo: 60%}
{{days_elapsed_int}} Days, {{hours_elapsed_int}} Hours, {{minutes_elapsed_int}} Minutes

*Where phase_started and phase_ended represent the custom DateTime Field names whose values should be used in the calculation.

Output the number of elapsed business days between two DateTime Fields

Only works if your environment has Holiday Provider configured and running.

{% assign start = phase_started | date: '%s' %}
{% assign end = phase_ended | date: '%s' %}
{% assign days = end | minus: start %}
{% assign leftover = days | modulo: 86400 %}
{% assign days = days | minus: leftover %}
{% assign days = days | divided_by: 86400 %}
{% assign first_day = phase_started | date: '%u' %}
{% assign last_day = phase_ended | date: '%u' %}
{% assign diff = first_day | minus: last_day %}
{% if first_day > last_day %}
{% assign days_to_subtract = 7 | minus: diff %}
{% else %}
{% assign days_to_subtract = diff | times: -1 %}
{% endif %}
{% assign days = days | minus: days_to_subtract | plus:1 | round %}
{% assign weeks = days | divided_by: 7 %}
{% assign business_days = weeks | times: 5 %}
{% if last_day > first_day %}
{% assign last_minus_days = last_day | minus: days_to_subtract %}
{% if last_minus_days > 6 %}
{% assign business_days = business_days | plus: days_to_subtract | minus: 1 %}
{% else %}
{% assign business_days = business_days | plus: days_to_subtract %}
{% endif %}
{% else %}
{% if days_to_subtract != 0 %}
{% assign days_greater= days_to_subtract | minus: last_day %}
{% assign days_to_subtract = days_to_subtract | minus: days_greater %}
{% assign business_days = business_days | plus: days_to_subtract %}
{% endif %}
{% endif %}
{% if leftover > 0 %}
{% assign business_days = business_days | plus: 1 %}
{% endif %}
{{business_days}}

*Where phase_started and phase_ended represent the custom DateTime Field names whose values should be used in the calculation.

Working with Fields Liquid References

Determine if a Field is either blank or null

For a Text Field:{% if matter_name == blank %}true{% endif %}

For a Date Field:{% if date_field == blank %}true{% endif %}

MultiCurrency Values

Get international currency code: {{ currency_field.currency }}

Get MultiCurrency Value: {{ currency_field.amount }}

Get MultiCurrency Value in subunits (e.g., cents): {{ currency_field.cents }}

Copy MultiCurrency Values

Suppose you have two apps, App 1 and App 2, and both Apps are related (parent-child for example). You want to copy over a multi-currency field from App 1 to App 2 using an 'Update Related Transaction' Action. Here is how we configure the params liquid property of the action:

p_mcf_app_2:{{mcf_app_1.amount}} {{mcf_app_1.currency}}

Note: mcf stand for Multi-Currency Field, and of course you need one multi-currency field in each app.

Update Attachment Field with a Document from a DocumentFolder Field

Suppose we have an App, that App has an attachment Field and a DocumentFolder Field. We want to trigger and Action that will set/update the content of the attachment field to the first document in the DocumentFolder field. Here is how we do it:

  • Create an Update Transaction Action, and in the Params Liquid Filed use this:
p_name_of_the_attachment_field: {{atom.documents[0]._id}}
  • Now we can create a button or business rule so we can attach the above Update Transaction action

Import Textarea Field into a Word Document without losing line breaks

When pulling data from a Textarea Field using a Generate Document Action Word will take the formatting out of the Textarea Field. This Liquid will look for line breaks and insert a split.

{% assign splits = '{ "key": "\r\n"}' | parse_json %}
{% assign lines = textarea_field | split: splits.key%}
{% for line in lines %}
{{line }}
{% endfor %}

Put more detail about changes into the history log

By default, the history in each transaction just says "[user] edited the [app name] Request Form." For more detail, create an "Add History" action, with this as the Message:

{{current_user.name}} updated the following attributes: 
{% for change in atom.changed_values %} 
{% unless change.field_name == 'updated_at' or change.display_name == blank %} 
{%unless change.previous == blank and change.current == blank%} 
{{ change.display_name }} ({{change.field_name}}) : {{ change.previous }} > {{change.current}} <br> 
{% endunless %}
{% endunless %}
{% endfor %}

Note: The atom.changed_values array changes between each execution of any Business Rule even if the Record has not been updated between calls. When hanging logic off an atom.changed_values array you must reference the first instance of the array directly after the Record updates.

For example, a Record is updated and a Transaction Phase Change Business Rule fires to send a notification,then a Transaction Updated Business Rule fires to check the atom.changed_values array for specific changes. The Transaction Updated Business Rule will not return the correct results because the atom.changed_values array has been mutated between the two calls, even though the Record was not updated twice. If the atom.changed_values array must be referenced after another Business Rule fires you should park the returned array in a hidden Field, then reference the Field.

Iterate/Loop through all documents associated with a Record

Suppose we have a record, and that record has a field of type DocumentFolder that holds a collection of documents. What we want is to iterate over that collection and extract information from each one of those records. So, basically what we have to do is iterate over the documents property of the atom object, like this:

{% for doc in atom.documents%}
{% if doc.tags contains "doctag"%}
<a href="https://environment.onit.com/rest/documents/{{doc.id}}/download" download>{{doc.name}}</a><br>
{% endif%}
{% endfor%}

In this case we are creating an html <a> tag per document that would allow us to download the corresponding document upon clicking the link. Notice as well use of"doctag"which is basically the name of the DocumentFolder field.

Daily Report List

  1. This code generates a list of the transactions included in the daily digest report.
{% if atoms.size!= 0%}
<p>Here is a list of matters that need accrual estimates:</p>
{% for atom in atoms%}
<p>{{ atom.matter_name }}</p>
{% endfor%}
{% endif%}
  1. This code sorts the atoms by a specific field.
{% if atoms.size!= 0%}
{% assign new_atoms = atoms | sort: "expiration_date"%}
{% for atom in new_atoms%}
<a href="https://avery.onit.com/adhoc_approval/atoms/{{atom.id}}/">{{ atom.name }}</a><br>
{% endfor%}
{% endif %}

Get Email Attachment IDs

This Liquid will get the attachment IDs of documents sent to a Record via email.

{% assign mail_id = atom.emails.last.id %}
{% for doc in documents %}
{% if doc.attachment_owner_id == mail_id %}
{{ doc.id }}
{% endif %}
{% endfor }

Project Emails

Approve email :{{email_address.account}}.approve@{{email_address.subdomain}}.app.onit.com

Reject email: {{email_address.account}}.reject@{{email_address.subdomain}}.app.onit.com

Execute an Action from an Email Button

Note: You can only use this filter in emails.

You can use the filter execute_reaction_url to create an email button that will trigger an action, and then redirect the user afterwards. The filter format looks like this:

{{ atom | execute_reaction_url: 'action name', 'redirect type', 'authentication' }}

Reply To Email

You may have seen buttons in Onit notifications before in your inbox, like a View Request button that takes you directly to a specific Record, but did you know that you can create a button that will open a new email for you to send, with the To: line already filled out? 
Here’s how: First, we’ll create a mailto URL using an assign operator: 
{% assign req_url = 'mailto:' | append: requester_email %} 
You could use any Field where you are storing an email address, or you could loop through an object like endorsements to grab the particular one you want. Then, all you have to do is provide this variable to the button_link Liquid Filter: 
{{ 'Email Requester' | button_link: req_url }} 
And you’ll get a shiny new reply button in your email! Super simple!
Previous Article Using Badges to Enhance App Orchestration Visibility and Workflow
Next Article Onit Actions Reference

© 2020 Onit, Inc.

docs.onit.com contains proprietary and confidential information owned by Onit, Inc. that is subject to copyright. Onit presents it exclusively to you for your sole use in conjunction with using Onit products. No portion of the materials contained herein may be used for any other purpose. No portion of the materials contained herein may be shared with third parties or reproduced in any form.