Copy link to clipboard
Copied
Hi,
I don't know Java so your help is greatly appreciated!
I want to sort my layers into folders based on naming convention.
The closest script I found was this from stackoverflow, but it is missing selecting layers, and moving them.
JavaScript string wildcards for photoshop
// group layer vegetables
var allLayers = new Array();
var artLayers = new Array();
var theLayers = collectAllLayers(app.activeDocument, 0);
var artLayerNames = "";
// loop over art layers backwards
for (var i = artLayers.length -1; i >= 0 ; i--)
{
var temp = artLayers[i];
var regEx = new RegExp(/t/gim);
if (temp.match(regEx))
{
// if the layer contains the letter "t" show it!
alert(temp);
}
artLayerNames+= artLayers[i] + "\n";
}
// print out all layers
alert(artLayerNames);
// function collect all layers
function collectAllLayers (theParent, level)
{
for (var m = theParent.layers.length - 1; m >= 0; m--)
{
var theLayer = theParent.layers[m];
// apply the function to layersets;
if (theLayer.typename == "ArtLayer")
{
// get the art layers
artLayers.push(theLayer.name);
}
else
{
allLayers.push(level + theLayer.name);
collectAllLayers(theLayer, level + 1)
}
}
}
var r_idx = new ActionReference();
var do_it = 0;
var text = prompt("Layer name:", "", "Input");
if (text != null)
{
var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("selectNoLayers"), d, DialogModes.NO);
for (var i = 0; i < activeDocument.artLayers.leng
...
sTT = stringIDToTypeID, obj = {ELEMENTS: [], MASKS: [], LIGHTS: []}
lrs = [].slice.call((aD = activeDocument).artLayers); while(lrs.length)
(mtch = (shft = lrs.shift()).name.match(/(ELEMENT|MASK|LIGHT)/i))
&& obj[mtch[1] + 'S'].push(shft.id); while(obj.__count__) {
if ((itm = obj[frst = obj.reflect.properties[0]]).length) {
ref1 = new ActionReference(); while(itm.length)
ref1.putIdentifier(sTT('layer'), itm.shift())
iI = aD.layerSets[0].layerSets.getByName(frst.name).itemIndex - 1;
...
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Is is only necessary for me to select and move "ELEMENT", "MASK" And "LIGHT".
Copy link to clipboard
Copied
Copy link to clipboard
Copied
If it is complicated, just selecting the layer is good enough.
Copy link to clipboard
Copied
var r_idx = new ActionReference();
var do_it = 0;
var text = prompt("Layer name:", "", "Input");
if (text != null)
{
var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("selectNoLayers"), d, DialogModes.NO);
for (var i = 0; i < activeDocument.artLayers.length; i++)
if (activeDocument.artLayers[i].name.indexOf(text) >= 0) { r_idx.putIdentifier(stringIDToTypeID("layer"), activeDocument.artLayers[i].id); ++do_it; }
if (do_it)
{
var d = new ActionDescriptor();
d.putReference(stringIDToTypeID("null"), r_idx);
executeAction(stringIDToTypeID("select"), d, DialogModes.NO);
}
alert(do_it + " layers were selected");
}
Copy link to clipboard
Copied
You are amazing! Thank you 🙂
Copy link to clipboard
Copied
If a layer is nested inside groups, is it possible to find it by name?
Copy link to clipboard
Copied
Example:
Copy link to clipboard
Copied
if (activeDocument.activeLayer.typename == 'LayerSet') {
lrs=[].slice.call(activeDocument.activeLayer.artLayers); while(lrs.length)
(shft = lrs.shift()) && /PASS$/.test(nme = shft.name) && alert(nme)
}
btw is this in relation to this thread or this is independent issue?
Copy link to clipboard
Copied
relation to this thread, r-bins script selects only layers outside groups. It would be nice if it selected layers inside groups aswell.
Copy link to clipboard
Copied
How can is use this Kukurykus?
Is it possible to modifiy r-bins script to incorporate layer within groups aswell?
Copy link to clipboard
Copied
Let him adapt his script to. You can select folder and use a code for names ending with 'PASS':
function selectionOfLayersEndingWithPASS() {
sTT = stringIDToTypeID, ref = new ActionReference(); while(arr.length)
ref.putIdentifier(sTT('layer'),arr.shift());(dsc=new ActionDescriptor())
.putReference(sTT('null'), ref), executeAction(sTT('select'), dsc)
}
if (activeDocument.activeLayer.typename == 'LayerSet') {
arr = [], lrs = [].slice.call(activeDocument.activeLayer.artLayers);
while(lrs.length) (shft = lrs.shift()) && /PASS$/.test(nme = shft.name)
&& arr.push(shft.id); arr.length && selectionOfLayersEndingWithPASS()
}
Copy link to clipboard
Copied
Selects only the first layer ending with PASS. And only if it is in one group.
Copy link to clipboard
Copied
That's right, exacly like in posted earlier image.
Copy link to clipboard
Copied
Ah, sorry for being unclear. Should I start a new thread for this?
Copy link to clipboard
Copied
To make it works at least one layer(Set) must be selected:
arr = []; (function(v) {
var lrs = [].slice.call(v); while(lrs.length) {
if ((shft = lrs.shift()).typename == 'LayerSet')
callee(shft.layers) else /PASS$/.test(shft.name) && arr.push(shft.id)
}
})((aD = activeDocument).layerSets), sTT = stringIDToTypeID, arr.length && (function(){
runMenuItem(sTT('selectNoLayers')), ref = new ActionReference(); while(arr.length)
ref.putIdentifier(sTT('layer'), arr.shift()); (dsc = new ActionDescriptor())
.putReference(sTT('null'), ref), executeAction(sTT('select'), dsc)
})()
Copy link to clipboard
Copied
sTT = stringIDToTypeID, obj = {ELEMENTS: [], MASKS: [], LIGHTS: []}
lrs = [].slice.call((aD = activeDocument).artLayers); while(lrs.length)
(mtch = (shft = lrs.shift()).name.match(/(ELEMENT|MASK|LIGHT)/i))
&& obj[mtch[1] + 'S'].push(shft.id); while(obj.__count__) {
if ((itm = obj[frst = obj.reflect.properties[0]]).length) {
ref1 = new ActionReference(); while(itm.length)
ref1.putIdentifier(sTT('layer'), itm.shift())
iI = aD.layerSets[0].layerSets.getByName(frst.name).itemIndex - 1;
(dsc = new ActionDescriptor()).putReference(sTT('null'), ref1);
(ref2 = new ActionReference()).putIndex(sTT('layer'), iI)
dsc.putBoolean(sTT('adjustment'), false)
dsc.putReference(sTT('to'), ref2)
executeAction(sTT('move'), dsc)
}
delete obj[frst]
}
Copy link to clipboard
Copied
Hey Kukurykus,
I get this error when I try your script:
Copy link to clipboard
Copied
This script is made due to the layer(Sets) structure you showed on the screenshot. There is folder with 4 other subfolders inside, and then next to main folder there are many artLayers.
Do you use the same structure of folders and do you have layers column in the level zero, so under IMPORTS folder? I tried it again and it works for me. Please attach your .psd file so it will be easier for me to see if everything is like presented.
Copy link to clipboard
Copied
Ah, I forgot the IMPORTS folder!