Copy link to clipboard
Copied
Hi!
I am stuck with one part of a script I am writing. I need to perform some actions inside different Smart Objects on a document. I need my script to find them (they all share the same "YOUR IMAGE HERE" + some extra ones), go inside and do these different actions inside. Close the smart object and go to the next layer of the array.
The only thing I can achieve is to go to the first so of the list and create various layers (as many as smart objects are in the document). This is no good since I require one new layer on each smart object, not in the first one.
Probably is a silly solution, but I can't see it.
1 Correct answer
You can insert your operations instead of the alert in this example and add the exporting etc.
// 2023, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
var theSOs = collectSmartObjectsOfName("YOUR IMAGE HERE");
for (var m = 0; m < theSOs.length; m++) {
selectLayerByID(theSOs[m][1], false);
executeAction(stringIDToTypeID('placedLayerEditContents'), undefined, DialogModes.NO);
alert ("now the smart object "+theSOs[m][0]+" is open");
app.activeDocument.clo
...
Explore related tutorials & articles
Copy link to clipboard
Copied
Aren’t all the »YOUR IMAGE HERE« instances of the same Smart Object?
You seem to have omitted making the layer the activeLayer before running »Edit Contents«.
Edit: something like
doc.activeLayer = layers[i];
Copy link to clipboard
Copied
They are different Smart Objects, not a duplicate of the same.
That is true, I didn't add it!
Copy link to clipboard
Copied
Your code would not process Layers in Groups it seems.
The following code would check all Smart Objects in the active document and return an Array of Arrays (with the Smart Objects’ names and IDs).
You could pack the name-check and the other operations in the function or process the Array after running the function as it is.
// 2017, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
alert (collectSmartObjects2017().join("\n"));
};
////////////////////////////////////
////// collect smart objects, probably based on code by paul, mike or x //////
function collectSmartObjects2017 () {
// the file;
var myDocument = app.activeDocument;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
if(layerDesc.hasKey(stringIDToTypeID('smartObject'))) {theLayers.push([theName, theID])}
};
}
catch (e) {};
};
return theLayers
};
// based on code by mike hale, via paul riggott;
function selectLayerByID(id,add){
add = undefined ? add = false:add
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), id);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );
desc.putBoolean( charIDToTypeID( "MkVs" ), false );
try{
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message);
}
};
Copy link to clipboard
Copied
Thanks! I am a bit lost with functions, don't understand how they work, yet. If I try to call a variable of this code, after all brackets, everything appears to be undefined.
Copy link to clipboard
Copied
Thanks! I am a bit lost with functions, don't understand how they work, yet. If I try to call a variable of this code, after all brackets, everything appears to be undefined.
By martisans
Could you please post screenshots with the pertinent Panels (Toolbar, Layers, Options Bar, …) and the alert visible?
Edit: Or, better yet, post the code.
Copy link to clipboard
Copied
 I attached a sample of layers. It will always be different. When it is only one smart object, there is no group and when there is more than one, we usually put it like this inside a group.
The code is almost complete as you have it. What I need to do is to clean all the paths and layers inside each Smart Object. Before this, the code will save a couple of jpegs of the image with specific names and resize it.
Thank you!
Copy link to clipboard
Copied
You can insert your operations instead of the alert in this example and add the exporting etc.
// 2023, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
var theSOs = collectSmartObjectsOfName("YOUR IMAGE HERE");
for (var m = 0; m < theSOs.length; m++) {
selectLayerByID(theSOs[m][1], false);
executeAction(stringIDToTypeID('placedLayerEditContents'), undefined, DialogModes.NO);
alert ("now the smart object "+theSOs[m][0]+" is open");
app.activeDocument.close();
}
};
////////////////////////////////////
////// collect smart objects, probably based on code by paul, mike or x //////
function collectSmartObjectsOfName (theString) {
// the file;
var myDocument = app.activeDocument;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
if(layerDesc.hasKey(stringIDToTypeID('smartObject')) && theName.match(theString)) {theLayers.push([theName, theID])}
};
}
catch (e) {};
};
return theLayers
};
// based on code by mike hale, via paul riggott;
function selectLayerByID(id,add){
add = undefined ? add = false:add
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), id);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );
desc.putBoolean( charIDToTypeID( "MkVs" ), false );
try{
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message);
}
};
Copy link to clipboard
Copied
That is great! Thank you very much, c.pfaffenbichler!

