Skip to main content
Known Participant
April 17, 2024
Answered

Photoshop script replacing linked smart objects based on layer "name string"

  • April 17, 2024
  • 3 replies
  • 2648 views

I need a photoshop script to do the following:

Open a Dialogue Box and have an option to...
 Replace linked smart objects labeled "RED" in the Name of the layer and update all linked smart objects associated with that color to "BLUE"
ex: "RED" will replace the following smart objects based on their name from the current file directory

Linked Smart Objects:
- RED_3D22
- RED_BLACK
- RED_FUTURE
- RED_WHITE
- RED_HUGOKNOTS_NEG
- RED_HUGOKNOTS_POS
- RED_MONOCHROME
- RED_MONOPLUS_BP

to these Linked Smart Objects from the same directory

- BLUE_3D22
- BLUE_BLACK
- BLUE_FUTURE
- BLUE_WHITE
- BLUE_HUGOKNOTS_NEG
- BLUE_HUGOKNOTS_POS
- BLUE_MONOCHROME
- BLUE_MONOPLUS_BP

 

** If smart object above does not exist in the existing PSD, it will ignore and continue executing the script til completion.

that is all, no exporting or saving, just swapping.

any help is appreciated.

This topic has been closed for replies.
Correct answer Stephen Marsh

This "Relink All Smart Object Layers Using New Name Prefix.jsx" variation will process all linked smart object layers found inside layer groups/nested layer groups (not only root/top-level layers):

 

/*
Relink All Smart Object Layers Using New Name Prefix.jsx
(Including layers in groups and nested groups)
v1.0 - 19th April 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-script-replacing-linked-smart-objects-based-on-layer-quot-name-string-quot/td-p/14559920

Note: The case-insensitive colour name prefix replaces the linked file with another file in the same directory with a different colour prefix name -

From: blue_rectangle.psd
      blue_circle.psd

To:   red_rectangle.psd
      red_circle.psd

There is no need to type the underscore _ separator character (although it has to exist in the filename) and the replacement image should have the same resolution and file format as the smart objects
*/

#target photoshop

app.activeDocument.suspendHistory("Relink All Smart Object Layers Using New Name Prefix.jsx", "main()");

function main() {

    // Prompt for the colour prefix
    var thePrefix = prompt("Enter the new linked filename prefix:", "red");
    if (thePrefix === null) {
        //alert('Script cancelled!');
        //app.beep();
        return
    }
    processAllLayersAndSets(app.activeDocument);


    ///// FUNCTIONS /////

    function getSmartObjectReference() {
        // https://stackoverflow.com/questions/63010107/get-a-smart-objects-layers-files-directory-source-in-jsx
        try {
            var smartObject = {
                found: false,
                fileRef: '',
                filePath: '',
                linked: false,
            };
            var ref, so;
            ref = new ActionReference();
            ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObject"));
            ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
            so = executeActionGet(ref).getObjectValue(stringIDToTypeID("smartObject"));
            smartObject.found = true;
            smartObject.linked = so.getBoolean(stringIDToTypeID("linked"));
            smartObject.fileRef = so.getString(stringIDToTypeID("fileReference"));
            if (smartObject.linked) {
                smartObject.filePath = so.getPath(stringIDToTypeID("link"));
            } else {
                smartObject.filePath = Folder.temp + '/' + smartObject.fileRef;
            }
            return smartObject;
        } catch (e) {
            alert(e);
            return smartObject;
        }
    }

    function processAllLayersAndSets(obj) {
        // Process all layers and layer sets
        // Change the following 2 entries of "obj.artLayers" to "obj.layers" to include layer sets
        for (var al = obj.artLayers.length - 1; 0 <= al; al--) {
            app.activeDocument.activeLayer = obj.artLayers[al];
            relink();
        }
        // Process Layer Set Layers 
        for (var ls = obj.layerSets.length - 1; 0 <= ls; ls--) {
            processAllLayersAndSets(obj.layerSets[ls]);
            relink();
        }
    }

    function relink() {
        if (app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT) {
            // Conditional check for linked SO
            var ref = new ActionReference();
            ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObject"));
            ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
            var so = executeActionGet(ref).getObjectValue(stringIDToTypeID("smartObject"));
            if (so.getBoolean(stringIDToTypeID("linked"))) {
                // Set the file path and name variables
                var thePath = getSmartObjectReference().filePath.toString().replace(/(^.+\/)(.+)/, '$1');
                //alert(thePath);
                var theName = getSmartObjectReference().filePath.fsName.toString().replace(/(^.+?)(_.+)/, '$2');
                //alert(theName);
                var theAD = new ActionDescriptor();
                //alert((thePath + thePrefix + theName));
                // Relink to the new file 
                theAD.putPath(stringIDToTypeID("null"), new File(thePath + thePrefix + theName));
                executeAction(stringIDToTypeID("placedLayerRelinkToFile"), theAD, DialogModes.NO);
            }
        }
    }
}

 

 

 

