Put the globe back in Episerver!

In Episerver CMS prior to the UI refresh in Episerver.CMS.UI 11.21.0 we were able to open the current content, and see what our visitors would see, by simply clicking the globe on the toolbar.
oldglobe

The problem

In Episerver.CMS.UI 11.21.0 the globe disappeared! We would first have to click «Options» and then «View on website» to accomplish the same. That is one more click I do not want to do.
newlink

The solution

Luckily it is possible to customize the Episerver UI, once you get rid of the fear of dojo and dijit. Episerver even has some nice documentation.

I created a CustomToolbarProvider with inspiration from this part of the documentation. The Global Toolbar has three areas that you can add commands to; leading, center, and trailing.

//viewonwebsite/CustomToolbarProvider
define([
        "dojo/_base/declare",
        "dijit/form/Button",
        "epi-cms/component/command/_GlobalToolbarCommandProvider",
        "viewonwebsite/ViewOnWebsiteCommand",
        "dojo/topic",
        "dojo/_base/lang"
    ],
    function (declare, Button, _GlobalToolbarCommandProvider, ViewOnWebsiteCommand, topic, lang) {
        return declare([_GlobalToolbarCommandProvider],
            {
                constructor: function () {
                    this.inherited(arguments);
                    this.addToTrailing(new ViewOnWebsiteCommand(), { showLabel: false, widget: Button });
                    topic.subscribe("/epi/shell/context/changed", lang.hitch(this, this._contextChanged));
                },

                // Executes when the context changes, i.e. nodes in the page tree are clicked
                // Show correct icon and tooltip on after context change
                _contextChanged: function (newContext) {
                    if (!newContext) {
                        return;
                    }

                    this.commands[0].set('iconClass', newContext.publicUrl ? "epi-iconWebsite" : "epi-iconLock");
                    this.commands[0].set('label', newContext.publicUrl ? "View on website" : "Content has no URL");
                } 
            });
    }
);

I then subscribe to the ContextChangeEvent. This event fires when the context changes, for example when the editor clicks another page in the page tree. I set a different icon and tooltip if the current content does not have a public URL.

And then added a ViewOnWebSiteCommand with inspiration from the same documentation. I checked the Episerver Front-End Style Guide to find the correct CSS class for the globe icon.

//viewonwebsite/ViewOnWebsiteCommand.js
define([
        "dojo/_base/declare",
        "epi/shell/command/_Command",
        "epi/dependency",
        "dojo/topic"
    ],
    function (declare, _Command, dependency, topic) {
        return declare([_Command],
            {
                name: "ViewOnWebsite",
                iconClass: "epi-iconWebsite",
                canExecute: true,

                // Show correct icon and tooltip on initial page load
                constructor: function () {
                    var contextService = dependency.resolve("epi.shell.ContextService");
                    var currentContext = contextService.currentContext;

                    if (currentContext) {
                        this.set('iconClass', currentContext.publicUrl ? "epi-iconWebsite" : "epi-iconLock");
                        this.set('label', currentContext.publicUrl ? "View on website" : "Content has no URL");
                    }
                },

                // Executes when toolbar button is clicked
                _execute: function () {
                    var contextService = dependency.resolve("epi.shell.ContextService");
                    var currentContext = contextService.currentContext;
                    var publicUrl = currentContext.publicUrl;

                    if (publicUrl) {
                        window.open(publicUrl);
                    }
                }
            });
    }
);

The same logic as happens in the ContextChangeEvent, also has to be done in the constructor, to make sure the correct icon and tooltip are shown on page load.

Then all that is left is calling some initialization and adding a module.config. And the globe is back in all its glory!

newglobe

The full source code is available on GitHub and a NuGet package is available on nuget.org.

Another globe, another problem

When creating the NuGet package, I, of course, wanted the globe icon displayed in Visual Studio too. I was kind of disappointed learning that I had to use the deprecated element iconUrl, instead of the recommended element icon, to make it work in Visual Studio.

globeinvisualstudio