Your prescription for increased productivity and profitability
When starting a new InDesign project, whether you are using a template or not, you may end up doing the “Open Dialogs Shuffle”:
If you think it would be nice to be able to do all of this automatically with one simple dialog, the following discussion is for you. We will be writing it in AppleScript, but you ExtendScript users can follow the same pattern.
In order for a dialog to display, the user interaction level for InDesign needs to be set to interact with all. As with other application settings you want to put the current setting in a variable before changing and then restore the value when you are through. Our example will use a variable called origLevel.
tell application "Adobe InDesign CC 2014" --capture the current settings set origLevel to user interaction level of script preferences --set the setting to what the script requires set user interaction level of script preferences to interact with all (*do whatever needs to be done using the new preferences *) --set user interaction level back to original set user interaction level of script preferences to origLevel end tell
To create a dialog, you simply tell InDesign to make a dialog. Set properties for the dialog as part of the make statement. The following puts a reference to the dialog into a variable (dlgRef) as part of its being created.
set dlgRef to make dialog with properties {name:"Name Here", can cancel:true, label:"Label name"
A dialog is created in memory and does not display until you tell the dialog to show. With can cancel set to true, the user can respond to the dialog or cancel it. The following places the result of the user’s response into a variable as part of the statement that displays the dialog. Notice how the variable used to create the dialog is used to reference the dialog..
set userResponse to show dlgRef
When through with the dialog, you need to clear the dialog from memory.
destroy dlgRef
With all of this in mind, the following can be used as a boilerplate template for creating a custom dialog.
tell application "Adobe InDesign CC 2014" set origLevel to user interaction level of script preferences set user interaction level of script preferences to interact with all set user interaction level of script preferences to interact with all set dlgRef to make dialog with properties {name:"Dialog Name", can cancel:true, label:"Dialog Label"} (*put the dialog code here *) (*end of user interface*) set userResponse to show dlgRef if userResponse = true then set theResult to {name:edit contents of nameField} else set theResult to {} end if --destroy the dialog destroy dlgRef --reset user interaction level set user interaction level of script preferences to origLevel end tell theResult
At this point if you run the script, all you will have is a dialog with two buttons: OK and Cancel.
Now that you have the skeleton for a custom dialog, you need to add input items. There are a number of widgets provided by InDesign’s custom dialog for this purpose: text fields, dropdowns, radio buttons, and checkboxes are just a few.
When you build the user interface, there are a few things you need to keep in mind:
Easy enough. To demonstrate, the following creates a master column for the dialog. The master column then creates a dialog row.
(*put the dialog code here*) --first create the master column for the dialog tell dlgRef set masterColumn to make dialog column tell masterColumn tell (make dialog row) --create label make static text with properties {static label:"Document Name:"} --add a text field (text editbox) set nameField to make text editbox with properties {min width:200} end tell end tell end tell (*end of user interface*)
Add this code to the skeleton for the dialog and run. The result will look like the following.
Notice that a variable is created to hold a reference to the name field (nameField). This will be used to create a record or list to hold the result of the user’s actions. Replace the if userResponse…end if statement block that checks the user’s response with the following and run the script.
if userResponse = true set theResult to {name: edit contents of nameField} else set wasCancelled to true end if
If the user enters information in the text field and clicks the “OK” button, the result will be a record having the value for a single record item: name.
You can add any number of fields to your custom dialog using code similar to that for creating the text edit box.
For a dropdown you need to supply it with a list of string (text) values. The value for the variable templateList below is the result of a handler (subroutine) that pulls the names of the files from the path to a fixed folder.
tell (make dialog row) make static text with properties {static label:"Select template: "} set templateField to make dropdown with properties {string list:templateList, selected index:0} end tell
Notice that lists for a custom dialog start indexing at 0 instead of 1. In returning the value from the user’s selection, your script will need to add 1.
Replace code inside the if statement that checks the user’s response (userResponse) with the following:
if userResponse = true then set tempIndex to selected index of templateField + 1 set theResult to {name: edit contents of nameField, templateIndex:tempIndex} --etc.
To get the text editbox and the dropdown to line up, the example simply placed a space after the colon for the label. If you have a number of label/widget groups to place in a custom dialog, you may want to create a column for the labels and another column for the input items.
Checkboxes include the label as part of creating the checkbox.
set checkDate to make checkbox control with properties {static label:"Add date stamp to document name:", checked state:true}
Radio buttons are a little different in that you first create a radiobutton group and then tell the readiobutton group to make radiobutton controls.
set radioGroup to make radiobutton group tell radioGroup make radiobutton control with properties {static label:"Option 1", checked state:true} make radiobutton control with properties {static label:"Option 2"} make radiobutton control with properties {static label:"Option 3"} end tell
As you can see, a custom dialog can take a hefty amount of code. While writing the code, it is easiest to write it as its own routine so the code can be tested as you work with it. Once you have the dialog working the way you want it, make it a subroutine (handler) for your script.
Because the user can take more than the default time alloted for a modal dialog, you will want to place the call to the routine inside of a with timeout statement.
global fileTypeList set fileTypeList to {"IDm7", "ID7t", "ID8t", "ID9t", "IDXt"} set templateList to getTemplateList("Templates") --call the handler for creating custom dialog and pass values for dialog properties as part of the call: with timeout of 500 seconds set userResponse to customDialog (dialogName, canCancel, dialogLabel) end timeout if userResponse = {} then activate display alert "User Cancelled" else --go on to use the information to create the document createDocument (userResponse) end if on createDocument (userResponse) --code for creating the document using information from userResponse end createDocument (*the handler that creates the dialog*) on customDialog (dialogName, canCancel, dialogLabel) --place code for creating the dialog here --don't forget to return the result back to where it was called return theResult end customDialog
Now all you need is the handler to get the list of templates and your script is ready to create a document from a template using a script to get all of the information needed. With our next script we will post a sample script that does this and more.
Our next blog will look at adding metadata to a document. Of course, the information for the metadata will come from the user input in our custom dialog.