I know its possible to convert an action to a uxp script but is it possible to execute a script from a uxp button? At times its more usful to be able to edit the action rather than remake the script everytime.
Thanks
I know its possible to convert an action to a uxp script but is it possible to execute a script from a uxp button? At times its more usful to be able to edit the action rather than remake the script everytime.
Thanks
Do you mean to play an action, or run a JSX script? Yes, either can be done.
I have a UXP plugin that plays actions and there have been no issues at all with that.
You can also play JSX extendscript through UXP. I donât use this in my plugins but I did do some testing. It works fine but for some reason runs at about 1/2 the speed that my JSX extendscripts run when ran natively, not through UXP.
Here is the documentation for playing actions.
https://www.adobe.io/photoshop/uxp/ps_reference/classes/action/
https://www.adobe.io/photoshop/uxp/ps_reference/classes/actionset/
I currently play actions using batchPlay and have a report that if the action contains a script (.jsx), then it wonât play from the plugin. So using APIs to play actions instead of batchPlay may be preferable.
I found this code in the tutorials
const app = require('photoshop').app;
const allActionSets = app.actionTree;
const firstActionSet = allActionSets[0];
let actions = new Map(); // a JS Map allows easy "find by name" operations
firstActionSet.actions.forEach((action) => { actions.set(action.name, action)});
const myAction = actions.get("Wood Frame - 50 pixel");
if (myAction) { // user may have deleted this action
await myAction.play();
}
I assume if i change âWood Frame - 50 pixelsâ to my action name it should then point to my action. I have 2 questions though.
Can anyone help me with this please, i still canât figure out how to play an action from a UXP button.
Iâm sure this isnât the most efficient use of javascript and forgive the longhand⌠but it works.
//Use same ID in HTML doc
document.getElementById("yourButtonID").addEventListener("click", async function (){
await playAction("Your Action Set","Your Action");
});
async function playAction(setName,actionName){
let setFound=false;
let actionFound=false;
const actionSets = require('photoshop').app.actionTree;
// check for action set name to exist
for (let i=0; i<actionSets.length; i++){
if (actionSets[i].name==setName){var setToPlay=actionSets[i]; setFound=true;}
}
//check for action name to exist
if(setFound==true){
for (let i=0; i<setToPlay.actions.length; i++){
if (setToPlay.actions[i].name==actionName){var actionToPlay=setToPlay.actions[i]; actionFound=true;}
}
}
//play if action set/action both exist
if(setFound==true&&actionFound==true){await actionToPlay.play();}
}
Iâm getting an error, i think its because of a â{â at the end of the line âasync function playAction(setName,actionName){â
It doesnât seem to be closed again. Where should the â}â go?
I tried it at the end but the action wouldnât play from the button
What is the exact error?
I must have missed the closing bracket when I copied it from my plusing. I updated the post. It is the exact function I use for multiple plugins and Iâve never had it give an error.
OK, I just updated it again. I missed the last line and the closing bracket when I copied it last time⌠oops.
//Use same ID in HTML doc
document.getElementById("yourButtonID").addEventListener("click", async function (){
await playAction("Your Action Set","Your Action");
});
async function playAction(setName,actionName){
let setFound=false;
let actionFound=false;
const actionSets = require('photoshop').app.actionTree;
// check for action set name to exist
for (let i=0; i<actionSets.length; i++){
if (actionSets[i].name==setName){var setToPlay=actionSets[i]; setFound=true;}
}
//check for action name to exist
if(setFound==true){
for (let i=0; i<setToPlay.actions.length; i++){
if (setToPlay.actions[i].name==actionName){var actionToPlay=setToPlay.actions[i]; actionFound=true;}
}
}
//play if action set/action both exist
if(setFound==true&&actionFound==true){await actionToPlay.play();}
}
Thank you very much, that worked perfectly.
Are all the checks needed? I didnât see any errors or pop ups when i tried to assign an action that didnât exist. I have 50+ actions so less code would be more benficial to me
That is your decision. You can put an else statement in there to prompt an error. In my case, I didnât want it to throw an error and just move on if the action doesnât exist.
Dies this still work in PS 23?
I use the exact code but my action is not played.
The action has no extendedscript adn when I debug it both setFound & actionFound are true before it tries to play it.
I donât think it works in recent Photoshop versions. Iâm pretty sure that UXP scripting is replacing extendscript. So maybe it doesnât work anymore by design⌠not sure.
UXP scripting is still missing many methods which exist in extendedacript but are still missing in UXP.
Even if I wanted to convert my existing CEP plugin to UXP it would be impossible at this stage.
Iâm not sure why it doesnât work anymore. It could be a bug. You would have to ask Adobe on that. I just know it stopped working at least 6 months ago, maybe longer. You canât play an action through UXP containing an extendscript either. One of my plugins plays actions from a Hot Folder. Several of my users were running actions that played scripts. It stopped working for all of them. I donât know if there is anyway to play a script through UXP at all right now. Again, Adobe would have to give an official answer about if it is possible, or if it is a bug or by design.
Interesting! @ddbell Your code actually works well for me. for either run normal actions or a JSX script.
const app = require("photoshop").app;
const batchPlay = require("photoshop").action.batchPlay;
const ExecuteAsModal = require("photoshop").core.executeAsModal;
async function playAction(setName, actionName) {
let setFound = false;
let actionFound = false;
const actionSets = require("photoshop").app.actionTree;
// check for action set name to exist
for (let i = 0; i < actionSets.length; i++) {
if (actionSets[i].name == setName) {
var setToPlay = actionSets[i];
setFound = true;
}
}
//check for action name to exist
if (setFound == true) {
for (let i = 0; i < setToPlay.actions.length; i++) {
if (setToPlay.actions[i].name == actionName) {
var actionToPlay = setToPlay.actions[i];
actionFound = true;
}
}
}
//play if action set/action both exist
if (setFound == true && actionFound == true) {
await actionToPlay.play();
}
}
document
.getElementById("action1")
.addEventListener("click", async function () {
await ExecuteAsModal(() => playAction("Actions set Name", "Action 1"));
});
but I have notice different behaviour based on how I run the JSX.
if I have the JSX play like this
It wonât work And I get this error:
but if I set it to play an action from another set that contain JSX file it works
btw: I am in Photoshop 23.4.1 api 2 manifest 5
That is interesting. However, I donât know if I would trust that workaround to be future-proof. I think JSX is on itâs way out. I have seen things in my JSX scripts stop working on newer PS releases. So even if you get it to play, the doesnât guarantee that the script will work correctly in future PS releases. For myself, I have 1 last JSX program that I am trying to convert to UXP so my collection of plugins will all be JSX-free.
Donât rely on it. This one might require your intervention in the future.
I am doing the same converting all my jsx files. but I still use some of my jsx script because they rely on keyboard shortcuts, I hope we get support for shortcuts soon in UXP.
Hello, I have here a script to run a pre-recorded photoshop action: I use this âRunAction.jsâ script, in combination with another âbuttonConfig.jsonâ file. Here is the RunAction.js script :
const { core, action } = require(âphotoshopâ);
async function actionCommands(actionName, actionSet) {
console.log(Executing actionCommands with actionName: ${actionName}, actionSet: ${actionSet}
);
try {
const result = await core.executeAsModal(async () => {
return await action.batchPlay(
[
{
_obj: "play",
_target: [
{ _ref: "action", _name: actionName },
{ _ref: "actionSet", _name: actionSet }
],
_options: { dialogOptions: "dontDisplay" }
}
],
{}
);
}, { commandName: `Executing ${actionName}` });
console.log("Action executed successfully:", result);
return result;
} catch (err) {
console.error(âError in batchPlay:â, err);
throw err;
}
}
module.exports = { actionCommands };
and here is the buttonConfig.json file :
{
âName_of_Buttonâ: {
âactionâ: âName_of_Actionâ,
âactionSetâ: âName_of_Setâ
}
}