9

I'm working on a Photoshop script in JavaScript using ExtendScript. My script allows some user input, and I'd like to save it between uses. That is, I'm looking for a way to save a simple string or numeric value under a particular key so that I'll be able to access it on subsequent uses of the script. Simply put, I want to save a preference for my script. How do I do that?

Even better would be to be able to save at least some preferences on a per-document basis. Is that possible? That is, can I store an arbitrary bit of data with a document?

Dave Feldman
  • 104
  • 1
  • 9
  • 28

3 Answers3

13

You can use put/get custom options to save preference parameters that persist across Photoshop launches:

const kMyFlag = app.stringIDToTypeID( "myFlag" );
const kMyNumber = app.stringIDToTypeID( "myNumber" );
const kMySettings = "mySettings";

function saveSettings()
{
  var desc = new ActionDescriptor();
  desc.putBoolean(kMyFlag, true);
  desc.putInteger(kMyNumber, 42);

  // "true" means setting persists across Photoshop launches.
  app.putCustomOptions( kMySettings, desc, true );
}

function getSettings()
{
  var desc = app.getCustomOptions( kMySettings );
  return [desc.getBoolean( kMyFlag ), desc.getInteger( kMyNumber )];
}
Tobias Kienzler
  • 25,759
  • 22
  • 127
  • 221
J. Peterson
  • 1,996
  • 1
  • 24
  • 21
  • Edited the example to show multiple values on the same descriptor. – J. Peterson Jun 13 '13 at 18:52
  • Just in case someone else finds this when looking for a solution that works in indesign: You can use app.insertLabel and app.extractLabel to store your preferences – ChristophK Nov 03 '14 at 15:24
  • Will this solution work on macOS? Based on getCustomOptions documentation "Retrieves user objects from the Photoshop registry for the ID with value key" and since I understand mac does not use registry, hence the question. I dont have a mac so I cant test. – deggen Aug 14 '20 at 06:40
  • The "registry" in question is internal to Photoshop, so it'll work on both Mac and Windows. – J. Peterson Aug 17 '20 at 08:39
  • noobie question here: is this what `ActionDescriptor` supposed to do? Saving preferences? In Illustrator we have `Preferences` solely for this purpose. – Hendra Anggrian Jul 22 '21 at 13:31
  • In Photoshop, `ActionDescriptor` is a generic structure for passing events and related data from scripts to the application. Storing preferences is one use of it, there are many others. – J. Peterson Jul 26 '21 at 23:00
7

You have some options. You can create a text file and write to it using the File object:

var prefs = new File("~/desktop/prefs.txt");
prefs.open("w"); // or "a" to append
prefs.writeln("user:lenny;favorite_color:ff6600;likes:sunsets;");

...if you wanted your preferences tied to the script itself.

If you want per-document preferences you could write a string to one of the metadata fields of the file your working on using Document.info like this (using the 'instructions' field but you could use any writable field):

var doc = app.activeDocument;
doc.info.instructions = "user:lenny;favorite_color:ff6600;likes:sunsets;";
//alert(doc.info.instructions); // see, it works!

As for how to actually format the string you could just do it like a simple config file or, if you have a complex user preferences object you could use the XML object to construct and serialize it. JSON would be great for this but there is no JSON object in Extendscript, unfortunately.

Tobias Kienzler
  • 25,759
  • 22
  • 127
  • 221
pdizz
  • 4,100
  • 4
  • 28
  • 42
1

For per-document prefs I suggest the use of the XMP Metadata. You can find example snippet here: http://forums.adobe.com/thread/790973. You can leverage AdobeXMPScript library to create your own namespace like it is suggested in the link by Paul Riggott.

LeZuse
  • 1,132
  • 10
  • 17