---
title: Plug-in commands
slug: cms-13/docs/plug-in-commands
docTags: 
createdAt: 2026-07-30T20:22:06.232Z
---

The command pattern in Optimizely Content Management System (CMS) encapsulates interface actions into reusable objects. This separates execution logic from concrete widgets into a testable unit.

The consumer and provider architecture lets you add commands to a command consumer. The following examples illustrate two common scenarios:

- Add a command that does not depend on a model, such as a global toolbar plug-in that opens a dialog.
- Add a command that depends on a model for its state, such as a command that plugs into the CMS `publishmenu` and operates on the selected page.

The global command registry maps command providers against keys. This lets you plug in commands without a reference to a specific widget instance.

## Plug in a command

The following example creates a command provider that adds the `Test` command:

```javascript
define([
    "dojo",
    "dojo/_base/declare",
    "epi/shell/command/_CommandProviderMixin",
    "samples/TestCommand"
  ],
  function (dojo, declare, _CommandProviderMixin, TestCommand) {
    return declare([_CommandProviderMixin], {
      constructor: function () {
        this.inherited(arguments);
        var testCommand = new TestCommand();
        this.add("commands", testCommand);
      }
    });
  }
);
```

The following code shows the `Test` command:

```javascript
define([
    "dojo/_base/declare",
    "epi/shell/command/_Command"
  ],
  function (declare, _Command) {
    return declare([_Command], {
      name: "Test",
      label: "Test command",
      tooltip: "Click to execute me",
      iconClass: "", //Define your own icon css class here.
      canExecute: true,

      _execute: function () {
        alert("Name : " + this.model.contentData.name);
      },
      _onModelChange: function () {
        //You can update canExecute depending on the model settings if your command is depending on the model state.
        console.log("New name: " + this.model.contentData.name);
      }
    });
  }
);
```

The following example plugs into the `publishmenu` of CMS. Add this code to a module initializer:

```javascript
var commandregistry = dependency.resolve("epi.globalcommandregistry");
commandregistry.registerProvider("epi.cms.publishmenu", new MyCommandProvider());
```

## Add custom plug-in capabilities

Extend your widgets with plug-in support using the `epi/shell/command/_WidgetCommandConsumerMixin` mixin. Set the `commandKey` property to a unique key, such as `samples.mywidgetkey`. Third-party extensions use this key to plug into the widget menu.

The following example defines a toolbar widget that consumes commands from the global toolbar registry:

```javascript
define("samples.Toolbar",
  [
    // Dojo
    "dojo/_base/array",
    "dojo/_base/lang",
    "dojo/_base/declare",
    "dojo/_base/lang",

    // Dijit
    "dijit/_Widget",
    "dijit/_Container",
    "dijit/form/Button",

    // EPi CMS
    "epi/shell/command/_WidgetCommandConsumerMixin"
  ],
  function (
    // Dojo
    array, lang,
    declare,
    lang,

    // Dijit
    _Widget,
    _Container,
    Button,

    _WidgetCommandConsumerMixin) {
    return declare("samples.Toolbar", [_Widget, _Container, _WidgetCommandConsumerMixin], {
      //Get commands that has been registered to the global toolbar
      commandKey: "epi.cms.globalToolbar",
      onCommandsChanged: function (name, removed, added) {
        //Add a button for each command
        array.forEach(added, lang.hitch(this, function (command) {
          //Create a button and bind onClick to command.execute
          this.addChild(new Button({
            label: command.label,
            onClick: function () {
              command.execute();
            }
          }));
        }));

        array.forEach(removed, function (command) {
          //Remove the commands
        });
      }
    });
  }
);
```
