Objectif Lune joins Upland Software.Learn more >
Philippe Fontan
May 4th, 2023
Yes, you read that title right: starting with version 2023.1, you can include your own user-defined JS modules in Workflow so that you no longer have to copy/paste into every single scripting task all these wonderful methods and objects you created to make your development job easier. I have been using this feature for several months now (one of the perks of my job!) and I just don’t know how I managed without it for all these years. Let’s take an in-depth look.
When you’ve used Workflow for as long as I have, you start developing patterns and habits. I have tens of code snippets that are carefully named and stored in one of my OneDrive folders so that I can quickly import them into some new project I’m working on. I just make a few adjustments, and I get things up and running much more quickly than if I had to do everything from scratch.
For instance, I have snippets with examples on how to navigate a DOM structure using the MSXML object. Other samples remind me how to connect to, query and retrieve results from an ODBC database. I have numerous examples of using the OL Connect REST API and even more snippets for PDF manipulation.
Generally, Workflow solutions use several scripts across many different processes, and you have to copy those snippets of code from one script task to the next to make sure they are consistent. If you need to make changes, you might have to do that in several different scripting tasks, which is time-consuming and error-prone.
For instance, one of the things almost all Workflow configurations I create have in common is the use of a manifest file that contains information read at start-up time from a JSON file, which allows the configuration to work across several different machines (which is a must for DTAP environments). So in my start-up process, I usually have a scripting task that reads and parses a manifest file, and assigns the values it contains to various global variables in my Workflow configuration.
Starting with Connect 2023.1, I can standardize this manifest procedure and implement it in a consistent fashion in any Workflow configuration I create.
An Include file is a module that gets read and parsed by the JavaScript engine prior to executing a scripting task. The module can therefore be referenced and used inside that scripting task because you know it’s been loaded by the engine. In Workflow, include files only work for scripting tasks that use the Enhanced JScript language. Don’t try them with VB or with standard JS, they just won’t work.
The include file must adhere to the same coding restrictions as any other Enhanced JScript task. That means you can’t just copy a random JS file from the interwebs and expect it to work as is. In other words, don’t start including the entire JQuery library, or the Angular Framework into your configurations: they are highly unlikely to work. The goal of the include files in Workflow is to allow you to re-use your own code, or at the very least, code that has been proven to work in Workflow.
There’s no GUI for doing so (yet!). But all you have to do is create/edit a JSON file ( C:/ProgramData/Objectif Lune/PlanetPress Workflow 8/PlanetPress Watch/includes.json ) that contains an array of files you want to automatically make available to all your scripting tasks. Here’s what the file might look like:
[ "C:/WF/JSIncludes/logger.js", "C:/WF/JSIncludes/manifest.js", "C:/WF/JSIncludes/textfile.js" ]
That syntax is pretty much self-explanatory: just list the full path name for each module. It’s worth noting that the paths can contain dynamic values (e.g. %{global.MyWorkFolder}/manifest.js) so that the modules can be moved easily.
%{global.MyWorkFolder}/manifest.js
Save that file and we’re off to the races!
Let’s implement a manifest parser and include it as a reusable piece of code.
The code for the parser itself is relatively straightforward:
(function() { function Manifest(obj) { this.params; this.fileName; this.error; this.loadFromFile = function(fName){ if(!(new ActiveXObject("Scripting.FileSystemObject")).FileExists(fName)) return false; var result; var stream = new ActiveXObject("ADODB.Stream"); stream.Type = 2; stream.CharSet = "utf-8"; try { stream.Open(); stream.LoadFromFile(fName); result = stream.ReadText(); this.params = JSON.parse(result); this.fileName = fName; } catch(e) { this.error = e; } finally { stream.Close(); stream = null; } return true; } this.assignVars = function(){ if(!this.params) return; if(this.params.globals){ for(var varName in this.params.globals){ try { if(typeof this.params.globals[varName]==="function") continue; Watch.SetVariable('global.'+varName, this.params.globals[varName]); } catch(e) { this.error = e; break; } } } } // contructor code if(!this.loadFromFile(obj)){ try { this.params = Object.assign(obj); } catch(e) { this.error = e; } } } global.Manifest = Manifest; }());
The Manifest object can be initialized with a file name or with an object. It has 2 methods:
Manifest
The magic happens on the penultimate line: global.Manifest = Manifest. That line of code assigns the object prototype to the global scripting environment, which is what will allow you, in any script, to create an instance of the manifest object by using var mf = new Manifest(), as if that object was natively available in the engine.
global.Manifest = Manifest
var mf = new Manifest()
The actual manifest.json file might look something like this:
{ "globals": { "workspace": "C:/WF/Workspace", "localURL" : "192.168.55.14", "role" : "DEV" } }
With a structure like this one, we need to create the corresponding global variables in Workflow: workspace, localURL and role. That’s how the manifest object’s assignVars() method will understand which values from the manifest file to map to which variable.
workspace
localURL
role
assignVars()
Now to use (and reuse!) the manifest, all you need is a scripting task with the following lines of code:
var mf = new Manifest(); mf.loadFromFile("C:/WF/JSIncludes/manifest.json"); mf.assignVars();
If you really want to save some real-estate, you can do it all with a single statement:
// initialize Manifest with a file name (new Manifest("C:/WF/JSIncludes/manifest.json")).assignVars(); // or initialize Manifest with an object (new Manifest( { globals: { role : "TEST"} })).assignVars();
If you’re anything like me, you’ll want to revisit some of the Workflow processes and configurations you’ve created in order to identify the reusable pieces that could be candidates for include files. Over the next few weeks, I plan on writing blog articles in which I will be sharing some of the modules I have created and which have now become an integral part of my work with Workflow.
Tagged in: JavaScript
Receive exclusive OL products news, tips and resources.
Your email address will not be published. Required fields are marked *
Notify me of followup comments via e-mail. You can also subscribe without commenting.
Δ