• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
10

Is it possible to store data in layers and save them?

Participant ,
Mar 28, 2024 Mar 28, 2024

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?

TOPICS
How to , Import and export , Scripting , Sync and storage

Views

95

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 28, 2024 Mar 28, 2024

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. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 28, 2024 Mar 28, 2024

Copy link to clipboard

Copied

Yes, by using LABEL property.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 28, 2024 Mar 28, 2024

Copy link to clipboard

Copied

@Lordrhavin 

 

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.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 28, 2024 Mar 28, 2024

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 28, 2024 Mar 28, 2024

Copy link to clipboard

Copied

LATEST

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines