Is it possible to add menu items dynamically from a plugin?

I am trying to develop a plugin that will dynamically add menu items from a plugin, and assign keyboard shortcuts to them using normal InDesign functionality. I expect to be able to add or remove menu items at any given time, not just register them the first time.

Looking at the UxpMenuItems in entrypoints, it seems that insertAt(index, newItem) exists and can be added. Not sure if this will work because cannot find a sample, is this possible? Or do I need to work around this in InDesign’s MenuItems object?

2 Likes

I think I recall from the last developer’s office hours Adobe indicating that this wasn’t yet possible in Adobe InDesign outside of using, as you suggested, Adobe InDesign menu items (which I’ve test within UXP). But I could have confused this with Adobe Photoshop that doesn’t allow access to the main menu bar.

1 Like

That is probably InDesign topic, as no workaround can be found in Photoshop. Thanks for letting me know.

If you need to add a menu item from the UXP script, then this already works. There is only one condition. The script needs to run synchronously.

This UXP script (it works ID 18.5 Win) adds a menu and creates a black rectangle when called.
Create a new document and invoke ‘Menu Item 1’ of menu ‘TEST MENU’.

const { app, LocationOptions } = require(‘indesign’);

await (async () => new Promise ((resolve, reject) => uxpScript()))();

function uxpScript() {
let menu = app.menus.item(0).submenus.add(“TEST MENU”, LocationOptions.AT_END);
let menuAction = app.scriptMenuActions.add({name: “Menu Item 1”});

menuAction.addEventListener(‘beforeDisplay’, (event) => {
event.parent.enabled = app.documents.length > 0;
});
menuAction.addEventListener(‘onInvoke’, (event) => {
app.activeDocument.pages.firstItem().rectangles.add({fillColor: “Black”});
});

menu.menuItems.everyItem().remove();
menu.menuItems.add(menuAction);

}

=======================================
To delete created menu, you can use regular (*.jsx) script:

app.menus.item(0).submenus.itemByName(‘TEST MENU’).remove();

2 Likes

Thanks @Vnh68 nice work there! Thanks for sharing.

Similar to what I do with legacy ExtendScript.