I’ve meanwhile become a bit more dangerous in JavaScript so I changed the original script into something more logical to me. Problem remains the same: for each document layer A, any Photoshop file in that layer should have its layer with the same name A visible, all other layers with a corresponding document layer, invisible. This leaves any other layer in the Photoshop file untouched (usually the “Background” layer with the main image. Layers or layergroups A then perform some adjustments on that background.
The code below provides a dialog box listing all layers in your document. Either pick one for all Photoshop files in that layer to be modified, or “All” to repeat the same process for each layer.
The script has a lot of $.writeln instructions commented out. They would output to the Javascript Console
/ SyncIDandPSDLayers.jsx
//
// Select an InDesign layer. Check for any Photoshop images on that layer in the document.
// If so, if the PSD file has a layer with the same name, set it visible
// set all other PSD layers that match with other InDesign layer names invisible
// Any non-matching layer name in PSD remains untouched (which usually includes the Background layer)
//
// Hence on ID layers X,Y,Z the Photoshop files have layer X visible and Y,Z invisible on the ID X layer if X layer is selected
// ,, Y X,Z Y Y
// ,, Z X,Y Z Z
//
// A n additional radiobutton allows all InDesign layers to be checked
main();
exit();
//--------------------------------------------------------------------------------------------------------------------------
function main()
{
var myDoc = app.activeDocument;
var myLayers = myDoc.layers;
var selectedLayer; // list of layers to process. Can be one or all
var numChanges;
// ask what layer to use to modify images
selectedLayer = selectLayer(myLayers);
numChanges = 0;
for (var i=0;i<selectedLayer.length;i++){
numChanges = + setPSDlayerVisible(selectedLayer[i])
};
alert ("Finished. \r Changed " + numChanges + " image layer visibility settings on " + selectedLayer.length + " InDesign layers");
exit();
}
//--------------------------------------------------------------------------------------------------------------------------
function setPSDlayerVisible(selectedLayer){
// go through all pages of the document, select the layer indicated, open all images if PhotoShop made
// and set all layers invisbile except for layer with same name as selected layer
// Return the number of changed visibility properties in the Photoshop files in the specified document layer
var links, placedFile, PSDlayer, numChanges;
// store all layers in InDesign document
var docLayers = app.activeDocument.layers;
// start with no modifications
numChanges = 0;
// only look for images that have their roots in external files, i.e. have links
links = app.activeDocument.links;
for (var i = 0; i < links.length; i++){
// get the file info from the link: stored as "parent" of the link
placedFile = links[i].parent;
// file must be an image, not null (not embedded) and made by Photoshop
if (placedFile.constructor.name == "Image" && placedFile.itemLink != null && placedFile.itemLink.linkType == "Photoshop" ){
//$.writeln ("1 found: "+ placedFile.itemLink.filePath + " on ID layer " + placedFile.itemLayer.name);
imageChange = false;
//$.write ("2 PSD file on selected layer " );
if (placedFile.itemLayer == selectedLayer){
//$.writeln (" - Yes");
// check if Photoshop file has a layer by the same name as one of the InDesign layers.
// If it does not exist, the layer will be invalid, if it does, check if the psd layer name matches an InDesign layer name.
// If that is so, set visibility true only for the layer with the same name as the selectedLayer, otherwise set layer invisible
for (var n = 0; n < docLayers.length;n++){
placedFile = links[i].parent; // after any modification of a linked object, it is replaced, so reset it to use the old object at its new location
layer = placedFile.graphicLayerOptions.graphicLayers.item(docLayers[n].name);
if (layer.isValid){
if (layer.name == selectedLayer.name){
if (layer.currentVisibility != true){
//$.writeln("psd/InDesign layer names the same - layer set visible");
layer.currentVisibility = true;
imageChange = true;
}
else{
//$.writeln("psd/InDesign layer names the same - layer already visible");
}
}
else{
if (layer.currentVisibility != false){
//$.writeln("psd/InDesign layer names different - layer set invisible");
layer.currentVisibility = false;
imageChange = true;
}
else{
//$.writeln("psd/InDesign layer names different - layer already invisible");
}
}
// count the number of changes made
if (imageChange){
numChanges++;
}
else{
}
}
else{
//$.writeln ("Layer invalid (not found)");
}
} // next docLayer
}
else{
//$.writeln (" - No");
}
}
else{
//$.writeln ("No photoshop file");
}
} // next linked file
return numChanges;
}
function selectLayer(allLayers, nrLayers){
// present all layer names in document. Allow selection of a single one or all.
// The selection is returned as an array with only 1 element or as many as there are levels.
// Each element is added to the array by push and filled with a layer object
var result=[];
// create dialog
var myDialog = app.dialogs.add({name:"Select document layer (with PSD images) ", canCancel:true});
// within the dialog box it all happens in its columns - create a radiobutton group for a series of radiobuttons
// - one button for each layer plus a button for "all layers".
// Only one button can be selected at any time. The buttongroup will obtain its value.
// Set the first button as the initially selected layer.
with (myDialog.dialogColumns.add () ){
with (borderPanels.add() ){
staticTexts.add({staticLabel:"Specify InDesign layer to sync Photoshop image layers:"});
var myRadioButtonGroup = radiobuttonGroups.add();
with(myRadioButtonGroup){
for (var i=0; i< allLayers.length; i++){
radiobuttonControls.add({staticLabel: allLayers[i].name});
}
radiobuttonControls.add({staticLabel: "All InDesign layers"});
radiobuttonControls[0].properties=({checkedState:true});
}
}
};
// show the box
var myResult = myDialog.show();
// check for OK or Cancel
if (myResult == true){
// make a difference between a single selected layer or all layers (selected button (last) then length-1 since buttons start to count from 0)
with (myDialog.dialogColumns[0].borderPanels[0].radiobuttonGroups[0]){
if(radiobuttonControls.length-1== myRadioButtonGroup.selectedButton ){
for (var i=0;i<allLayers.length;i++){
result.push(allLayers[i]);
}
}
else{ // array has a single element :the one selected layer
result.push (allLayers[myRadioButtonGroup.selectedButton]);
}
}
}
else {
result = [];
}
// delete dialog box
myDialog.destroy;
if (result == []){
alert ("Operation cancelled");
exit();
}
else{
return result;
}
}