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
Community Expert
Stephen MarshCommunity ExpertCorrect 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!

Stephen Marsh
Community Expert
Community Expert
April 25, 2024

thank you for the above script, one more caveot I had a thought about, is there a way to differentiate the smart objects so that way only a specific layer(s) will be swaped based on the layer name?

example:

DOGS_TEAM_NAME.psd

DOGS_TEAM_LOGO.psd

CATS_TEAM_NAME.psd

CATS_TEAM_LOGO.psd

 

Currently the script would replace every logo in this example.

Is there a way to target in this case, just the "DOGS" name portion and not have it change the "CATS"?

(attached a visual reference) 
Thanks!


quote

thank you for the above script, one more caveot I had a thought about, is there a way to differentiate the smart objects so that way only a specific layer(s) will be swaped based on the layer name?

example:

DOGS_TEAM_NAME.psd

DOGS_TEAM_LOGO.psd

CATS_TEAM_NAME.psd

CATS_TEAM_LOGO.psd

 

Currently the script would replace every logo in this example.

Is there a way to target in this case, just the "DOGS" name portion and not have it change the "CATS"?

(attached a visual reference) 
Thanks!


By @defaulttev3kfc5iehr

 

I'm not understanding... The script prompts for the prefix to change.

 

In your original example, red to blue.

 

There should be no reason why dogs to cats would be any different.

 

If you changed dogs to cats, then only two of the four layers would update.

 

From:

 

DOGS_TEAM_NAME.psd

DOGS_TEAM_LOGO.psd

CATS_TEAM_NAME.psd

CATS_TEAM_LOGO.psd

 

This should result in:

 

CATS_TEAM_NAME.psd

CATS_TEAM_LOGO.psd

CATS_TEAM_NAME.psd

CATS_TEAM_LOGO.psd

 

Yes, there are now 2 duplicate links, this is what you asked for when replacing the prefix isn't it?

 

Sorry if I'm blinded by the obvious!

 

 

 

Stephen Marsh
Community Expert
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
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.