Update 4/10/2018: Our CEP Getting Started resources are now on GitHub! See the repo for the latest info.
This article is part two of Scripting CC Apps Using CEP Panels, by guest developer Davide Barranca, a Photoshop retoucher based in Italy.
This series of posts is aimed at beginning developers who have built a panel, or are just starting to build a panel, and would like to understand how CEP communicates with CC host applications like Photoshop, InDesign, and so forth. (If you’ve never built a panel, check out our first post: “How to create your first Adobe panel in 6 easy steps”)
— Erin Finnegan, Community Engineer, Adobe
In this post we will learn how to pass
JSON string objects to the host application from our panel.
Let’s assume your web sharpening routine from part one of our series has been updated and uses several parameters: the panel has grown, and features a multitude of sliders, checkboxes and buttons. It would be awkward to list them all, like:
It’s string interpolation madness. It’s much better to provide an object parameter: in order to let the
JSX engine to properly digest your code, remember to transform it into a
JSON string first!
Without a doubt, this is nicer. Please note that even if the parameter is passed from the
JS as a
JSON string, the
JSX side receives it as an actual object.
Communicating from the host application to the panel
The Communication flow is bidirectional, so the Adobe application can tell things to the panel too. In order for the panel to listen to what e.g. Photoshop has to say, you need to include a callback in the
In the snippets above, the callback function we’ve added will receive
"true" back from Photoshop (mind you,
"true" as a string, not an actual
true boolean). Why might we want this? Well, it could be that the panel needs to know whether the
addSharpeningForWeb() function has been doing its job successfully or not. In case of errors thrown on the JSX side, the returned value is always the
"EvalScript error." string.
If you’re familiar with Promises, instead of callbacks, please refer to Steve’s post about ES6 promises .
In more sophisticated panels (this is just an example), the aspect of the panel itself may be dependent on the document currently open in Photoshop. Say, for instance, that the panel needs to somehow display layer names, and current foreground/background colors in the panel GUI. You may need to extract structured data from the host application. You know how to do this via scripting, but how can you pass this data, e.g. as an object from Photoshop to the panel?
The trick is to convert the object to a
JSON string first (in the
JSX), and then
JSON.parse() it back (in the panel's
Pay attention, though, because the ExtendScript engine has no way to know about
JSON: it's not natively featured in the language specifications from 2009, so you have to include extra code to implement
JSON.parse() otherwise an error will be thrown when you use them in the
Usually, developers borrow code from Douglas Crockford’s
json2.js, directly injecting it in their JSX; for better compatibility with the ExtendScript language itself, you can also use the code in
json.jsx, written by the InDesign developer Marc Autret instead. Please note that instead of
parse() he's implemented functions named
In this post you’ve seen how two different and fundamental parts of CEP panels (the panel’s
JS engine, and the host application’s
JSXengine) can communicate. On one side, the panel's
JS can send ExtendScript strings to the host application by means of the
evalScript() function. On the other side, the host application can send strings back to the panel that the
evalScript() second parameter callback is able to receive.
If you need to pass complex parameters such as objects from your panel’s
JS to the host app's
JSON.stringify() them first (no need to
JSON.parse() them in the
JSX – they arrive as objects). If you need to pass an object the other way around (from the host application
JSX to the panel
JS), you need to
JSON.stringify() it in the
JSX first, and
JSON.parse() it in the
JS. There's no native support of
JSON in ExtendScript, so you need either
Another form of communication between CEP Panels and host applications is based on events, but before tackling such topic you should feel comfortable with
JSON objects. Try implementing this technique on a simple panel, head over my HTML Panels Tips, and follow the Adobe I/O blog for more insights!
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
Davide Barranca is the author of two books about panels, Adobe Photoshop HTML Panels Development and The Ultimate Guide on Native Installers and Automated Build Systems. He blogs about panels and script development on his homepage, davidebarranca.com.
For more stories like this, subscribe to our Creative Cloud Developer Newsletter.