Workaround for missing API methods (get all layercomps)

I am trying to get all layercomps names. Since this is still missing in UXP API.

  1. I created a simple extendedscript to get this list and write it to file.
    Currently I write this list to the temp folder under: $.getenv(“LocalAppData”).
    %LocalAppData%\Temp\layerscomps.txt.
  2. I created an action to run this script.
  3. In my UXP plugin I run this action via batchplay.

The problem I am facing, in UXP, is that I can’t read from the temp folder unless the user specifies it with the file picker, which is not an option.

How can write to a file which is accessible to the UXP plugin?
Or, how can I write to the UXP plugin folder in my extendedscript which would mean passing the UXP plugin path to the script/action, which I think it is not possible?

You could use getTemporaryFolder(), which IIRC doesn’t require user interaction. Same as getPluginFolder() and getDataFolder()

But beware, that running scripts from UXP might stop working on any time, even through actions (I think)

I intend to start migrating my existing CEP plugin.
I will use this locally until adobe provide the proper name.
This is just a temporary solution

How do I open a file “myfile.txt” in the temp folder and read it’s content into an array?
Each line is an element in the array?

const tempFolder = await fs.getTemporaryFolder();

If you’re dealing with arrays, you might consider using a JSON files instead. Wouldn’t be any issues figuring out how to parse lines. Sorry, but I don’t have any example on how to parse such structure.

I finally got it but it is a cumbersome solution which I will temporarily use until adobe adds this support.

It goes like this:

Preparation:

  1. Prepare an extendedScript which generates a list of all layerComps and writes it to tmpFile.
    tmpFile name is read from the layer[0] in the current doc.
  2. Create a batchPlay function to run this script

Usage:

  1. Generate a new layer whose name equals to the plugin TemporaryFolder. this is now layer[0].
  2. Run the batchPlay action to run teh extendedScript.
  3. Read tmpFile (which was generated in TemporaryFolder by the extended script)

Complicated but working :rofl:

You could write the layer comp names to an array and save the array as a global variable in your plugin’s JS. No file writing necessary and easily accessible. This assumes you’ll be using the names during the current Ps session. If you need the names for another Ps session, then the getDataFolder() option should work.

How do you write that global variable?
The layercoms are generated in an external extendedscript file?
Can you show a simple exampe of write this variable and then read it?

var myGlobalVariable = [ ];

This establishes the variable as an array. As long as you don’t put this declaration inside a function, it will be available throughout your JS, both inside and outside the function brackets, { }. This is what makes it a “global” variable.

You then need to use the JavaScript .push() function to add data values (layer comp names, in your case) to the array as they are generated.

However, I think your other issue is using extendScript to get the layer comp names. As mentioned elsewhere in this thread, using ExtendScript inside UXP is not a good idea. You should use Alchemist instead. It has a “compsList” property in Documents that looks like it supplies the information you’re looking for. You could iterate through the “compsList” arrary from Alchemist to extract their names and then “push” them into your array, which only contains these names.

This is what Alchemist shows when I select a layer comp:

const batchPlay = require("photoshop").action.batchPlay;

const result = await batchPlay(
[
   {
      _obj: "applyComp",
      _target: [
         {
            _ref: "compsClass",
            _name: "Layer Comp 1"
         }
      ],
      _options: {
         dialogOptions: "dontDisplay"
      }
   }
],{
   synchronousExecution: false,
   modalBehavior: "execute"
});

Could you elaborate how you suggest I extract the list of all layerComp names with it?

When you click on the “Code” option in Alchemist, you get:

const batchPlay = require("photoshop").action.batchPlay;

const result = await batchPlay(
[
   {
      _obj: "get",
      _target: [
         {
            _property: "compsList"
         },
         {
            _ref: "document",
            _id: 219
         }
      ],
      _options: {
         dialogOptions: "dontDisplay"
      }
   }
],{
   synchronousExecution: false,
   modalBehavior: "fail"
});
console.log(result);

This is the “getter” for this “compsList” Document property. NOTE: I don’t think you need the “_id: 219” part as it would be document specific for my document. Don’t include that.

The

console.log(result);

will display the results in the UXP Developer Tool console.

It’s usually an array of objects, and you’ll need to deconstruct based on what you get in order to find the “title”, which is the name for a particular layer comp. The UXP Developer Tool will show you the “result” via console.log and you can keep clicking the arrows on the left to locate the path to the “title”.

This is what fixed it:

const getLayerComps = (id) => {
   const result = batchPlay(
      [
         {
            _obj: "get",
            _target: [
               {
                  _property: "compsList"
               },
               {
                  _ref: "document",
                  _id: id
               }
            ],
            _options: {
               dialogOptions: "dontDisplay"
            }
         }
      ], {
      synchronousExecution: true,
      modalBehavior: "wait"
   });
   let lc=result[0].compsList;
   if(typeof lc == "undefined"){
      return [];
   }else{
      return lc.map(comp => comp.title);
   }
}