Article Embedded Script Interoperability

When executing a scripted customization, the widget, theme, or automation can execute embedded Velocity (.vm) and Server-side Javascript (.jsm) files. These embedded executable scripts can share variables and more but are governed by a few rules.

Basic Execution

When a script executes an embedded script using core_v2_widget.Execute('FILENAME'), the following contextual data is available to the executed embedded file:

Local variables

In Velocity, local variables are every variable that's been set using the #set() or #store() directive. In Server-side Javascript, every variable defined on the object represented by this on the outermost execution context of the script is considered local for interoperability.

When executing an embedded Server-side JavaScript script from a Velocity script, a variable named $myValue will be accessible within the Server-side Javascript as this.myValue. Note that the $ prefix is removed and the variable is available on this

When executing an embedded Velocity script from a Server-side JavaScript script, a variable this.myValue (the myValue variable defined on the outermost execution context, this) will be available as $myValue in the Velocity script.

Local values can be edited in the sub-script and the new values will be reflected in the parent script. See "Changing Execution Parameters" below for a rule that affects changes being propagated back up to the calling script.

Execution state

The execution state of sub-scripts executed via core_v2_widget.ExecuteFile('FILENAME') is preserved when the sub-script is executed. Values such as the contextual user, contextual APIs such as context_v2_automationTrigger (for Automations), and URL page state information (core_v2_page.QueryString, etc) are still accessible.

Returning Complex Objects

When returning a result from a Server-side Javascript embedded file executed with core_v2_widget.ExecuteFile('FILENAME'), a complex object can be returned, for example, 

var count = 0;

return {
    name: 'Bob McBobberson',
    next: function() {
        count++;
        return count;
    },
    add: function(a, b) {
        return a + b;
    }
};

This script will return a complex object including a basic value (name), a function that references a contextual variable (next()), and a function that takes input and performs an operation (add(a, b)). The script receiving this object can interact with it, basically creating a custom scripting API. Interaction with complex objects is supported in both Velocity and Server-side Javascript.

If the script above was saved as "api.jsm", the following could be done in Velocity:

#set($myApi = $core_v2_widget.ExecuteFile('api.jsm'))

<p>My name is $myApi.name</p>
<p>One: $myApi.next()</p>
<p>Two: $myApi.next()</p>
<p>One plus Two: $myApi.add(1, 2)</p>

or this could be done in Server-side Javascript:

var myApi = core_v2_widget.ExecuteFile('api.jsm');

var result = [];
result.push('<p>My name is ');
result.push(myApi.name);
result.push('</p>\n<p>One: ');
result.push(myApi.next());
result.push('</p>\n<p>Two: ');
result.push(myApi.next());
result.push('</p>\n<p>One plus Two: ');
result.push(myApi.add(1, 2));
result.push('</p>');

return result.join('');

Both samples would result in the HTML:

<p>My name is Bob McBobberson</p>
<p>One: 1</p>
<p>Two: 2</p>
<p>One plus Two: 3</p>

Note the rules associated with "Changing Execution Options" below as they affect interaction with complex return values.

Changing Execution Options

The core_v2_widget.ExecuteFile() API includes options to control environmental context when executing the requested embedded script file. These options include:

  • DisableAbuseChecking. When set to true, automated abuse checking will be disabled for the script while it executes.
  • DisableActivityStories. When set to true, no activity stories will be created by API actions made by the script while it executes.
  • DisableNotifications. When set to true, no notifications will be created by API actions made by the script while it executes.
  • RunAsServiceUser. When set to true, the accessing user will be set to the service user for the script while it executes effectively running the script as the service user.
  • RunAsUserName. When set, the accessing user will be set to the user with the provided username for the script while it executes effectively running the script as the requested user.

If any of these values are different from the current execution options (the script calling core_v2_widget.ExecuteFile()), some rules are applied to prevent leaking of information from the sub-script, specifically:

  • Edits to local variables made within the sub-script are not applied to the calling script.
  • Complex objects returned from the sub-script are read-only, which means properties cannot be set and functions cannot be called.

Scheduled Execution

All scripted customizations can make use of core_v2_widget.ScheduleFile() to run a sub-script as a background job on the Verint Community job server. When the sub-script is executed, the execution state is fully available, however, any local variables defined in the calling script are not persisted. Instead, it is recommended to provide any non-contextual parameters to the scheduled sub-script via the Parameters option of core_v2_widget.ScheduleFile(). Data provided via the Parameters option is available to the sub-script using core_v2_widget.GetExecutionParameterValue() and core_v2_widget.GetExecutionParameterValues().

Executing Local Configuration Property Templates

Dynamic configuration allows scripted components to use custom UI implementations to present configuration properties by assigning the property's template attribute to the name of an embedded script file (for example, template="mycustompropertytemplate.vm"). When an embedded script is executed as a custom property template, it runs without much of the execution state associated to normal execution. For example, a custom property template within an automation will not have access to context_v2_automationTrigger and a custom property template within a widget won't be able to retrieve details about layout placement.