3 replies

Stephen Marsh
Stephen MarshCorrect answer
Community Expert
April 19, 2024

This "Relink All Smart Object Layers Using New Name Prefix.jsx" variation will process all linked smart object layers found inside layer groups/nested layer groups (not only root/top-level layers):

 

/*
Relink All Smart Object Layers Using New Name Prefix.jsx
(Including layers in groups and nested groups)
v1.0 - 19th April 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-script-replacing-linked-smart-objects-based-on-layer-quot-name-string-quot/td-p/14559920

Note: The case-insensitive colour name prefix replaces the linked file with another file in the same directory with a different colour prefix name -

From: blue_rectangle.psd
      blue_circle.psd

To:   red_rectangle.psd
      red_circle.psd

There is no need to type the underscore _ separator character (although it has to exist in the filename) and the replacement image should have the same resolution and file format as the smart objects
*/

#target photoshop

app.activeDocument.suspendHistory("Relink All Smart Object Layers Using New Name Prefix.jsx", "main()");

function main() {

    // Prompt for the colour prefix
    var thePrefix = prompt("Enter the new linked filename prefix:", "red");
    if (thePrefix === null) {
        //alert('Script cancelled!');
        //app.beep();
        return
    }
    processAllLayersAndSets(app.activeDocument);


    ///// FUNCTIONS /////

    function getSmartObjectReference() {
        // https://stackoverflow.com/questions/63010107/get-a-smart-objects-layers-files-directory-source-in-jsx
        try {
            var smartObject = {
                found: false,
                fileRef: '',
                filePath: '',
                linked: false,
            };
            var ref, so;
            ref = new ActionReference();
            ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObject"));
            ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
            so = executeActionGet(ref).getObjectValue(stringIDToTypeID("smartObject"));
            smartObject.found = true;
            smartObject.linked = so.getBoolean(stringIDToTypeID("linked"));
            smartObject.fileRef = so.getString(stringIDToTypeID("fileReference"));
            if (smartObject.linked) {
                smartObject.filePath = so.getPath(stringIDToTypeID("link"));
            } else {
                smartObject.filePath = Folder.temp + '/' + smartObject.fileRef;
            }
            return smartObject;
        } catch (e) {
            alert(e);
            return smartObject;
        }
    }

    function processAllLayersAndSets(obj) {
        // Process all layers and layer sets
        // Change the following 2 entries of "obj.artLayers" to "obj.layers" to include layer sets
        for (var al = obj.artLayers.length - 1; 0 <= al; al--) {
            app.activeDocument.activeLayer = obj.artLayers[al];
            relink();
        }
        // Process Layer Set Layers 
        for (var ls = obj.layerSets.length - 1; 0 <= ls; ls--) {
            processAllLayersAndSets(obj.layerSets[ls]);
            relink();
        }
    }

    function relink() {
        if (app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT) {
            // Conditional check for linked SO
            var ref = new ActionReference();
            ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObject"));
            ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
            var so = executeActionGet(ref).getObjectValue(stringIDToTypeID("smartObject"));
            if (so.getBoolean(stringIDToTypeID("linked"))) {
                // Set the file path and name variables
                var thePath = getSmartObjectReference().filePath.toString().replace(/(^.+\/)(.+)/, '$1');
                //alert(thePath);
                var theName = getSmartObjectReference().filePath.fsName.toString().replace(/(^.+?)(_.+)/, '$2');
                //alert(theName);
                var theAD = new ActionDescriptor();
                //alert((thePath + thePrefix + theName));
                // Relink to the new file 
                theAD.putPath(stringIDToTypeID("null"), new File(thePath + thePrefix + theName));
                executeAction(stringIDToTypeID("placedLayerRelinkToFile"), theAD, DialogModes.NO);
            }
        }
    }
}

 

 

 

Known Participant
April 19, 2024

First of all, thank you for your reply and attempt at this.

While the script works, I am trying to have it look for instances for a replacement of all smart objects.

example, imagine the folder has "GREEN_CIRCLE", or "PURPLE" CIRCLE, etc. Ideally I would like to 

have the script locate the directory and replace the prefix name along with what type of object it is.

