XMPie Scripting Plugin SDK
Introduction
Adobe InDesign features a scripting mechanism that allows developers to programmatically modify the document design. You can learn more about InDesign Scripting on the Adobe website at: https://helpx.adobe.com/au/indesign/using/scripting.html
Since XMPie's VDP engine is built upon Adobe InDesign, there is an opportunity to leverage XMPie's VDP capabilities, together with InDesign scripting to make further design changes.
Additionally, XMPie provides an optional Scripting Plugin for uCreate Print that adds functionality to the InDesign scripting libraries to enable InDesign scripts to automate functions from the Dynamic Content menu and panel. The XMPie Scripting Plugin is activated by installing the Advanced Layout Control license, and can for example, be used to programmatically turn a static InDesign file into a dynamic template by linking it to a data source or plan file, and place content objects into the design.
InDesign scripts may be used in both desktop and server XMPie environments, with slightly varying capabilities as described below.
Note that the following information is divided into separate information for scripting on the desktop and on the server, with a reference provided at the end.
InDesign scripting on the desktop (uCreate Print)
Use case 1 – Using only InDesign scripting features
If you wish to modify the InDesign document using only standard InDesign features, for example to add or move text or graphics to the document, you can create your script and run it on the desktop using the normal methods documented by Adobe and listed below.
Use case 2 – Scripting XMPie features
Assume that you have InDesign and uCreate Print installed yourself, but you are working with a graphic designer who does not own any XMPie software. The designer regularly creates some static InDesign documents that you wish to automatically link to a data source or plan file and place ADORs or content objects into the design instead of doing this manually every time you get a new document from the designer.
The designer can create the InDesign document and mark placeholders in the design where content objects should be placed. In the text, they can write the content object name surrounded by a specific character to represent placeholders. For example, if using “<” and “>”, the opening sentence in a mailer may look like this:
Hello <Salutation> <First Name>,
Thank you for registering to our upcoming event…
In this text there are placeholders for two content objects – <Salutation>, which will denote that person’s salutation (Mr, Miss, Mrs etc.), and <First Name> to refer to the person’s first name.
Once the document reaches you, you are supposed to link that document to a plan file and then associate each of the placeholders with a matching content object in the plan. You may have agreed on a set of placeholder names with the designer or just built the plan file based on the placeholders used. In any case, you must now go through the design and tag each placeholder with the relevant content objects of the Plan.
The XMPie Scripting Plugin and Advanced Layout Control license can assist here, because it can automate the tagging process.
The following sections outline the process to handle this task.
Licensing the desktop
From uCreate Print version 25.4 onwards, the XMPie Scripting Plugin is installed automatically by the application installer. If you have an earlier version of uCreate Print, please contact XMPie Support to request the plugin files needed for your InDesign version, and the location where they need to be saved.
The ability to use the XMPie Dynamic Content menu and panels functions in an InDesign script requires an optional license that can be purchased from XMPie. To add the XMPie Advanced Layout Control license, follow these steps:
-
Open InDesign.
-
From the Dynamic Content menu, select Help and then Activate license.
-
In the license key field, paste in the Advanced Layout Control license key and click Activate.
Creating and debugging the script
While you can use any text editor to create the script, Adobe recommends using Visual Studio Code and the ExtendScript debugger https://marketplace.visualstudio.com/items?itemName=Adobe.extendscript-debug. This is useful because you can select the Adobe InDesign application as the target application, and run the script, pause, continue and define breakpoints like you would expect from any IDE.
Sample InDesign script using XMPie plugin features
The sample script documented here will do the following:
-
Open the desired InDesign document.
-
Link the document with a plan file.
-
Associate all text content objects in the plan with the locations in the document text that matches their name.
-
Export the document as a Document Package (DPKG).
Create a new script file named, for example, myScript.jsx
At the top of the script write the following variables:
var PlanFilePath = "/C/stuff/testPlan.plan";
var DocumentFilePath = "/C/stuff/testDocument.indd";
var targetFilePath = "/C/stuff";
var targetFileName = "testDocumentXMPie";
These variables set up various file references for the script. You will change them for the document that you wish to use the script with (alternatively you can find another method to get the required information).
Note that paths are defined using “Unix” style paths, as is the custom with Adobe scripting.
To open the document and associate it with a plan, write the following:
var workDocument = app.open(File(DocumentFilePath));
workDocument.plan.filePath = File(PlanFilePath);
The first line opens the InDesign document, and saves the document reference to workDocument. The second line uses the plan property defined by the scripting plugin to set a reference to the plan file.
The next task is to go over all placeholders in the design and associate them with the plan content objects. For the sake of simplicity, we will assume that there are only text placeholders (for text content objects), and that the placeholder names fit the plan content objects (ADORs). If the names do not fit, you can code in also some mapping method.
The code does this by iterating the plan content objects, looking for placeholders that match that content object name, and setting up the content object on those placeholders. Here is how it’s done:
var planAdors = workDocument.plan.adors;
for (var i=0;i< planAdors.length;++i)
{
var planAdor = planAdors [i];
if (planAdor.objectType == ADORTypes.TEXTADOR)
{
app.findTextPreferences = NothingEnum.nothing;
app.findTextPreferences.findWhat = "<" + planAdor.name + ">";
var textsToChangeToADOR = workDocument.findText ();
for (var j=0;j<textsToChangeToADOR.length;++j)
textsToChangeToADOR[j].adorName = planAdor.name;
}
}
The first line retrieves the list of content objects from the plan, using the adors property of the now associated plan file. It then iterates it. For each content object, it checks that its type is "text" by looking into its objectType property and checking if it is equal to a TEXTADOR which is a member of the ADORType enumeration.
For each text content object it uses the findText method of a document, which is a regular InDesign method. It looks for the text “<” + planAdor.name + “>”, which, for example, for the content object “FirstName” will look for “<FirstName>”.
The findText method returns a list of results, which are simply range objects in various text contents in the document. This list is iterated, and for each range object, its adorName value is set to the name of a content object in the plan. adorName property for text range objects is an XMPie property that allows setting a content object reference to it, or querying for it.
To finish the task, the document is saved as a Document Package (DPKG). Make sure to save the document prior to exporting the dpkg because the exporting process will revert the document to its initial state:
workDocument.Save();
app.createXmpiePackage (targetFileName,
File(targetFilePath),
XmpiePackageTypes.LAYOUT); app.activeDocument.close(SaveOptions.NO);
The second line uses the XMPie scripting function createXmpiePackage in order to create a DPKG. The first parameter is the target DPKG file name. The second parameter is the folder path in which the DPKG file is created. The third parameter is the package type which is set to XmpiePackageTypes.LAYOUT, which is a DPKG. You can also pack to Campaign Package (CPKG), or XLIM document, as well as other possible XMPie packages.
The last line closes the document. Note that workDocument is no longer used. At this point, since the document is re-opened, it is invalid.
Running a script on the desktop
There are two ways to run the script with InDesign on the desktop:
-
For testing and debugging, Adobe recommends using the ExtendScript debugger in Visual Studio Code. For more information, refer to:
https://marketplace.visualstudio.com/items?itemName=Adobe.extendscript-debug -
Use the InDesign Scripts panel:
-
Open InDesign.
-
From the Windows menu, select Utilities > Scripts.
-
Right-click on the User Folder, and select Reveal in Explorer.
-
Copy your script (JSX) file into the scripts folder and it will become visible in the Scripts panel.
-
To run the script, double-click on the entry in the scripts panel.
-
Although outside the scope of this document, you can also run scripts on the desktop version of InDesign through application interfaces such as AppleScript (on Macintosh) or COM Automation (on Windows).
InDesign scripting on the server (uProduce)
System requirements
Note: Only Pro editions of PersonalEffect include the Adobe InDesign Server which is required to run InDesign scripts. Therefore, InDesign scripts cannot be run on XLIM-only servers.
Licensing the server
The ability to use InDesign scripts on the XMPie server requires an optional license that can be purchased from XMPie. The Advanced Output Control license needs to be installed in the uProduce dashboard by an admin user.
-
Browse to the uProduce dashboard and log in as an admin user.
-
Click the Settings button, and select License Manager from the list of options on the left.
-
In the License Key field, paste in the license key provided for the scripting plugin.
-
Click the link to get an activation key.
-
Your machine id and license key should be preset. Click Get Activation Key.
-
Copy the activation key.
-
Return to the uProduce dashboard, paste in the activation key and click the install button.
Running a script on the server
Running InDesign scripts on the server can be done in any of 3 ways:
-
Directly with InDesign server, via its port
-
As part of customization dials
-
As part of the “Custom Output” feature
Each method fits a different scenario, but all are common in being able to execute InDesign scripts.
Running scripts directly on the InDesign server
As part of the Adobe InDesign Server infrastructure, you can direct calls for InDesign server through the SOAP protocol. Discussing this option is outside of the scope of this document. Information about this option is available from the InDesign Scripting SDK from Adobe’s Web site: https://helpx.adobe.com/au/indesign/using/indesign-server.html
Running scripts from Customization Dials
It is possible to run scripts as part of the customization behavior in uStore. Similarly, uProduce REST API and WSAPI can also use the customization feature to run scripts. This allows you to extend the customization capabilities beyond what is supported by XMPie content objects, and in fact customize a document to any extent that is available through InDesign scripting.
An example for why you might want to run scripts as part of the customization process, could be that you wish to color a box based on a variable/customizable color value. Using a regular Style content object requires you to define each possible color in the InDesign swatches panel. If you want to allow for a large number of color values (like the full RGB or CMYK scale) this would be an overwhelming task. However, it is possible to script the color change.
Running scripts through Customization Dials is possible by using content objects (which are customized). To run a script in the beginning of the job, and thus customize the document for the VDP production process, define two Text content objects in your plan:
-
InitialScriptFileName
-
InitialScriptParameter
You should mark them as dials to make them visible as customization options in uStore. The customization value for InitialScriptFileName provides a script file (JSX) name reference (like myscript.jsx). On the uProduce server, this script file should be placed in the InDesign document's resources folder. To achieve that, you can save the JSX file next to the InDesign document in the desktop environment, and when exporting a Document Package (DPKG) or Campaign Package (CPKG), uCreate Print will automatically pack the JSX file with the document (it simply scans all JSX files placed next to the document and packs them).
You can provide a parameter to the script, with which you can further parameterize the customization (other than the choice of customization script). You can later get the parameter in the script by using this code:
var custParams = app.scriptArgs.getValue("CUST_PARAMS");
If you also wish to have a cleanup method, once the job finishes, for any actions carried out in the initial script you can define the following:
-
FinalScriptFileName
-
FinalScriptParameter
Similarly to the “Initial” scripts, the FinalScriptFileName denotes a name of a script file, and FinalScriptParameter is a parameter that can be passed to it for further parameterizing the cleanup action.
Running scripts from the Custom Output feature
The uProduce REST API and WSAPI provide a feature to allow custom outputs, that are not supported by the regular XMPie output formats. Note that any actions adding content objects during the main running script (the per-record script) will not be affective, because the content objects value population phase is passed by then. Therefore, it only makes sense to either query content objects then, or set them up at the initial script.
XMPie scripting plugin capabilities review
We learned that you can get and set the plan object for a document, as well as iterate over the ADORs or content objects in a plan. We associated text ranges with text content objects and created an XMPie Document Package (DPKG). All of these capabilities are added via the XMPie scripting plugin and Advanced Layout Control license.
The following provides a review of everything that you can do with the plugin. At the end of this document a complete reference is provided.
Document plan
An InDesign document object has a plan
property once the XMPie plugin is installed. For XMPie documents this
property will refer to the plan object. This plan may be either embedded,
or a linked plan file. In either case you can use the plan
properties to iterate plan objects. The plan objects are available via
3 properties:
-
Plan ADOR or content objects are available via plan.adors
-
Plan Variables are available via plan.variables
-
Plan fields (DB schema for recipient list are available via plan.planFields
In addition, the plan primary field name can be retrieved via the plan.primaryField property.
All these properties make it possible for a person to write general scripts that manipulate documents based on different plans. By using plan information queries one can write a script that, for example, assigns ADOR objects to a document in a pre-determined manner, as demonstrated by the example.
Document placeholders
Using scripting you can also query, add and modify document placeholders, which are the assignments of plans into a document.
Various objects that can potentially have ADOR assignments to them, such as boxes, or layers, or text ranges, have the property adorName once the plugin is installed. Through this property you can both get and set an ADOR reference. If the property value is an empty string it means that this object is not affected by an ADOR. Objects that can have a Style ADOR affecting them own the property styleADORName (such as boxes and text ranges).
For example, a layer can be assigned a Visibility ADOR, hence the following is valid:
app.activeDocument.layers[0].adorName = “myVisibilityADOR”;
where myVisibilityADOR is a name of a visibility ADOR.
It is also possible to query the document for its ADOR objects based on types. For example, you can get all Graphic ADOR placeholders by calling the following function:
Document.findGraphicAdors()
To find a specific ADOR usage (myADORName):
Document.findGraphicAdors(myADORName)
The return value is a list of page elements that either have Graphic ADOR Objects or Graphic ADOR Objects with a particular name.
Using similar methods, you can also find all usages of Visibility ADOR, as well as Object style ADOR Objects, with Document.findVisibilityAdors and Document.findStyleAdors.
Document.findVisibilityAdors()
Document.findStyleAdors()
The method for finding characters Style ADOR Objects and Text ADOR Objects is slightly different, and goes through the InDesign method of findText.
To look for Text ADOR usages, use this code:
app.findTextPreferences = NothingEnum.nothing;
app.findTextPreferences.adorName = "myADORName";
var textsToChangeToADOR = myDocument.findText();
The code sets up find preferences with the particular ADOR name for which we want to find usages, and then executes findText. In turn it will return a list of text ranges using this ADOR.
If you want to retrieve all texts that use ADOR Objects, set the adorName property of app.findTextPreferences to an empty string (“”).
The return values are text ranges, and you can check their adorName property to realize which ADOR Objects they use.
Using a similar method you can find Character Style ADOR
usages. Instead of
app.findTextPreferences.adorName
= “myADORName”, use
app.findTextPreferences.styleAdorName
= “myStyleADORName”.
Package creation
Last but not least, you can create packages from an XMPie document that is currently the active document. The types of packages that you can create are the same as those that are available via the export option in the XMPie palette menu.
You do this using the createXmpiePackage method that the scripting plugin adds to the application object. We used this method in the example script like this:
app.createXmpiePackage (targetFileName,
File(targetFilePath),
XmpiePackageTypes.LAYOUT);
As demonstrated then, the first parameter designates the package name, and the second is the folder path in which to place the package. The third parameter denotes the package type, which can be one of the values in the XmpiePackageTypes enumerator:
-
XmpiePackageTypes.CAMPAIGN – a CPKG, based on the InDesign template.
-
XmpiePackageTypes.LAYOUT – a DPKG, based on the InDesign template.
-
XmpiePackageTypes.PROOF – a Proof Set, for cases where the plan is embedded in the document. The Proof Set is generated based on the database link that is currently connected to the document, and the embedded plan.
-
XmpiePackageTypes.WEBCAMPAIGN – a Web Campaign CPKG. To be used in Hosted eMedia solutions. Contains only embedded plan logic, without the document.
-
XmpiePackageTypes.XLIM – a XLIM layout document representation of the InDesign document.
-
XmpiePackageTypes.XLIMCAMPAIGN – a CPKG, based on a XLIM representation of the InDesign document.
-
XmpiePackageTypes.XLIMLAYOUT – a DPKG, based on a XLIM representation of the InDesign document
Note that this method is available only with the desktop version of the scripting plugin. So it is possible to execute a code that contains a call to it in uCreate Print environment, but not in uProduce.
Viewing the available commands and constructs
You can see which methods and objects exist in InDesign scripting model in general, and in particular what is added by XMPie, by using the Object Model Viewer of the Extendscript toolkit. When the application is open, press F1 to open the Object Model Viewer window, and select the latest InDesign version from the browser:
You can now review the various objects that are available by the scripting model. Note that both original and XMPie commands and objects exist, each with a reference and description.
XMPie Scripting plugin reference
The following provides reference to the constructs and methods added by the scripting plugin.
Application object
The application object (available via app) has the following additions through the scripting plugin:
CreateXmpiePackage method
Application.createXmpiePackage(
name: string ,
parentFolder: File ,
packageType: XmpiePackageTypes = XMPiePackageTypes.LAYOUT,
exportFonts: Boolean = false)
Description
Exports the current document as one of 7 XMPie package types.
Return value
Nothing
Parameters
name: string, The name of the package to be created
parentFolder: File, The folder to contain the package
packageType: XmpiePackageTypes, The package type (Optional)
exportFonts: Boolean, Export fonts and agree to terms and conditions (Optional)
XmpiePackageTypes is an enumerator with the following possible values:
-
XmpiePackageTypes.CAMPAIGN – a CPKG, based on the InDesign template
-
XmpiePackageTypes.LAYOUT – a DPKG, based on the InDesign template
-
XmpiePackageTypes.PROOF – a Proof Set, for cases where the plan is embedded in the document. The Proof Set is generated based on the database link that is currently connected to the document, and the embedded plan
-
XmpiePackageTypes.WEBCAMPAIGN – a Web Campaign CPKG. To be used in hosted eMedia solutions. Contains only embedded plan logic, without the document.
-
XmpiePackageTypes.XLIM – a XLIM layout document representation of the InDesign document.
-
XmpiePackageTypes.XLIMCAMPAIGN – a CPKG, based on a XLIM representation of the InDesign document.
-
XmpiePackageTypes.XLIMLAYOUT – a DPKG, based on a XLIM representation of the InDesign document
Note that this method is only available with the desktop version of the scripting plugin.
findTextPreferences properties
Application.findTextPreferences.styleAdorName: string
Application.findTextPreferences.adorName: string
Description
The styleAdorName and adorName properties of the findTextPreferences property of the application object set up ADOR placeholder search for a later Document.findText method call. styleAdorName should be set to a string value in order to look for text ranges with style ADOR references. Empty string value will set an all style ADOR placeholder search, while a non-empty value will look for a particular ADOR name. Similarly, adorName should be set to a string value to look for text ranges with text ADOR placeholder references. Make sure to call app.findTextPreferences = NothingEnum.nothing prior to setting the property to make sure all relevant search properties are nulled.
Document object
The document object has 3 methods added through the scripting plugin, and a “Plan” property.
findGraphicAdors method
Document.findGraphicAdors(adorName:string = ””)
Description
findGraphicAdors retrieves graphic (image) placeholders. Passing empty string will retrieve all graphic placeholders. Passing a string will retrieve all placeholders where the ADOR object is used.
For each placeholder the object that contains them is retrieved, among other properties this object:
-
ADOR name (Document.findGraphicAdors()[i]. adorName)
-
Container ID (Document.findGraphicAdors()[i].id)
Return value
List of page items that contain graphic ADOR references
Parameters
adorName: string, Name of the ADOR Object that is being searched. If empty, will look for all Graphic ADOR placeholders.
findVisibilityAdors method
Document.findVisibilityAdors(adorName: string=””)
Description
findVisibilityAdors retrieves visibility placeholders. Passing empty string will retrieve all visibility placeholders. Passing a string will retrieve all placeholders where the ADOR object is used.
For each place holder the object that contains them (either spread or layer) is retrieved. The returned object will have the following information, among the regular properties:
-
ADOR name (Document. findVisibilityAdors ()[i]. adorName)
-
Container (spread or layer item) ID (Document. findVisibilityAdors ()[i].id)
-
The layer name (if layer) (Document. findVisibilityAdors ()[i].name)
Return value
A list of layers and spreads that contain visibility ADOR references
Parameters
adorName: string, Name of the ADOR Object that is being searched. If empty, will look for all visibilty ADOR placeholders.
findStyleAdors method
Document.findStyleAdors(adorName:string = ””)
Description
findStyleAdors retrieves object style placeholders. Passing empty string will retrieve all object style placeholders. Passing a string will retrieve all placeholders where the ADOR object is used.
For each place holder the object that contains them is retrieved, among other properties this object:
-
Style ADOR name (Document.findStyleAdors()[i]. styleAdorName)
-
Container ID (Document.findStyleAdors()[i].id)
Return value
List of page items that contain object style ADOR references
Parameters
adorName: string, name of ADOR to look references for. If empty, will look for all object style ADOR placeholders.
Plan property
Document.plan
Description
The document plan property contains a reference to the plan object of the document. If it is an XMPie document it will be a none-null. The plan object information may be retrieved whether the plan is embedded or not.
The plan object has the following properties:
-
filePath: File
Both set and get property for the plan file path (in case it is an external plan). Plan may be set up through this property.
-
ADOR Objects: ADOR Objects
List of plan ADOR Objects. For each ADOR Object the following properties are available:
-
name: string, ADOR name
-
dial: bool, indication of Dial property
-
rule: string, plan expression for this ADOR Object
-
annotation: string, description for this ADOR Object
-
objectType: ADORTypes, type of ADOR. Can be one of:
-
ADORTypes.GRAPHICADOR - Graphic ADOR Object
-
ADORTypes.STYLEADOR - Style ADOR Object
-
ADORTypes.TABLEADOR - Table ADOR Object
-
ADORTypes.TEXTADOR - Text ADOR Object
-
ADORTypes.TEXTFILEADOR - Text file ADOR Object
-
ADORTypes.VISIBILITYADOR - Visibility ADOR Object
-
-
variables: Variables
List of plan variables. For each variable the following properties are available:
-
name: string, Variable name
-
dial: bool, indication of Dial property
-
rule: string, plan expression for this variable
-
annotation: string, description for this ADOR Object
-
objectType: VariableObjectTypes, type of Variable. Can be one of:
-
VariableObjectTypes.BOOLEANVAR – Boolean
-
VariableObjectTypes.DATEVAR - Date
-
VariableObjectTypes.NUMBERVAR - Number
-
VariableObjectTypes.TEXTVAR - Text
-
-
-
PlanFields: PlanFields
List of plan field, that is the recipient list schema fields. For each field the following properties are available:
-
name: string, field name
-
objectType: FieldObjectTypes, type of Variable. Can be one of:
-
FieldObjectTypes.BOOLEAN – Boolean
-
FieldObjectTypes.DATE - Date
-
FieldObjectTypes.NUMBER - Number
-
FieldObjectTypes.TEXT - Text
-
-
-
primaryField:string
Name of primary field.
styleAdorName and adorName properties
Objects that can have placeholders will have adorName or styleAdorName properties. adorName is used to designate a reference to an ADOR object that is Visibility, Text or Image. styleAdorName is used to designate a Style ADOR. You can both get and set these properties, in order to query an ADOR reference, or attach an ADOR to an object. You can use these properties to set the following ADOR Objects:
-
Visibility ADOR Objects (using the adorName property of a spread or a layer)
-
Text ADOR/Text File ADOR (using the adorName property of a text range)
-
Style ADOR (either text style or object style. Use the styleADORName property of either a box or a text range, accordingly)
-
Graphic ADOR (using the adorName property of a graphic box)
Story object
Story objects (the objects in InDesign that represent a complete text content stream that uses one or more text frames to appear in) can have two extra properties, with the scripting plugins:
Story.suppressTrailingSpaces
A boolean value that determines whether trailing spaces are suppressed in case ADOR Objects are empty.
Story.suppressEmptyTables
A boolean value that determines whether table headers/footers are to be removed in case dynamic tables are empty.
Story.copyFitting
A boolean value that determines whether copy fitting will get a default value. Default values are overflow and font size.
Note that these properties are available only for the desktop version of the scripting plugin.