Few weeks ago I described how to extend Tools menu with additional Move to trash command. Trash button was displayed only for News pages. For all other page types button was not displayed. What if we need to show the button also on the Article type? We could add another hardcoded Page Type condition to dojo component. It will work but it sounds like a fragile solution. It would be better to store all supported types on the server and send serialized settings to the client module.
To prepare server configuration we need to set backend type in modile.config file. Type is the attribute of “module” node. It should be full type name with assembly (AlloyTest.TrashButtonModule, AlloyTest).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="utf-8" ?> <module type="AlloyTest.TrashButtonModule, AlloyTest"> <clientResources> <add dependency="epi-cms.widgets.base" path="scripts/commandsInitializer.js" resourceType="Script" /> </clientResources> <clientModule initializer="additionalTrashButton.commandsInitializer"> <moduleDependencies> <add dependency="CMS" type="RunAfter" /> </moduleDependencies> </clientModule> <dojo> <paths> <add name="additionalTrashButton" path="scripts" /> </paths> </dojo> </module> |
TrashModuleButton have to extend EPiServer.Shell.Modules.ShellModule class. To return custom configuration from module we need to override CreateViewModel method and return custom viewmodel instance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
using System.Collections.Generic; using System.Linq; using System.Web.Hosting; using ContentAreaWithPreview.Models.Pages; using EPiServer.DataAbstraction; using EPiServer.Framework.TypeScanner; using EPiServer.Framework.Web.Resources; using EPiServer.ServiceLocation; using EPiServer.Shell.Modules; namespace AlloyTest { public class TrashButtonModule : EPiServer.Shell.Modules.ShellModule { public TrashButtonModule(string name, string routeBasePath, string resourceBasePath) : base(name, routeBasePath, resourceBasePath) { } public TrashButtonModule(string name, string routeBasePath, string resourceBasePath, ITypeScannerLookup typeScannerLookup, VirtualPathProvider virtualPathProvider) : base(name, routeBasePath, resourceBasePath, typeScannerLookup, virtualPathProvider) { } public override ModuleViewModel CreateViewModel(ModuleTable moduleTable, IClientResourceService clientResourceService) { var trashButtonViewModel = new TrashButtonViewModel(this, clientResourceService); var contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>(); var contentTypes = contentTypeRepository.List().ToList(); var articlePageType = contentTypes.Single(c => c.ModelType == typeof (ArticlePage)).Name; var newsPageType = contentTypes.Single(c => c.ModelType == typeof (NewsPage)).Name; trashButtonViewModel.AllowedTrashButtonTypes = new List<string> { articleModelType, testPageModelType }; return trashButtonViewModel; } } } |
TrashButtonViewModel have to inherit from ModuleViewModel. It contains one custom setting property AllowedTrashButtonTypes. The list is used to store all content types for which additional trash button should be visible. Serialized parameters are passed directly to system client Bootstrapper and then to the to module constructors.
1 2 3 4 5 6 7 8 9 |
public class TrashButtonViewModel : ModuleViewModel { public TrashButtonViewModel(ShellModule module, IClientResourceService clientResourceService) : base(module, clientResourceService) { } public IEnumerable<string> AllowedTrashButtonTypes { get; set; } } |
The allowedAdditionalTrashButtonTypes setting is assigned to the private field and then used in CommandsProvider.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
define([ "dojo", "dojo/_base/declare", "epi/dependency", "epi/routes", "additionalTrashButton/commandsProvider" ], function ( dojo, declare, dependency, routes, CommandsProvider ) { return declare([], { allowedAdditionalTrashButtonTypes: [], constructor: function(settings) { this.inherited(arguments); this.allowedAdditionalTrashButtonTypes = settings.allowedAdditionalTrashButtonTypes; }, initialize: function () { this.inherited(arguments); var commandsProvider = new CommandsProvider({ allowedAdditionalTrashButtonTypes: this.allowedAdditionalTrashButtonTypes }); var commandregistry = dependency.resolve("epi.globalcommandregistry"); var area = "epi.cms.contentdetailsmenu"; //var area = "epi.cms.publishmenu"; commandregistry.registerProvider(area, commandsProvider); } }); }); |
In the command provider allowedAdditionalTrashButtonTypes setting is used to control isAvailable property of Move to Trash command. The command is displayed only if type is listed in the property.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
define([ "dojo", "dojo/_base/declare", "dojo/_base/array", "epi/dependency", "epi/shell/command/_CommandProviderMixin", "epi/shell/ClipboardManager", "epi/shell/selection", "epi-cms/widget/ContentTreeStoreModel", "epi-cms/widget/ContentTreeModelConfirmation", "epi-cms/command/DeleteContent" ], function ( dojo, declare, array, dependency, _CommandProviderMixin, ClipboardManager, Selection, ContentTreeStoreModel, ContentTreeModelConfirmation, DeleteContent ) { return declare([_CommandProviderMixin], { constructor: function() { this.inherited(arguments); this._clipboardManager = new ClipboardManager(); this._selection = new Selection(); this._settings = { //category: "context", model: new ContentTreeModelConfirmation(new ContentTreeStoreModel()), clipboard: this._clipboardManager, selection: this._selection }; this._deleteCommand = new DeleteContent(this._settings); this.add("commands", this._deleteCommand); }, updateCommandModel: function (content) { if (array.indexOf(this.allowedAdditionalTrashButtonTypes, content.contentData.properties.pageTypeName) < 0) { this._deleteCommand.set("isAvailable", false); return; } var selected = [{ type: "epi.cms.contentdata", data: content.contentData }]; this._selection.set("data", selected); this._deleteCommand.set("isAvailable", true); } }); }); |