I want to create a loop that checks if a layer with a set name is within a group, then save the layer group, if not, look outside any and all layer groups for a layer with a set name, if not, ignore and save the selected layer group ?
I want my script to check the composition if there is a layer with a set name, first in the group, then outside of any, and all groups, then finally if no layer with a set name is found within the selected layer group and in the composition, excluding other layer groups, just save the layer group, understand ?
////// function to find layers of a name //////
var templateLayer;
var myLayerSet = app.activeDocument.activeLayer;
// make sure myLayerSet is a layerSet.
if( myLayerSet.typename == 'LayerSet' ){
// search the layerset for the layer name 'template'
for( var l = 0; l < myLayerSet.artLayers.length; l++ ) {
if( myLayerSet.artLayers[l].name == 'template' ){
templateLayer = myLayerSet.artLayers[l];
break;
}
}
// check to see if it was found
if( templateLayer != undefined ){
// it was found so do whatever
// call function doWhatever
}else{
// not found in expected layerset so check next level
for( var l = 0; l < myLayerSet.parent.artLayers.length; l++ ) {
if( myLayerSet.parent.artLayers[l].name == 'template' ){
templateLayer = myLayerSet.parent.artLayers[l];
break;
}
}
}
// check again to see if found
if( templateLayer != undefined ){
// found at the next level up so do whatever
// call function doWhatever
}else{
// either keep searching until parent == doc
// then if still not found bail or just bail now
throw( 'Layer not found' );
}
// function doWhatever(){ return 'done';}
}
Snippt of the scripts code, I can send you the entire script to analyze.
Maybe this arrangement can help, it uses a function that can be run on a LayerSet or a Document.
// 2012, use it at your own risk;
#target photoshop
var myDocument = app.activeDocument;
var theLayerGroup = myDocument.activeLayer;
if (theLayerGroup.typename == "LayerSet") {
var theName = "name";
var theLayers = searchForLayers(theName, theLayerGroup, []);
if (theLayers.length > 0) {alert ("the layerset contains the layer/s")}
else {
var theLayers = searchForLayers(theName, myDocument, []);
switch (theLayers.length) {
case 0:
alert ("the document contains no layer of that name");
break;
case 1:
alert ("the document contains the layer");
break;
default:
alert ("the document contains more than one layer of that name");
break;
}
}
};
////// function collect all layers //////
function searchForLayers (theName, theParent, allLayers) {
if (!allLayers) {var allLayers = new Array}
else {};
for (var m = theParent.layers.length - 1; m >= 0;m--) {
var theLayer = theParent.layers[m];
if (theLayer.typename == "ArtLayer") {
// check name;
if (theLayer.name == theName) {allLayers.push(theLayer)}
}
// apply the function to layersets;
else {
allLayers = (searchForLayers(theName, theLayer, allLayers))
}
};
return allLayers
};
To execute the error; I created three layer groups. One layer group labelled 'Group 3' with a red square, another layer group with a green hexegon labelled 'Group 2' and finally a third layer group with a black circle, labelled 'Group 1'. I have a layer that is outside of all of these groups called 'template'.
Selecting the layergroup 'Group 3' that contains the red square, I ran the script, I get an error 'ReferenceError:findTemplate is not a function'. What I was expecting was the layer group would be saved with an option to save to any image format, and including the template layer that exists outside of all of the layergroups. Lets not forgot, what if the 'template' layer is within a layergroup, and not 'outside' of all the layergroups, it must be included in that layer group and saved specifically with that layer group to a image format. I decided to post the entire script; maybe you will find fault somewhere.
// Custom Saving LayerGroup Productivity Tool
// 2012 - csMotion_Design
#target photoshop
if (app.documents.length > 0) {
////////////////////////////////////
// get document-path and -title;
// 2012, use it at your own risk;
#target photoshop
var myDocument = app.activeDocument;
var theLayerGroup = myDocument.activeLayer;
if (theLayerGroup.typename == "LayerSet") {
var theName = "name";
var theLayers = searchForLayers(theName, theLayerGroup, []);
if (theLayers.length == 1) {alert ("the layerset contains the layer")}
else {
var theLayers = searchForLayers(theName, myDocument, []);
switch (theLayers.length) {
case 0:
alert ("the document contains no layer of that name");
break;
case 1:
alert ("the document contains the layer");
break;
default:
alert ("the document contains more than one layer of that name");
break;
}
}
};
////// function collect all layers //////
function searchForLayers (theName, theParent, allLayers) {
if (!allLayers) {var allLayers = new Array}
else {};
for (var m = theParent.layers.length - 1; m >= 0;m--) {
var theLayer = theParent.layers[m];
if (theLayer.typename == "ArtLayer") {
// check name;
if (theLayer.name == theName) {allLayers.push(theLayer)}
}
// apply the function to layersets;
else {
allLayers = (searchForLayers(theName, theLayer, allLayers))
}
};
return allLayers
};
// get template;
var theTemplateName = "template";
var theResults = findTemplate(myDocument, theTemplateName);
switch (theResults.length) {
case 0:
alert ("no layer named »template«");
var myReturn = 1;
break;
case 1:
theTemplate = theResults[0];
var dlg = new Window("dialog", "put template at", [500,300,920,370]);
// buttons for rounded points;
dlg.position = dlg.add('panel', [15,10,105,60], '');
dlg.position.top = dlg.position.add('radiobutton', [13,0,185,25], 'top');
dlg.position.top.value = true;
dlg.position.bottom = dlg.position.add('radiobutton', [13,20,185,50], 'bottom');
// buttons for ok and cancel;
dlg.buttons = dlg.add('panel', [115,10,405,60], '');
dlg.buttons.buildBtn = dlg.buttons.add('button', [145,12,270,34], 'OK', {name:'ok'});
dlg.buttons.cancelBtn = dlg.buttons.add('button', [13,12,135,34], 'Cancel', {name:'cancel'});
// show the dialog;
dlg.center();
var myReturn = dlg.show ();
break;
default:
alert ("more than one layer named »template«")
break;
};
////////////////////////////////////
if (myReturn == 1) {
// psd options;
psdOpts = new PhotoshopSaveOptions();
psdOpts.embedColorProfile = true;
psdOpts.alphaChannels = false;
psdOpts.layers = true;
psdOpts.spotColors = true;
////////////////////////////////////
// create a history state to return to later;
myDocument.quickmaskMode = true;
myDocument.quickmaskMode = false;
var historyState = myDocument.activeHistoryState;
// do the operation;
for (var m = selectedLayerSets.length - 1; m >= 0; m--) {
var theRemove = myDocument.artLayers.add();
theRemove.remove();
// get the layername for the file-name;
var thisSet = selectedLayerSets[m];
hideOthers (thisSet, myDocument);
var aLayerName = thisSet.name;
// remove »/« and »:«;
while (aLayerName.indexOf("/") != -1) {
aLayerName = aLayerName.replace("/", "_")
};
while (aLayerName.indexOf(":") != -1) {
aLayerName = aLayerName.replace(":", "_")
};
// show template;
if (theResults.length == 1) {theTemplate.visible = true};
// duplicate;
var theCopy = myDocument.duplicate ("thecopy", false);
// delete hidden layers;
////// delete hidden layers //////
function deleteHiddenLayers () {
try {
var id26 = charIDToTypeID( "Dlt " );
var desc6 = new ActionDescriptor();
var id27 = charIDToTypeID( "null" );
var ref6 = new ActionReference();
var id28 = charIDToTypeID( "Lyr " );
var id29 = charIDToTypeID( "Ordn" );
var id30 = stringIDToTypeID( "hidden" );
ref6.putEnumerated( id28, id29, id30 );
desc6.putReference( id27, ref6 );
executeAction( id26, desc6, DialogModes.NO );
} catch (e) {}
};
///////////////////////
/// save and close;
//////////////////////
theCopy.saveAs((new File(myPath+"/"+myDocName+"_"+aLayerName+".psd")),psdOpts,true);
theCopy.close(SaveOptions.DONOTSAVECHANGES)
// return in history;
myDocument.activeHistoryState = historyState;
}
};
};
else {alert ("no document open")};
////////////////////////////////////
////// buffer number with zeros //////
function bufferNumberWithZeros (number, places) {
var theNumberString = String(number);
for (var o = 0; o < (places - String(number).length); o++) {
theNumberString = String("0" + theNumberString)
};
return theNumberString
};
////// delete hidden layers //////
function deleteHiddenLayers () {
var id26 = charIDToTypeID( "Dlt " );
var desc6 = new ActionDescriptor();
var id27 = charIDToTypeID( "null" );
var ref6 = new ActionReference();
var id28 = charIDToTypeID( "Lyr " );
var id29 = charIDToTypeID( "Ordn" );
var id30 = stringIDToTypeID( "hidden" );
ref6.putEnumerated( id28, id29, id30 );
desc6.putReference( id27, ref6 );
executeAction( id26, desc6, DialogModes.NO );
};
////// toggle visibility of others //////
function hideOthers (theLayer, myDocument) {
myDocument.activeLayer = theLayer;
// =======================================================
var idShw = charIDToTypeID( "Shw " );
var desc10 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var list4 = new ActionList();
var ref7 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref7.putEnumerated( idLyr, idOrdn, idTrgt );
list4.putReference( ref7 );
desc10.putList( idnull, list4 );
var idTglO = charIDToTypeID( "TglO" );
desc10.putBoolean( idTglO, true );
executeAction( idShw, desc10, DialogModes.NO );
};
////// by paul mr //////
function GetSelectedLayers() {
var A=[];
var desc11 = new ActionDescriptor();
var ref9 = new ActionReference();
ref9.putClass( stringIDToTypeID('layerSection') );
desc11.putReference( charIDToTypeID('null'), ref9 );
var ref10 = new ActionReference();
ref10.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
desc11.putReference( charIDToTypeID('From'), ref10 );
executeAction( charIDToTypeID('Mk '), desc11, DialogModes.NO );
var gL = activeDocument.activeLayer.layers;
for(var i=0;i<gL.length;i++){
A.push(gL[i]);
}
executeAction( charIDToTypeID('undo'), undefined, DialogModes.NO );
return A;
};
////// function to find layers of a name //////
function findTemplate (theParent, theTemplateName) {
if (!allLayers) {var allLayers = new Array}
else {};
for (var m = theParent.layers.length - 1; m >= 0;m--) {
var theLayer = theParent.layers[m];
// apply the function to layersets;
if (theLayer.typename == "ArtLayer") {
if (theLayer.name == theTemplateName) {
allLayers.push(theLayer)
}
}
else {
allLayers = allLayers.concat(findTemplate(theLayer, theTemplateName))
}
};
return allLayers
};
I have no intention of trouble-shooting your lengthy script.
With the Script I provided earlier a case like you described (template layer at top level) results in the alert »the document contains the layer«, so I see no issue there.
»ReferenceError:findTemplate is not a function« sounds like there might be an issue with the function findTemplate (though I can’t reproduce the issue) – why you use that function at all I don’t know.
I mentioned that I was going to be posting a part of my script related to the problem, I never said I needed a entire new script to solve the issue
I need find an fix what the problem is with my script with regards to the layer groups not saving the template layers. You posted a entirly new script, I thought I could take the script you posted and blend it with my complete script to solve the problem, argggh.
Can you verify something for me, the script you posted, did the task I was after ? I just copied and pasted it within my code. I would greatly appreciate if, even though you are busy, if you could aid in solving this. The script as it stands is perfect, it is only the template issue that is plaqing me.
The script solves the problem, that I was encountering. It's up to me to take it, or change it and add it to my complete script ? There is no newbie forum to help with situations as this, what part of the script needs to be removed to add a change etc. Everyone knows programming is not easy, remembering a programs syntax is a step in the right direction, but making something work not so much.
The snippet I provided provides alerts for the various situations, that is where you could insert the corresponding procedures you want to trigger.
And the array theLayers lists the respectively corresponding template-Layer/s, so that can be used to address them or their parents.
In the code I posted the alerts mark the various places you could use as jumping off points for the different operations you want to perform depending on the situation (template-layer in the layerSet or not etc.).
If you wrap your operation(s) in function(s) you can insert those instead of the alerts.
If the function takes the template layer and the selected layerSet as arguments you can feed them into the functions there.
I'm not quite understanding, do I take your script and incorporate it into mine ? As I mentioned my script works as it currently stands, the problem is it doesn't take into account any layer within the layergroup or outside of the layergroup named 'template', remember I'm a newbie at scripting with Ps, if you don't mind ?
This would be an example of how to use a function to jump off from the various points – don’t consider this as a final Script but as an illustration of one possible way.
I frankly did not see what the dialog was for as the input did not seem to be used later on so I dropped it.
// 2012, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
////////////////////////////////////
// get document-path and -title;
// 2012, use it at your own risk;
#target photoshop
var myDocument = app.activeDocument;
var theLayerGroup = myDocument.activeLayer;
if (theLayerGroup.typename == "LayerSet") {
var theName = "template";
var theLayers = searchForLayers(theName, theLayerGroup, []);
if (theLayers.length == 1) {
doStuff (myDocument, theLayerGroup, undefined);
}
else {
var theLayers = searchForLayers(theName, myDocument, []);
switch (theLayers.length) {
case 0:
alert ("the document contains no layer of that name");
doStuff (myDocument, theLayerGroup, undefined);
break;
case 1:
doStuff (myDocument, theLayerGroup, theLayers[0]);
break;
default:
alert ("the document contains more than one layer of that name");
break;
}
}
};
};
else {alert ("no document open")};
////////////////////////////////////
////// function collect all layers //////
function searchForLayers (theName, theParent, allLayers) {
if (!allLayers) {var allLayers = new Array}
else {};
for (var m = theParent.layers.length - 1; m >= 0;m--) {
var theLayer = theParent.layers[m];
if (theLayer.typename == "ArtLayer") {
// check name;
if (theLayer.name == theName) {allLayers.push(theLayer)}
}
// apply the function to layersets;
else {
allLayers = (searchForLayers(theName, theLayer, allLayers))
}
};
return allLayers
};
////// delete hidden layers //////
function deleteHiddenLayers () {
var id26 = charIDToTypeID( "Dlt " );
var desc6 = new ActionDescriptor();
var id27 = charIDToTypeID( "null" );
var ref6 = new ActionReference();
var id28 = charIDToTypeID( "Lyr " );
var id29 = charIDToTypeID( "Ordn" );
var id30 = stringIDToTypeID( "hidden" );
ref6.putEnumerated( id28, id29, id30 );
desc6.putReference( id27, ref6 );
executeAction( id26, desc6, DialogModes.NO );
};
////// toggle visibility of others //////
function hideOthers (theLayer, myDocument) {
myDocument.activeLayer = theLayer;
// =======================================================
var idShw = charIDToTypeID( "Shw " );
var desc10 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var list4 = new ActionList();
var ref7 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref7.putEnumerated( idLyr, idOrdn, idTrgt );
list4.putReference( ref7 );
desc10.putList( idnull, list4 );
var idTglO = charIDToTypeID( "TglO" );
desc10.putBoolean( idTglO, true );
executeAction( idShw, desc10, DialogModes.NO );
};
////// by paul mr //////
function GetSelectedLayers() {
var A=[];
var desc11 = new ActionDescriptor();
var ref9 = new ActionReference();
ref9.putClass( stringIDToTypeID('layerSection') );
desc11.putReference( charIDToTypeID('null'), ref9 );
var ref10 = new ActionReference();
ref10.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
desc11.putReference( charIDToTypeID('From'), ref10 );
executeAction( charIDToTypeID('Mk '), desc11, DialogModes.NO );
var gL = activeDocument.activeLayer.layers;
for(var i=0;i<gL.length;i++){
A.push(gL[i]);
}
executeAction( charIDToTypeID('undo'), undefined, DialogModes.NO );
return A;
};
////// function to find layers of a name //////
function findTemplate (theParent, theTemplateName) {
if (!allLayers) {var allLayers = new Array}
else {};
for (var m = theParent.layers.length - 1; m >= 0;m--) {
var theLayer = theParent.layers[m];
// apply the function to layersets;
if (theLayer.typename == "ArtLayer") {
if (theLayer.name == theTemplateName) {
allLayers.push(theLayer)
}
}
else {
allLayers = allLayers.concat(findTemplate(theLayer, theTemplateName))
}
};
return allLayers
};
////// the operation //////
function doStuff (myDocument, thisSet, theTemplate) {
var myPath = myDocument.path;
var myDocName = myDocument.name;
// psd options;
psdOpts = new PhotoshopSaveOptions();
psdOpts.embedColorProfile = true;
psdOpts.alphaChannels = false;
psdOpts.layers = true;
psdOpts.spotColors = true;
////////////////////////////////////
// create a history state to return to later;
myDocument.quickmaskMode = true;
myDocument.quickmaskMode = false;
var historyState = myDocument.activeHistoryState;
// hide other layers;
hideOthers (thisSet, myDocument);
var aLayerName = thisSet.name;
// remove »/« and »:«;
while (aLayerName.indexOf("/") != -1) {aLayerName = aLayerName.replace("/", "_")};
while (aLayerName.indexOf(":") != -1) {aLayerName = aLayerName.replace(":", "_")};
// show template;
try {
theTemplate.move(myDocument, ElementPlacement.PLACEATBEGINNING);
theTemplate.visible = true;
}
catch (e) {};
// duplicate;
var theCopy = myDocument.duplicate ("thecopy", false);
deleteHiddenLayers ();
///////////////////////
/// save and close;
//////////////////////
theCopy.saveAs((new File(myPath+"/"+myDocName+"_"+aLayerName+".psd")), psdOpts, false);
theCopy.close(SaveOptions.DONOTSAVECHANGES)
// return in history;
myDocument.activeHistoryState = historyState;
};
When I export a layergroup which the template layer resides outside of any and all layergroups, the script does what it should be doing, except when I load the layergroup that was exported from the script, the template layer is above the exported layergroup of the composition instead of within it, at the very bottom of all other layers, that is the only final bug.
Currently the function uses a try-clause to move a template outside of the selected LayerSet to the top of the file and make it visible.
You can change the line
theTemplate.move(myDocument, ElementPlacement.PLACEATBEGINNING); to instead move it to the end of the LayerSet instead.
And if you want to treat template Layers differently according to whether they are top level or inside another LayerSet you could add an if-clause that checks for the template Layer’s parent.
if (theTemplate.parent == myDocument) {/*do one thing*/}
else {/*do another*/}
And if you want to treat template Layers differently according to whether they are top level or inside another LayerSet you could add an if-clause that checks for the template Layer’s parent.
if (theTemplate.parent == myDocument) {/*do one thing*/} else {/*do another*/}
Correct me if I'm wrong, if the template layer is outside of the layer group I can have it "pulled" into the layerGroup upon exporting the specific layerGroup or not, with a dialog ?
I want to streamline the export process, by having dialog ask me to keep the 'template' in the layergroup or outside and regardless of which option choosen it always places the 'template' layer at the buttom of either the layergroup outside of the exported layergroup, I hope someone can help ?
North America
Europe, Middle East and Africa
Asia Pacific