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.
2 Correct answers
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
...
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
...
Explore related tutorials & articles
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.
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.
Copy link to clipboard
Copied
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
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);
}
}
}
}
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!
Copy link to clipboard
Copied
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.
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!
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!
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?
Copy link to clipboard
Copied
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?
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.
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.
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!
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?
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!
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!
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.
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.
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.
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.
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.
Copy link to clipboard
Copied
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.

