Build Business Manager extension cartridges with custom admin tools, menu items, and dialog actions. Use this skill whenever the user needs to create bm_* cartridges, add menu actions or dialog buttons in BM, configure bm_extensions.xml, or extend admin pages with form overlays. Also use when customizing the BM interface for back-office workflows -- even if they just say 'add a button to BM' or 'custom admin page'.
Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
Build Business Manager extension cartridges with custom admin tools, menu items, and dialog actions. Use this skill whenever the user needs to create bm_* cartridges, add menu actions or dialog buttons in BM, configure bm_extensions.xml, or extend admin pages with form overlays. Also use when customizing the BM interface for back-office workflows -- even if they just say 'add a button to BM' or 'custom admin page'.
Business Manager Extensions Skill
This skill guides you through creating Business Manager (BM) extension cartridges to customize the admin interface.
Overview
BM extensions add custom functionality to Business Manager through a single bm_extensions.xml descriptor plus a controller that renders ISML pages:
Extension Type
Purpose
Menu Items
Add a navigation section (a container in the Admin or a site's menu)
Menu Actions
Add a functional link/page under a menu item — wired to a controller node
Dialog Actions
Add buttons to existing BM pages at defined extension points
Form Extensions
Add fields to existing BM search forms (order/customer search)
⚠️ Schema essentials (read first)
These are the most common mistakes. The descriptor uses the bmmodules/2007-12-11 schema (bmext.xsd), not the extensibility/* namespace.
Namespace is http://www.demandware.com/xml/bmmodules/2007-12-11.
name, short_description, and are with a required attribute — NOT attributes and NOT resource keys. Localize by repeating the element per language. There is no attribute.
description
child elements
xml:lang
name="..."
<icon> is a plain string element holding a path (<icon>icons/q.png</icon>), NOT <icon path="..."/>.
position is ascending: lower numbers appear higher in the menu. Core BM items run 2000–12000, so custom items typically use a large number (e.g. 99999) to sit at the bottom, or -1 to float a "Home" action to the top.
The dialog-action extension-point attribute is xp_ref (underscore), and dialog actions link to a menu action via a child <menuactions><menuaction-ref action-id="..."/></menuactions> element — there is no menuaction-ref attribute.
Use the file encoding ISO-8859-1 to match platform samples.
To confirm any detail against the authoritative schema:
bm_my_extension.properties is a standard cartridge marker file:
## cartridge.properties for cartridge bm_my_extension
demandware.cartridges.bm_my_extension.multipleLanguageStorefront=true
demandware.cartridges.bm_my_extension.id=bm_my_extension
Basic bm_extensions.xml
<?xml version="1.0" encoding="ISO-8859-1" ?><extensionsxmlns="http://www.demandware.com/xml/bmmodules/2007-12-11"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.demandware.com/xml/bmmodules/2007-12-11 bmext.xsd"><!-- Menu Item: a container in the Administration menu (site="false") --><menuitemid="acme_id01"position="99999"site="false"><namexml:lang="x-default">ACME Tools</name><short_descriptionxml:lang="x-default">ACME admin tools</short_description><descriptionxml:lang="x-default">Tools and utilities from the ACME team</description><icon>icons/acme.png</icon></menuitem><!-- Menu Action: a page under the menu item, wired to a controller node.
position="-1" floats it to the top of the section. --><menuactionid="acme-home"menupath="acme_id01"position="-1"site="false"><namexml:lang="x-default">Home</name><short_descriptionxml:lang="x-default">ACME Home</short_description><execpipeline="ACME"node="Start"/><sub-pipelines><pipelinename="ACME-Start"/></sub-pipelines><icon>icons/acme.png</icon></menuaction></extensions>
pipeline="ACME" resolves to the controller ACME.js; node="Start" resolves to its exported Start function (which must be marked Start.public = true).
Menu Items
Top-level navigation containers. site="false" places the item in the Administration menu; site="true" (the default) places it in a site menu.
Unique identifier. Prefix to avoid collisions with core BM IDs.
site
No
true
true = site menu, false = Administration menu
position
No
-
Sort order — lower = higher. Use a large value to sit at the bottom.
type
No
BM
BM or CSC (Customer Service Center)
Child elements: name (required, localized), short_description, description (localized), icon (string path), sldsIconName (an SLDS utility icon name, preferred in the modern BM UI), exec.
Menu Actions
Functional pages under a menu item. Wire each to a controller node via <exec> and register every controller node it uses in <sub-pipelines>.
<menuactionid="acme-export"menupath="acme_id01"position="20"site="false"><namexml:lang="x-default">Product Export</name><short_descriptionxml:lang="x-default">Export products to CSV</short_description><execpipeline="ACME"node="Export"/><sub-pipelines><pipelinename="ACME-Export"/><pipelinename="ACME-Download"/></sub-pipelines><parameters><parametername="defaultFormat"value="csv"/></parameters><icon>icons/export.png</icon></menuaction>
Attribute
Required
Default
Description
id
Yes
-
Unique identifier
menupath
No
-
Parent menu item id (or a core BM menu/item id to attach to it)
Note:<exec> takes only pipeline and node (both required) — there is no https attribute. The apis, scapis, and required-features elements in the schema are not supported for custom menu actions.
The NoPermissionCheck idiom
BM checks that the logged-in user has permission for the menu action whose sub-pipelines register the requested controller node. For endpoints that must work without a module permission check — keepalive pings, service workers, polling/AJAX endpoints called by your page's JavaScript — register their nodes under a dedicated action with the reserved id NoPermissionCheck and no <exec>:
<menuactionid="NoPermissionCheck"site="false"><namexml:lang="x-default">Dummy</name><short_descriptionxml:lang="x-default">Holds pipelines that do not require a permission check</short_description><sub-pipelines><pipelinename="ACME-Keepalive"/><pipelinename="ACME-ServiceWorker"/><pipelinename="ACME-Poll"/></sub-pipelines></menuaction>
Without this, those nodes 403 for users who haven't been granted the module. Only register nodes here that are genuinely safe to expose to any authenticated BM user.
Dialog Actions
Add buttons to existing BM pages at a named extension point (xp_ref).
Child elements: name (optional, localized), exec (required), parameters, menuactions (one or more <menuaction-ref action-id="..."/> linking to the menu action that owns the permission check). Dialog actions do not take an icon child.
Common extension points: OrderPage-OrderDetails, ProductPage-General, ProductPage-Images, CustomerPage-Profile, ContentPage-General, CatalogPage-CategoryGeneral.
Form Extensions
Add fields to existing BM search forms (e.g. order or customer search).
id matches the target form (e.g. order-search, customer-search). valueinput requires type (string, int, or double) and name; defaultvalue is optional. Each valueinput has localized <label> children and optional <option> children for dropdowns.
Controller Example
Controllers live in controllers/ and export functions marked .public = true. Use */cartridge/... requires so logic can be shared, and gate page nodes on the BM session.
'use strict';
varISML = require('dw/template/ISML');
varURLUtils = require('dw/web/URLUtils');
varLogger = require('dw/system/Logger');
var log = Logger.getLogger('bm', 'ACME');
/**
* Render the dashboard. Wired to <exec pipeline="ACME" node="Start"/>.
*/functionStart() {
// BM nodes should only be reachable in an authenticated BM sessionif (!session.userAuthenticated) {
response.setStatus(403);
return;
}
ISML.renderTemplate('extensions/acme/dashboard', {
stats: getStats()
});
}
Start.public = true;
module.exports.Start = Start;
/**
* Process an action, then redirect back to the dashboard.
*/functionProcess() {
var action = request.httpParameterMap.action.stringValue;
try {
performAction(action);
response.redirect(URLUtils.url('ACME-Start', 'message', 'Done'));
} catch (e) {
log.error('Action failed: {0}', e.message);
response.redirect(URLUtils.url('ACME-Start', 'error', e.message));
}
}
Process.public = true;
module.exports.Process = Process;
/**
* Lightweight endpoint called by page JS — registered under NoPermissionCheck.
*/functionKeepalive() {
response.setContentType('application/json');
response.writer.print('{"ok":true}');
}
Keepalive.public = true;
module.exports.Keepalive = Keepalive;
Every node referenced by <exec> or <sub-pipelines> must be exported and .public = true, or BM returns 403.
Template Example
BM templates render under templates/default/extensions/. Reference the node via URLUtils.url('Controller-Node', ...).
Decorating with application/MenuFrame (and including inc/Modules) gives the page the standard BM chrome. A plain HTML document also works if you want a fully custom page (the modern qlabs-style approach mounts a single-page app into a container template).
Attaching to Existing BM Menus
Instead of a new menu item, point a menu action's menupath at a core BM menu id. The full list of core ids is in the reference; the most useful: