Copy link to clipboard
Copied
Okay so here's what I need to do. I'd like this to be done with an action (including a custom script) so I can assign a keyboard shortcut to it, but I know next to nothing about scripting in photoshop. I'll be using this on a Mac but "might" also need to use it on a Windows PC in the future. I'll also be using this while I have the file open (in other words I don't need it to pull in files).
1. Firstly, I'll need to run an action that I already have to check spelling and ensure the correct CMYK color profile. I can do this part easily on my own but I need help with the steps below.
2. Secondly, I need to automatically rename the file using the text in a text layer. The text layer name will most likely change to whatever the text in that layer is so I would like this to work by automatically finding that text layer inside a group named "Identifier" instead of finding the layer named "xxxxx".
3. Thirdly, I need to save this file as a layered PSD into a new folder that has the same name as the newly created filename. I would like it to prompt me for where this folder is created but if that isn't possible I'll need it to go to a pre-designated folder location.
4. Fourthly, I'll need it to flatten to a single layer and save as a Photoshop PDF with a specific profile ("John's PDF Profile" for example) to the same folder that was created for the PSD.
Thanks for any help, you are all awesome!
Here is a version 1 script.
This initial version can be used to target a networked or local directory. If this works as intended, the code can be adjusted to save to a local temporary location, then copy the files over the network to the target volume. Baby steps.
Read the comments at the head of the script for options to change the PDF preset name and run your spellcheck/CMYK action.
Let me know how it goes...
/*
Save PSD and PDF versions to subfolder in selected folder.jsx
...
Copy link to clipboard
Copied
You will need a script.
Please post a screenshot of your layers panel, expanding any groups that contain the required layers.
Also, a screenshot of the folder structure on your drive would help.
You can't rename an open file, however, you can:
1) Save a copy with a new name
2) Duplicate the open file with a new name
3) Close the open file and rename it on drive
4) Copy the file on drive to a new location with a new name
Copy link to clipboard
Copied
Sorry, I mean I need to save it with a new name automatically created from the text layer that's in the "Identifier" group.
Attached is the layer panel screenshot. I've marked the location of the text layer that the filename and folder name should come from. Please note that all of the layers will be completely different for each file, the only thing that will remain the same is that there will be a group named "Identifier" and it will have a text layer in it.
As for the folder structure, it's going to look something like:
/ Volumes / Pulse / Composing / Humane Society of the Ouachitas / *Place New Folder Here*
However, I'm planning to use this not only on our current system but to carry it over to a completely new network with a new server that we'll be getting soon. So as long as I can identify the path in the script I assume I'll be able to just edit that part of the script to point where I need it to go on the new system (am I right about that?).
Copy link to clipboard
Copied
Will the text layer always be at the top position in the "Identifier" group?
Will there only be one text layer in this "Identifier" group?
Will the name of the text layer always match the content of the text layer? If not, should the name come from the layer name or the text layer content?
It would be helpful to understand the location of the open file on drive, and how this relates to the new save location.
Also note that Adobe don't recommend opening and more importantly, resaving to a network volume. It's safer to work locally and then copy to the network location.
https://helpx.adobe.com/photoshop/kb/networks-removable-media-photoshop.html
Copy link to clipboard
Copied
Well, beggars can't be choosers, I'll take whatever you suggest. If that's to save it locally and then move it to the server then that will just have to be the way it's done, I'm fine with that. That may even be better in some ways.
Yes, the text layer will always be at the top of that group and it will always be the only text layer in the "Identifier" group.
I believe the name of the text layer will always change to be the same as the content (unless Adobe suddenly changes something so that doesn't automatically happen).
As for where the file previously exists that will be conditional. Sometimes these files will be modifications of a previously designed file and sometimes it will be a completely new file that's never been saved before. In both cases, the saving process will not replace a previously created file.
For further clarification each file will be saved in a client's folder and inside that folder it will be saved in a folder with the same 5-digit alphanumeric name (i.e. A1234) as the filename.
Copy link to clipboard
Copied
So instead of a server location let's say the path is:
/ Users / JohnsComputer / Desktop / Composing Backup /
Copy link to clipboard
Copied
You can have the script prompt you to select a folder. Then the script will copy the locally saved file to that location. There is now enough information to plan and create a script (I think!).
Copy link to clipboard
Copied
Please let me know if you need to know anything else and thank you so much for your help : )
Copy link to clipboard
Copied
OOPS I forgot something.
In the example above I want it to pause at this point:
/ Volumes / Pulse / Composing /
and ask me to choose a subfolder in that directory to create the new folder in.
In this example it would pause for me to choose the " Humane Society of the Ouachitas / " subfolder (or whatever other subfolder) and then create the new folder in that folder.
Copy link to clipboard
Copied
Here is a version 1 script.
This initial version can be used to target a networked or local directory. If this works as intended, the code can be adjusted to save to a local temporary location, then copy the files over the network to the target volume. Baby steps.
Read the comments at the head of the script for options to change the PDF preset name and run your spellcheck/CMYK action.
Let me know how it goes...
/*
Save PSD and PDF versions to subfolder in selected folder.jsx
Stephen Marsh
v1.0 - 22nd November 2024
Info: This script saves both a layered PSD and a flattened PDF version named
after the Identifier group text layer to a selected folder, in a subfolder
named after the Identifier group text layer.
Notes:
* Change the PDF preset name from "Press Quality" to your desired preset
* Optionally uncomment and change the name of the action and action set
*/
#target photoshop;
(function () {
// Check if there's an open document
if (app.documents.length) {
try {
// Run the spellcheck and CMYK profile action (case sensitive)
//app.doAction("My Action", "My Action Set");
// Set the text layer in the "Identifier" layer group
var identifierTextLayer = app.activeDocument.layerSets["Identifier"].layers[0].name;
// Select the output folder
var selectedFolder = Folder.selectDialog("Select the root/top-level output folder:");
if (selectedFolder === null) {
alert('Script cancelled!');
return;
}
// Set the save folder
var outputFolder = new Folder(decodeURI(selectedFolder) + "/" + identifierTextLayer);
if (outputFolder.exists == false) outputFolder.create();
// Save a layered PSD file named after the identifier into a sub-folder named after the identifier
var saveFilePSD = new File(outputFolder + "/" + identifierTextLayer + '.psd');
savePSD(saveFilePSD);
// Save a flattened PDF file named after the identifier into the same folder as the PSD
app.activeDocument.flatten();
var saveFilePDF = new File(outputFolder + "/" + identifierTextLayer + '.pdf');
savePDF(saveFilePDF);
// SaveOptions.PROMPTTOSAVECHANGES | SaveOptions.DONOTSAVECHANGES | SaveOptions.SAVECHANGES
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
} catch (err) {
alert("Error!" + "\r" + err + ' ' + err.line);
}
} else {
alert('A document must be open to run this script!');
}
// Helper functions
function savePSD(saveFile) {
var psdSaveOptions = new PhotoshopSaveOptions();
psdSaveOptions.embedColorProfile = true;
psdSaveOptions.alphaChannels = true;
psdSaveOptions.layers = true;
psdSaveOptions.annotations = true;
psdSaveOptions.spotColors = true;
app.activeDocument.saveAs(saveFile, psdSaveOptions, false, Extension.LOWERCASE);
}
function savePDF(saveFilePath) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
descriptor2.putString(s2t("pdfPresetFilename"), "Press Quality"); // Change the PDF preset as required
descriptor.putObject(s2t("as"), s2t("photoshopPDFFormat"), descriptor2);
descriptor.putPath(s2t("in"), saveFilePath);
descriptor.putBoolean(s2t("copy"), true);
descriptor.putBoolean(s2t("lowerCase"), true);
descriptor.putBoolean(s2t("embedProfiles"), false);
executeAction(s2t("save"), descriptor, DialogModes.NO);
}
}());
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html
Copy link to clipboard
Copied
You are a King among coders! Thank you so much! This is perfect!
I decided to use this as part of an action instead of having the script trigger the actions. I also made one small change by commenting-out the part that closed the file because I decided (after you made the script) that for now I wanted to leave the file open.
Again, this works GREAT, and thank you so so much!
Copy link to clipboard
Copied
I’m glad that you like the script! As saving files to a network volume may result in corruption, I proposed a script that will work on your local drive, then copy the saved files to the network volume. I'll post that shortly as a second option as I have already modified the original script.
Copy link to clipboard
Copied
Here is the updated 1.1 version to copy the locally saved files to the network volume, rather than directly saving them:
/*
Save PSD and PDF versions to subfolder in selected folder 1-1.jsx
Stephen Marsh
v1.0 - 22nd November 2024, Saving to the specified (local or network) volume
v1.1 - 23rd November 2024, Copies from the local drive to the networked volume
Info: This script saves both a layered PSD and a flattened PDF version named
after the Identifier group text layer to a selected folder, in a subfolder
named after the Identifier group text layer.
Notes:
* Change the PDF preset name from "Press Quality" to your desired preset
* Optionally uncomment and change the name of the action and action set
*/
#target photoshop;
(function () {
// Check if there's an open document
if (app.documents.length) {
try {
// Run the spellcheck and CMYK profile action (case sensitive)
//app.doAction("My Action", "My Action Set");
// Set the text layer in the "Identifier" layer group
var identifierTextLayer = app.activeDocument.layerSets["Identifier"].layers[0].name;
// Select the final network volume folder
var selectedFolder = Folder.selectDialog("Select the network volume and folder:");
if (selectedFolder === null) {
alert('Script cancelled!');
return;
}
// Set the local temporary output folder
var tempOutputFolder = new Folder("~/Desktop" + "/" + identifierTextLayer);
if (tempOutputFolder.exists == false) tempOutputFolder.create();
// Save a layered PSD file named after the identifier into a sub-folder named after the identifier
var saveFilePSD = new File(tempOutputFolder + "/" + identifierTextLayer + '.psd');
savePSD(saveFilePSD);
// Save a flattened PDF file named after the identifier into the same folder as the PSD
app.activeDocument.flatten();
var saveFilePDF = new File(tempOutputFolder + "/" + identifierTextLayer + '.pdf');
savePDF(saveFilePDF);
// Copy the local files to the selected network volume/folder and identifier sub-folder
/* https://helpx.adobe.com/photoshop/kb/networks-removable-media-photoshop.html */
try {
var identifierSubFolder = new Folder(selectedFolder + "/" + identifierTextLayer);
if (identifierSubFolder.exists == false) identifierSubFolder.create();
saveFilePSD.copy(identifierSubFolder + "/" + identifierTextLayer + ".psd");
saveFilePDF.copy(identifierSubFolder + "/" + identifierTextLayer + ".pdf");
// Check if files were copied successfully
var copiedPSD = new File(identifierSubFolder + "/" + identifierTextLayer + ".psd");
var copiedPDF = new File(identifierSubFolder + "/" + identifierTextLayer + ".pdf");
if (copiedPSD.exists && copiedPDF.exists) { alert("Local files successfully copied to the network volume!"); }
} catch (err) {
alert("Error copying the local files to the network volume!" + "\r" + err + ' ' + err.line);
}
// Delete the local temporary output files and folder
if (confirm("Are you sure you want to permanently delete the local temporary files and folder?")) {
// First remove the temporary files
saveFilePSD.remove();
saveFilePDF.remove();
// Before removing the empty temporary folder
tempOutputFolder.remove();
}
// SaveOptions.PROMPTTOSAVECHANGES | SaveOptions.DONOTSAVECHANGES | SaveOptions.SAVECHANGES
app.activeDocument.close(SaveOptions.PROMPTTOSAVECHANGES);
} catch (err) {
alert("Error!" + "\r" + err + ' ' + err.line);
}
} else {
alert('A document must be open to run this script!');
}
// Helper functions
function savePSD(saveFile) {
var psdSaveOptions = new PhotoshopSaveOptions();
psdSaveOptions.embedColorProfile = true;
psdSaveOptions.alphaChannels = true;
psdSaveOptions.layers = true;
psdSaveOptions.annotations = true;
psdSaveOptions.spotColors = true;
app.activeDocument.saveAs(saveFile, psdSaveOptions, false, Extension.LOWERCASE);
}
function savePDF(saveFilePath) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
descriptor2.putString(s2t("pdfPresetFilename"), "Press Quality"); // Change the PDF preset as required
descriptor.putObject(s2t("as"), s2t("photoshopPDFFormat"), descriptor2);
descriptor.putPath(s2t("in"), saveFilePath);
descriptor.putBoolean(s2t("copy"), true);
descriptor.putBoolean(s2t("lowerCase"), true);
descriptor.putBoolean(s2t("embedProfiles"), false);
executeAction(s2t("save"), descriptor, DialogModes.NO);
}
}());
Copy link to clipboard
Copied
Hey! Thanks, I'll try that out when I'm back in the office next week.
I do want to mention that in my further testing today I did have an error pop up at one point (maybe it was my 5th use of it or so). I was doing everything exactly the same as prior tests so I don't know what caused it. I tried to take a screenshot of the error but for some reason, the screenshot disappeared into the void. I then had to update a bunch of Adobe apps and try to track down some strange Chrome Extension error that popped up (which I could never figure out), so I didn't get back around to trying to replicate the error and take a better screenshot. The error said something like "General Photoshop Error... something something... unspecified error (84)" or something like that.
Copy link to clipboard
Copied
Yes, a screenshot of the error or a copy/paste of the error message and line number would help. It's a version-specific general message, I am writing and testing the code in v2021 on an Intel Mac. Also testing in v2024, both without issue.
Copy link to clipboard
Copied
This 1.2 version moves the local files to the remote volume using OS specific commands, instead of using the cross-platform ExtendScript copy command:
/*
Save PSD and PDF versions to subfolder in selected folder 1-1.jsx
Stephen Marsh
v1.0 - 22nd November 2024, Saving to the specified (local or network) volume
v1.1 - 23rd November 2024, Copies files from the local drive to the networked volume
v1.2 - 23rd November 2024, Moves files from the local drive to the networked volume
Info: This script saves both a layered PSD and a flattened PDF version named
after the Identifier group text layer to a selected folder, in a subfolder
named after the Identifier group text layer.
Notes:
* Change the PDF preset name from "Press Quality" to your desired preset
* Optionally uncomment and change the name of the action and action set
*/
#target photoshop;
(function () {
// Check if there's an open document
if (app.documents.length) {
try {
// Run the spellcheck and CMYK profile action (case sensitive)
//app.doAction("My Action", "My Action Set");
// Set the text layer in the "Identifier" layer group
var identifierTextLayer = app.activeDocument.layerSets["Identifier"].layers[0].name;
// Select the final network volume folder
var selectedFolder = Folder.selectDialog("Select the network volume and folder:");
if (selectedFolder === null) {
alert('Script cancelled!');
return;
}
// Set the local temporary output folder
var tempOutputFolder = new Folder("~/Desktop" + "/" + identifierTextLayer);
if (tempOutputFolder.exists == false) tempOutputFolder.create();
// Save a layered PSD file named after the identifier into a sub-folder named after the identifier
var saveFilePSD = new File(tempOutputFolder + "/" + identifierTextLayer + '.psd');
savePSD(saveFilePSD);
// Save a flattened PDF file named after the identifier into the same folder as the PSD
app.activeDocument.flatten();
var saveFilePDF = new File(tempOutputFolder + "/" + identifierTextLayer + '.pdf');
savePDF(saveFilePDF);
// Move the local files to the selected network volume/folder and identifier sub-folder
/* https://helpx.adobe.com/photoshop/kb/networks-removable-media-photoshop.html */
var identifierSubFolder = new Folder(selectedFolder + "/" + identifierTextLayer);
if (!identifierSubFolder.exists) identifierSubFolder.create();
// Move PSD file
var fromPSD = saveFilePSD.toString();
var toPSD = identifierSubFolder + "/" + identifierTextLayer + ".psd";
moveFile(fromPSD, toPSD);
// Move PDF file
var fromPDF = saveFilePDF.toString();
var toPDF = identifierSubFolder + "/" + identifierTextLayer + ".pdf";
moveFile(fromPDF, toPDF);
// Check if files were successfully moved
var copiedPSD = new File(identifierSubFolder + "/" + identifierTextLayer + ".psd");
var copiedPDF = new File(identifierSubFolder + "/" + identifierTextLayer + ".pdf");
if (copiedPSD.exists && copiedPDF.exists) {
alert("Local files successfully moved to the network volume!");
// Delete the local temporary folder
tempOutputFolder.remove();
}
// SaveOptions.PROMPTTOSAVECHANGES | SaveOptions.DONOTSAVECHANGES | SaveOptions.SAVECHANGES
app.activeDocument.close(SaveOptions.PROMPTTOSAVECHANGES);
} catch (err) {
alert("Error!" + "\r" + err + ' ' + err.line);
}
} else {
alert('A document must be open to run this script!');
}
// Helper functions
function savePSD(saveFile) {
var psdSaveOptions = new PhotoshopSaveOptions();
psdSaveOptions.embedColorProfile = true;
psdSaveOptions.alphaChannels = true;
psdSaveOptions.layers = true;
psdSaveOptions.annotations = true;
psdSaveOptions.spotColors = true;
app.activeDocument.saveAs(saveFile, psdSaveOptions, false, Extension.LOWERCASE);
}
function savePDF(saveFilePath) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
descriptor2.putString(s2t("pdfPresetFilename"), "Press Quality"); // Change the PDF preset as required
descriptor.putObject(s2t("as"), s2t("photoshopPDFFormat"), descriptor2);
descriptor.putPath(s2t("in"), saveFilePath);
descriptor.putBoolean(s2t("copy"), true);
descriptor.putBoolean(s2t("lowerCase"), true);
descriptor.putBoolean(s2t("embedProfiles"), false);
executeAction(s2t("save"), descriptor, DialogModes.NO);
}
/*
Based on:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/to-move-files-and-folders/td-p/8787869/page/2
by willcampbell7
*/
function moveFile(from, to) {
var command;
var fileFrom = new File(new File(from).fsName);
var fileTo = new File(new File(to).fsName);
if (/%(?!20|5C)/.test(File.encode(fileFrom.fsName))) {
// Unicode characters detected in filename. Move will fail.
return false;
}
if (!fileTo.exists) {
var folderTo = new Folder(fileTo.path);
if (!folderTo.exists) {
folderTo.create();
}
if (File.fs == "Windows") {
command = "move \"" + fileFrom.fsName + "\" \"" + fileTo.fsName + "\"";
app.system(command);
} else if (File.fs == "Macintosh") {
command = "mv \"" + fileFrom.fsName + "\" \"" + fileTo.fsName + "\"";
app.system(command);
}
if (fileTo.exists) {
return true;
}
}
// Failed to move.
return false;
}
}());