Copy link to clipboard
Copied
I dont know if scripts can do this, but..
can I store data in layers (layer.someArbitraryAttribute = ..) that could be saved and load with the document and can I attach a script to the document that aceses those data, by a GUI dialog for example, where you could change them?
Copy link to clipboard
Copied
Hi @Lordrhavin, yes you can. There are a few ways, but here's one:
//@include 'path/to/json3.js'
var doc = app.activeDocument;
// your abitrary object
var testObject = {
key1: 'value1',
key2: 'value2'
};
// store the object in 'myKey' in layer
doc.layers[0].insertLabel('myKey', JSON.stringify(testObject));
Then to retrieve the object, do this:
//@include 'path/to/json3.js'
var doc = app.activeDocument;
// retrieve the string stored in 'myKey' in layer 0
var myString = doc.layers[0].extractLabel('myKey');
// note: it is a String
$.writeln(myString);
// parse the string, into an normal Object
var myExtractedObject = JSON.parse(myString);
// read a property of the parsed object
$.writeln(testObject.key1);
Because you can only store Strings, I am using the 'json3.js' library (download free here) to do the work to convert the Object to String and then back again later. So the first line of the script "includes" the json3.js file.
- Mark
Edit: if you don't want to use JSON.stringify you can use myObject.toSource() to convert to string and then later use eval(myString) to convert back. I always have the JSON polyfill available so I prefer that way.
Edit 2: by the way, if you want to store something that you want to access from the GUI, then if you use the "label" key to store an object, then it will appear in the ScriptLabel Panel in Indesign. The shortcut for this is to set and get the "label" property of pretty much any DOM object. Yeah you can do insertLabel and extractLabel on almost any DOM object, eg. a TextFrame. And if you export IDML you can read it in plain text.
Copy link to clipboard
Copied
Yes, by using LABEL property.
Copy link to clipboard
Copied
What kind of information do you want to store - and what do you want to do with it? What's your end goal?
Pretty much each object in the InDesign have LABEL property - accessible directly in the UI - and scripting accessible only Insert/Extract functionality.
Copy link to clipboard
Copied
@m1b Mark -- You don't need the json3.js package. You can store a JSON object using toSource():
doc.layers[0].insertLabel('myKey', testObject.toSource());
Which in effect stringifies the object. Then retrieve the string and eval it:
var myString = doc.layers[0].extractLabel('myKey');
var myObject = eval (myString);
$.writeln(myObject.key1);
P.
Copy link to clipboard
Copied
Hi @Peter Kahrel, you are right (and actually I did add that option as an edit, that you wouldn't have seen in the notification email).
But it makes me strangely nervous and I won't do it that way because—and this is going to sound a bit extreme in our context of ExtendScript—I think it's a bad practice to run arbitrary code. It seems far-fetched, but really, if someone knew that a popular script or extension stored data in a particular label (which they could discover by exporting IDML) then they could share a document with malicious code inserted in that label, and that script or extension would happily run it—deleting files, for example.
Additionally, I almost always store data as JSON so using JSON.stringify suits me well. It is extremely fast, and I have it always on hand, so there's no downside for me.
- Mark