Views: 6595
Number of votes: 6
Average rating:

Taking control of the EPiServer 7 user interface

The design of the user interface in EPiServer 7 has been primarily targeted toward editors and publishes. Meaning that a lot of the more advanced functionality has been hidden from the main view. Dynamic Properties is one of these pieces of functionality that has been hidden.

From my time working with previous versions of EPiServer at a partner company, I know that dynamic properties can be used quite often. So to make your lives as developers or system admins easier I’ve created a nice little plugin that will add a button to the main toolbar in edit mode. The button will display the dynamic properties edit view in the main content area of edit mode when clicked. The nice thing about this scenario is that it lets me demonstrate a couple of ways that you too can customize edit mode!

The Command

In EPiServer 7 we use a command pattern to back the visual elements in the user interface. This allows us to separate the functional concerns of a command from the visual representation. Here is the code for the edit dynamic properties command:

define([
    // General application modules
    'dojo/_base/declare', 'dojo/_base/lang', 'dojo/topic', 'epi/cms/contentediting/ContentActionSupport',
    // Parent classes
    'epi/shell/command/_Command', 'epi/cms/_ContentContextMixin',
    // Resources
    'epi/i18n!epi/nls/addon.dynamicproperties'
], function(declare, lang, topic, ContentActionSupport, _Command, _ContentContextMixin, resources) {
 
    // module:
    //        addon/command/EditDynamicProperties
    // summary:
    //        Displays the edit dynamic properties view in the main edit area when executed. Also listens
    //        for context changes in order to update whether it can execute.
    return declare([_Command, _ContentContextMixin], {
 
        // label: [public] String
        //        The action text of the command to be used in visual elements.
        label: resources.label,
 
        // tooltip: [public] String
        //        The description text of the command to be used in visual elements.
        tooltip: resources.tooltip,
 
        // iconClass: [public] String
        //        The icon class of the command to be used in visual elements.
        iconClass: 'dijitNoIcon',
 
        contentContextChanged: function() {
            // summary:
            //        Set the command's model to the new current content.
            // tags:
            //        protected
            this.getCurrentContent().then(lang.hitch(this, 'set', 'model'));
        },
 
        _execute: function() {
            // summary:
            //        Publishes a change view topic to switch to the dynamic properties view for the current model.
            // tags:
            //        protected
            topic.publish('/epi/shell/action/changeview', 'addon/view/DynamicProperties', null, this.model);
        },
 
        _onModelChange: function() {
            // summary:
            //        Updates canExecute after the model has been updated. Set to true if the current content is
            //        a page and the current user has the administer access level; otherwise false.
            // tags:
            //        protected
            var model = this.model,
                canExecute = model && model.capabilities.isPage && ContentActionSupport.hasAccess(model.accessMask, ContentActionSupport.accessLevel.Administer);
 
            this.set('canExecute', canExecute);
        }
    });
});

As you can see the only things that related to the user interface are the properties: label, tooltip, and icon class.

Here you can also see the first method for taking control of the user interface. In the _execute method we publish a topic which tells the main view to display the widget that we pass through; in this case the addon/view/DynamicProperties widget. We also pass through the model as a parameter to be set on the view since this contains the information about the current page.

Localization

You might have noticed that the label and tooltip properties are having their values set from a resource file. This resource file is using the standard EPiServer localization service with the translations coming from a XML file as usual. To use localization in JavaScript we use a special plugin module. This module takes a parameter which is defined after the ! character. In this case the parameter is epi/nls/addon.dynamicproperties. This parameter is parsed server side; the first part indicates that EPiServer will handle this language resource, the second part indicates that this is a language resource request, and the third part is the usual dot separated path to the localization in the XML file.

The View

The view that we’re going to display basically just wraps an iframe. This is because I’m not creating a new edit view for dynamic properties but rather just display the legacy one in the main content area.

define([
    // General application modules
    'dojo/_base/declare', 'epi/routes',
    // Parent classes
    'epi/shell/widget/Iframe'
], function(declare, routes, Iframe) {
 
    // module:
    //        addon/view/DynamicProperties
    // summary:
    //        Displays the legacy dynamic properties edit view for the current page.
    return declare([Iframe], {
 
        // baseUrl: [public] String
        //        The base URL to the edit dynamic properties page.
        baseUrl: null,
 
        constructor: function() {
            // summary:
            //        Construct the dynamic properties view and set the base URL.
            // tags:
            //        public
            this.baseUrl = routes.getActionPath({
                path: 'Edit/EditDynProp.aspx',
                moduleArea: 'LegacyCMS'
            });
        },
 
        updateView: function(data) {
            // summary:
            //        Load a new view in the iframe using the base URL and the current page's content link.
            // tags:
            //        public
            this.load(this.baseUrl, {
                query: {
                    id: data.contentLink
                }
            });
        }
    });
});

