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.
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.
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!
The full source code is available on GitHub and a NuGet package is available on nuget.org and episerver.nuget.com.
If you want to the globe to open the current page in the same tab, use version 0.94.0. If you want the globe to open the current page in a new tab, use version 0.93.0.
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.