Command pluggability
Table of contents
Introduction
With the command pattern and it is consumer and provider architecture we get the ability to add commands to a command consumer. There are the following main scenarios here:
- You want to add a command that is not dependant on a specific model to operate on. For instance a plug-in to the global toolbar to open a dialog.
- You want to add a command that is dependant on a model for its state. For instance a command that plugs into the cms publish menu and operates on the currently selected page.
Plugging in a command
To be able to plug in commands virtually anywhere in the system without having to have a reference to a specific widget instance EPiServer has something called the global command registry. The global command registry is used to map command providers against given keys. This makes it possible to add a command provider that can feed a consumer with command given that the global key matches. The following example shows how to create a command provider that adds the “test” command:
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);
}
});
});
And the following shows the test command:
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 () {
//Here 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);
}
});
});
To add your command provider to a given consumer you need to set this up, for instance in your module initialization (this examples shows to to plug in to the publish menu of EPiServer CMS):
var commandregistry = dependency.resolve("epi.globalcommandregistry");
commandregistry.registerProvider("epi.cms.publishmenu", new MyCommandProvider());
Adding plug-in capabilities for your own classes and widgets
Adding extension functionality for your own widgets can be done by using the "epi/shell/command/_WidgetCommandConsumerMixin" mixin. When using this mixin you need only to define the property commandKey: to a unique key, for instance “samples.mywidgetkey”. This is the key third-party extensions can use to plug into your menu.
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
});
}
});
});
Last updated: Jul 09, 2014