So all this really does is get the base URL to the legacy edit dynamic properties view and then append the current page ID to the end as a query parameter.

Getting the Command into the Main Toolbar

So now for the next method for taking control of the user interface. While not simple, it is possible to plug into the main toolbar. But first a little explanation.

EPiServer 7 uses a provider and consumer pattern for passing commands around the interface. This allows, for example, a component to say that it provides commands without having to be concerned about where the commands are consumed or how they are displayed. In this example the component toolbar is a consumer and will automatically take those commands and display them how they should be displayed in a toolbar.

So in the global toolbar case, the toolbar is a consumer and it consumes commands that are registered in a named global provider. So we need to add our command to this named provider.

require(['dojo/aspect', 'epi/dependency', 'addon/command/EditDynamicProperties'], function(aspect, dependency, EditDynamicProperties) {
 
    // summary:
    //        Initialize the addon by registering the command in the global toolbar.
    var handle,
 
        key = 'epi.cms.globalToolbar',
 
        registry = dependency.resolve('epi.globalcommandregistry'),
 
        callback = function(identifier, provider) {
            if(identifier !== key) {
                return;
            }
 
            // When the command provider for the global toolbar is registered add our additional command.
            provider.addCommand(new EditDynamicProperties(), {
                showLabel: true
            });
 
            // Remove the aspect handle.
            handle.remove();
        };
 
    // Listen for when the global toolbar command provider is registered in the command provider registry.
    handle = aspect.after(registry, 'registerProvider', callback, true);
});

Here we have a small initialization script that will hook into the provider registration method and when the global toolbar provider is registered we’ll add our command.

How It Looks

This is the button in the toolbar

This is the edit dynamic properties view

To make your life easier, I’ve packaged this as an add-on which you can manually upload and install on your site if you want to try it out or you can just extract it to see the code.

Download

    (By Per Nergård , 07 December 2012 12:12, Permanent link)

    Excellent! I had been thinking of doing a plugin to get a tab in forms mode but this is much better!

    (By kayvan shaabani , 04 January 2013 18:23, Permanent link)

    Thanks Ben

    I have a simple requirement which I'm not sure if I need (if its possible) to create a new editor using Dojo.

    The requirement is to have a property of type "PageReference" which should be set by only pages of a specific page type (i.e. AuthorPageType).

    I need to retain the Episerver's nice default PageRefrence editor, but just filter the pages in tree view based on specific ones, so the user only select the right ones.

    Is this requirement something somewhere in the SDK which I cannot see or I need to do extra work?

    Thanks
    Kayvan

    (By Christian Lindeberg , 19 June 2013 10:14, Permanent link)

    I cant get it to work with 7.1 and patch 3. I have tried your solution here:
    http://world.episerver.com/Blogs/Ben-McKernan/Dates/2013/4/Changes-to-the-moduleconfig-for-EPiServer-71/

    but no luck.

    (By Ben McKernan , 19 June 2013 14:19, Permanent link)

    Hey Christian, I haven't tried this in EPiServer 7.1 but I imagine the only difference would be that all the "epi/cms" references in the define should be changed to use the new dash namespace. e.g. "epi-cms/_ContentContextMixin". If you need more help you can create a thread on the forum as that is a better medium for answering these kind of questions.

    (By Andreas Ljungström , 30 September 2013 16:17, Permanent link)

    The button disapears some times for me, any guess to why that is?

    (By Andreas Ljungström , 30 September 2013 16:51, Permanent link)

    Actually... nevermind my last post. Realized that I hadn't changed from epi/cms to epi-cms on all places

    (By Danie de Kock , 11 June 2014 16:35, Permanent link)

    Hello, I've installed your addon and updated the epi/cms references to epi-cms. But I can't get the button to show. Is there anything else that needs to be done?

    (By Kenia Gonzalez , 23 December 2016 13:29, Permanent link)

    Thanks for a great post!

  Please login to post a comment