ex:

script would search "red" and identify any object labeled "red" and replace objects based on

the remaining string (_circle, or _square) 

I am going to build a PSD that will have over 20 smart objects, and would like to auto replace in 1 swoop

rather than having to manually select the replacements. so basically all smart objects will have the same ending text, only change would be the text aka red, green, blue, purple, etc etc.

if that is possible of course.

Thank you in advance!

Known Participant
April 25, 2024

apologies, yes the previous script provided works 100%. I was going more into "next level" to see if I could control specific smart objects that share similar string names, but could target even more specificity, in this case, seperating the dogs and cats, i hope that makes sense.


I guess to simplify what I am trying to achieve is this: can I replaceof the 4 smart objects, just the smart objects that say "DOGS" to "PIGS", even if there had to be an extra or modified dialogue box to tell the script which animal to pull, while keeping the end text string the same.

Stephen Marsh
Community Expert
April 19, 2024

@defaulttev3kfc5iehr 

 

You can try the following "Relink Top-Level Smart Object Layers Using New Name Prefix.jsx" script:

 

/*
Relink Top-Level Smart Object Layers Using New Name Prefix.jsx
v1.0 - 19th April 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-script-replacing-linked-smart-objects-based-on-layer-quot-name-string-quot/td-p/14559920

Note: The case-insensitive colour name prefix replaces the linked file with another file in the same directory with a different colour prefix name -

From: blue_rectangle.psd
      blue_circle.psd

To:   red_rectangle.psd
      red_circle.psd

There is no need to type the underscore _ separator character (although it has to exist in the filename) and the replacement image should have the same resolution and file format as the smart objects
*/

#target photoshop

app.activeDocument.suspendHistory("Relink Top-Level Smart Object Layers Using New Name Prefix.jsx", "main()");

function main() {

  (function () {

    try {

      // Prompt for the colour prefix
      var thePrefix = prompt("Enter the new linked filename prefix:", "red");
      if (thePrefix === null) {
        //alert('Script cancelled!');
        //app.beep();
        return
      }

      // Loop over the root/top-level layer (not groups or the content of nested groups)
      for (var i = 0; i < app.activeDocument.artLayers.length; i++) {
        activeDocument.activeLayer = activeDocument.artLayers[i];
        if (app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT) {
          // Conditional check for linked SO
          var ref = new ActionReference();
          ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObject"));
          ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
          var so = executeActionGet(ref).getObjectValue(stringIDToTypeID("smartObject"));
          if (so.getBoolean(stringIDToTypeID("linked"))) {
            // Set the file path and name variables
            var thePath = getSmartObjectReference().filePath.toString().replace(/(^.+\/)(.+)/, '$1');
            var theName = getSmartObjectReference().filePath.fsName.toString().replace(/(^.+?)(_.+)/, '$2');
            var theAD = new ActionDescriptor();
            // Relink to the new file 
            theAD.putPath(stringIDToTypeID("null"), new File(thePath + thePrefix + theName));
            executeAction(stringIDToTypeID("placedLayerRelinkToFile"), theAD, DialogModes.NO);
          }
        }
      }

      // End of script notification
      app.beep();

    } catch (e) {
      alert("Error!" + "\r" + e + ' ' + e.line);
    }


    function getSmartObjectReference() {
      // https://stackoverflow.com/questions/63010107/get-a-smart-objects-layers-files-directory-source-in-jsx
      try {
        var smartObject = {
          found: false,
          fileRef: '',
          filePath: '',
          linked: false,
        };
        var ref, so;
        ref = new ActionReference();
        ref.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObject"));
        ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
        so = executeActionGet(ref).getObjectValue(stringIDToTypeID("smartObject"));
        smartObject.found = true;
        smartObject.linked = so.getBoolean(stringIDToTypeID("linked"));
        smartObject.fileRef = so.getString(stringIDToTypeID("fileReference"));
        if (smartObject.linked) {
          smartObject.filePath = so.getPath(stringIDToTypeID("link"));
        } else {
          smartObject.filePath = Folder.temp + '/' + smartObject.fileRef;
        }
        return smartObject;
      } catch (e) {
        alert(e);
        return smartObject;
      }
    }

  })();

}

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

Stephen Marsh
Community Expert
April 17, 2024

Sample files (low resolution) or at least a screenshot of the layers panel and the properties panel for a selected layer would help others to help you.

Known Participant
April 17, 2024

Hopefully this explains it, simplified the request, basically looking to have a dialogue box open to replace linked smart object instances of the "like" layers. at once instead of having to repeat the process.