Extensions to Jelly syntax
-
- UpdatedAug 1, 2024
- 8 minutes to read
- Xanadu
- Building applications
Apache's Jelly syntax is used to render forms, lists, UI pages, and many other things rendered in ServiceNow.
With Jelly, logic can be embedded within static content and computed values may be inserted into the static content.
This page from Apache has a summary of the standard Jelly tags: http://commons.apache.org/jelly/tags.html
Namespaces
Jelly often includes multiple namespaces when invoking tags.
The "j" namespaces are standard Jelly whereas the "g" namespaces are unique to ServiceNow scripts. For example, the <g:evaluate> tag is supplied by ServiceNow to allow you to compute a value using JavaScript. The standard Jelly tag <j:test> is used to evaluate a condition.
Phases
Usually, there are two phases indicated by namespaces <j> versus <j2> and <g> versus <g2>.
The namespaces without the "2" happen in the first phase of processing and these are cached except when used in a UI page. Those with the "2" are never cached. Care must be taken when selecting whether to use phase 1 or phase 2 for efficiency and correct results.
In addition to the namespaces, the syntax used to insert values into static content differs
depending on which phase is to supply the value. A dollar with braces surrounding a value
inserts the value in phase 1. For example, ${jvar_ref}
inserts the value
jvar_ref
during phase 1 of the jelly process. A dollar with brackets
surrounding a value inserts the value in phase 2. For example, $[jvar_ref]
inserts the value jvar_ref
during phase 2. A value surrounded by quotes is
treated as a string. For example, '[jvar_ref]'
inserts the value
jvar_ref
as a string during phase 2.
If tests
You can use if statements in Jelly scripts.
Testing whether something is true or not can be done as follows:
- it is Boolean and true
- it is a String and = "true", "yes", "on", or "1"
Testing whether something exists can be done as follows:
- null
- an empty string
- a zero length collection
- a map with no keys
- an empty array
Set_If
Sets a variable to one of two different values depending on whether a test is true or false.
<g:insert> versus <g:inline> versus <g:call>
This page provides a comparative explanation of three tags: <g:insert>, <g:inline>, and <g:call>.
<g:insert>
The <g:insert> tag inserts a Jelly file into your Jelly in a new context. This means you cannot access the variables previously established in your Jelly.
<g:inline>
The <g:inline> tag inserts a Jelly file into your Jelly in the same context. This means that the inserted Jelly can access the variables you previously established and it can change the values of those variables.
<g:call>
For better encapsulation, the <g:call> tag may be used. Your function will only have access to the values passed to it. The Jelly context will look the same after a call as before the call. This means you cannot set a global variable here and read it later. This also means you can't mistakenly set a global variable called "jvar_temp" and overwrite a variable that somebody else was relying on.
Passing values, if needed, is done explicitly by including the name of the parameter on the <g:call> line followed by the equal sign followed by the value in quotes:
If values are passed, and you want to have defaults or required parameters, your Jelly referenced in the function must then include a line to declare whether the parameters are required or have a default value:
The example above indicates that 3 of the parameter are required and one parameter is option with a blank default value. Note that if you are not passing values or if you do want to have default or required values, you do not need to include the <g:function> line at all. In general, however, you will want to include a <g:function> line.
The value can then be referenced in your template by prepending the "jvar_" prefix to the parameter's name:
For <g:call>, parameters may also be pass implicitly as a list of named variables in an "arguments" parameter:
As an alternative to passing variables into the function via separate tag arguments, it is possible to pass a list of variables in a single 'arguments' argument. All variables identified by name (comma separated) in the argument parameter are re-introduced within the function under the exact same name (e.g. inside the function template, we'd have variables sysparm_view, ref_parent, and jvar_target_text available to us).
The function template may return a value to the calling template using the
return=
attribute. Within the function the jvar_answer
variable sets the return value.
<g:evaluate>
The <g:evaluate> tag is used to evaluate an expression written in Rhino JavaScript and sometimes to set a variable to the value of the expression.
The last statement in the expression is the value the variable will contain.
object="true"
If you would like to have the evaluate return an object (for example an array), use the argument object="true".
jelly="true"
If you would like to access Jelly variables inside an evaluate, include jelly="true" in the evaulate and add "jelly." before the Jelly variable's name. For example, to access the GlideJellyContext:
Another example of accessing a jvar using the jelly="true" parameter. The value of
jvar_h
was set previously and we can access it inside the
evaluate
:
copyToPhase2="true"
If you have a need to take the results of an evaluation that occurs in phase 1 and propagate it to phase 2, use copyToPhase2="true". There is some protection for escaping in this use. For example:
If you do not need to evaluate something, you can do this more directly. Beware of escaping issues here (double quotes in jvar_rows would cause a problem in the example):
<g:breakpoint/>
This tag can be used to display the current Jelly variables and their values in the log.
Be sure to remove this tag before going to production.
<g:ui_form/>
This tag defines a form on the UI page.
For example, if your form contained the application_sys_id
field, the g:ui_form might benefit from a processing script.
For more information, see UI macros.
<g:ui_input_field />
This tag adds a reference to a UI macro that creates an input field on a page that allows users to input information. The ui_input_field
passes a label, name, value, and size into the UI macro.
For more information, see UI macros.
<g:ui_checkbox/>
This tag puts a user-editable check mark on a page. The name and value are passed into the UI macro.
Here is an example from a table on a UI page:
For more information, see UI macros.
<g:dialog_buttons_ok_cancel/>
This tag puts buttons on the UI page that run a specified processing script if the tag returns true.
If your UI page contains a form (uses the <g:form> tag), you can submit the form and have the Processing Script run. The Processing Script can naturally access fields on the form. For example, if your form contained the application_sys_id field:
<g:ui_reference/>
This tag adds a reference to a page that can be referenced by a Processing Script.
The following example creates a reference defined by name, ID, and table parameters in the tag:
Then in the Processing Script, reference the name field like this:
Ampersand
Ampersands in Jelly can cause you grief because Jelly is XML.
Use ${AMP} to insert an ampersand in Jelly. If you are writing JavaScript that appears in the HTML part of say a UI page or UI macro that is actually going to run on the browser you are better off putting this code in the "client script" field and that way you can avoid escaping issues. However, if you really must put it in the "HTML" field, you will need to do something like this:
And
Use ${AND} to insert a JavaScript and in Jelly.
For example:
Alternately, in a Jelly test you would use &&. For example:
Less than
Similar to ampersands, less than ("<") signs can also cause problems due to Jelly being XML. This can be resolved by reversing your test such that it is not necessary or by using ${AMP}lt; in place of the less than sign.
Many times you can avoid the "less than" operator all together by just using "not equals" which doesn't have escaping issues. For example:
Whitespace
Normally, white space is removed by Jelly. To keep it, you must specify that it not be trimmed.
For example, the following keeps the space after the colon.
Spaces
To encode a non-breaking space ( ), you can use $[SP].
For example:
Tracing Jelly
ServiceNow has a feature that allows the evaluation of Jelly to be traced.
The trace is sent to the log. This should only be turned on during debugging as this produces a lot of logging. To turn on the trace, set the property glide.ui.template.trace to true. For example, the following script can be executed to do this:
If you want to see your log entries on your web browser at the bottom of each page, navigate to
.