• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

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

Community Beginner ,
Apr 16, 2024 Apr 16, 2024

Copy link to clipboard

Copied

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.

TOPICS
Actions and scripting , Windows

Views

341

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 2 Correct answers

Community Expert , Apr 18, 2024 Apr 18, 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 directo
...

Votes

Translate

Translate
Community Expert , Apr 18, 2024 Apr 18, 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/14
...

Votes

Translate

Translate
Adobe
Community Expert ,
Apr 17, 2024 Apr 17, 2024

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 17, 2024 Apr 17, 2024

Copy link to clipboard

Copied

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.

 

example.jpg

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 18, 2024 Apr 18, 2024

Copy link to clipboard

Copied

@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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 18, 2024 Apr 18, 2024

Copy link to clipboard

Copied

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);
            }
        }
    }
}

 

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 18, 2024 Apr 18, 2024

Copy link to clipboard

Copied

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!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 18, 2024 Apr 18, 2024

Copy link to clipboard

Copied

@defaulttev3kfc5iehr 

 

I understand.

 

I only tested on the Mac. All worked as expected.

 

When I tested on Windows, I found that I had to make a minor correction to handle the file paths in both operating systems.

 

Please try the updated code.

 

Tested on both Mac and Win in 2020, 2021 and 2024.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 18, 2024 Apr 18, 2024

Copy link to clipboard

Copied

Thank you for this, this worked!

curious to know, would this work if the smart objects were on a server and not locally? 

would i have to enter the directory path in the script if that was the case?

(all smart objects live in same directory) 

Thank you again for this!

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 18, 2024 Apr 18, 2024

Copy link to clipboard

Copied

In theory, yes, but I haven't tested the paths so there could be issues, not to mention:

 

https://helpx.adobe.com/photoshop/kb/networks-removable-media-photoshop.html

 

Oops, looks like I mentioned it!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 19, 2024 Apr 19, 2024

Copy link to clipboard

Copied

after doing some more testing, it looks like the main PSD file has to live in the same folder in order to switch the smart objects, I would like to place these smart objects in a subfolder, ( ex: "COLORS_FOLDER")

or even better (ex: "C:\Users\username\project\smartObjects")

I want to keep the main PSD seperate from the linked images.

is there a way to tweak the script to identify the path? even better if I can copy the location and place in the script so that it will always look in that specific directory?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 19, 2024 Apr 19, 2024

Copy link to clipboard

Copied

quote

I want to keep the main PSD seperate from the linked images.


By @defaulttev3kfc5iehr

 

The location of the parent file doesn't matter for the linked file paths, there is no direct relationship between the parent file path and the linked files paths. 

 

The script will relink to the new colour prefix in the same directory as the existing links, as long as the paths are valid and the existing links aren't broken.

 

I have tested on both Mac and Win in different versions with the PSD in a different folder and all works as expected.

 

Do you mean that you wish to select a different folder/path than the current links, without first having to manually relink the existing images to the new folder?

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 23, 2024 Apr 23, 2024

Copy link to clipboard

Copied

So I figured out what was giving me an issue, it does work over various servers,

the only thing I need to take into account is the name has 2 underscores, 

example:

 

red_square

red_circle

red_circle_small   <-- the script stops, and needs to identify every smart object labeled with a third word.

 

is there a way to modify script for variable smart object names beyond the 2 words?

Thank you so much in advance, I really do appreciate this.

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 23, 2024 Apr 23, 2024

Copy link to clipboard

Copied

@defaulttev3kfc5iehr – Yes, the original example only had two words. Change the following regular expression from "greedy":

 

var theName = getSmartObjectReference().filePath.fsName.toString().replace(/(^.+)(_.+)/, '$2');

 

To "lazy":

 

var theName = getSmartObjectReference().filePath.fsName.toString().replace(/(^.+?)(_.+)/, '$2');

 

Which will then handle any amount of words after the first underscore separator.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 24, 2024 Apr 24, 2024

Copy link to clipboard

Copied

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!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 24, 2024 Apr 24, 2024

Copy link to clipboard

Copied

@defaulttev3kfc5iehr – Before talking about another "new feature" (which isn't needed, unless I'm missing something) – let's discuss the previous revision. Does the replacement now work correctly for links with 3 or more words?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 24, 2024 Apr 24, 2024

Copy link to clipboard

Copied

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!

 

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 24, 2024 Apr 24, 2024

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 24, 2024 Apr 24, 2024

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 24, 2024 Apr 24, 2024

Copy link to clipboard

Copied

If there were matching files named with a prefix of pig in the same directory, then the files named dog would be relinked to pig. 


So I'm just not getting it.

 

Rather than looping over all layers, a modified version of the script could work on selected layers or layers within a selected group.

 

But linked layers would update all instances outside of the selected layers if they had matching names.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 24, 2024 Apr 24, 2024

Copy link to clipboard

Copied

Let me see if I can explain this differently.

These are the 4 linked smart objects in the PSD labeled the following:


AWAY_TEAM_NAME.psd

AWAY_TEAM_LOGO.psd

HOME_TEAM_NAME.psd

HOME_TEAM_LOGO.psd

 

I would like to have the script target and replace the 4 Smart Objects based on the first part of the name,


AWAY_TEAM_NAME.psd <-- script replaces this based on the name "AWAY" to "PIGS"

AWAY_TEAM_LOGO.psd <-- same as above

HOME_TEAM_NAME.psd <-- script replaces this based on the name "HOME" to "SLOTHS"

HOME_TEAM_LOGO.psd <-- same as above


** I still want to keep the functionality that looks for the part of the name "_TEAM_NAME" and "_TEAM_LOGO" since I can add an infinite amount
of smart objects as long as they have the same text string that is identified by the "HOME" and "AWAY" portion,

If I needed to create high school sports matchups for example and have a list of multiple teams, it be easier to type out the team name(s) and
replace that way instead of the script replacing "ALL" smart objects.

 

I can rename the default smart object layers to "AWAY_TEAM_NAME" / "AWAY_TEAM_LOGO" and "HOME_TEAM_NAME" / "HOME_TEAM_LOGO"

Again, thank you for your help, I know this can be quite the headache so any help is extremely appreciated.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 25, 2024 Apr 25, 2024

Copy link to clipboard

Copied

So, at the moment you would run the script twice:

 

Once for:

  • AWAY_TEAM_NAME.psd
  • AWAY_TEAM_LOGO.psd

 

Replacing AWAY for PIGS

 

Then a second time for:

  • HOME_TEAM_NAME.psd
  • HOME_TEAM_LOGO.psd

 

Replacing HOME for SLOTHS

 

However, you would like to automate that further? The script would need to find the different name prefixes, and then offer a new prefix to swap out for the replacements.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 25, 2024 Apr 25, 2024

Copy link to clipboard

Copied

LATEST

correct, I can always create a smart object placeholder in the PSD labeled with a prefix "AWAY and HOME" to differentiate between them. So in theory, I could have endless smart objects with various ending text strings as long as the prefix or in this case, the team is all that is being replaced.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines