Add custom icon to Episerver toolbar

Vote:
 

I would really like to get the globe back, to be able to «view on website» with one single click.

I guess it should be possible to add a button like this, getting the url from the link «view on website».

Example: https://imgshare.io/image/globe.vA9aq


If I were able to call the following javascript when the UI is fully loaded, it would work. Running the javascript from the browser's console puts the globe back in place.

var url = document.querySelectorAll('[data-dojo-attach-point="lastPublishedViewLinkNode"]')[0].href;

$('.dijit.epi-globalToolbar.dijitToolbar').find('.epi-toolbarTrailing').prepend('<a href="' + url + '" target="_blank"><span class="epi-iconWebsite">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></a>')

Any suggestions?

#208378
Edited, Oct 22, 2019 18:10
Vote:
 

Have you tried that with adding ClientResources script file? That may help in bringing back Globe icon. :)

#208459
Oct 24, 2019 13:16
Vote:
 

I managed to bring the globe back, but the link href does not get updated when I select another page from the page tree. Clicking the globe always open the start page...until I refresh the page.

#208476
Edited, Oct 24, 2019 16:22
Vote:
 

So, in that case we will need to find a way to bind js event that will update url. Let's do more research than 😎

#208487
Oct 24, 2019 19:47
Vote:
 

I managed to get something working. Now I've got this button, that opens the page in a new browser tab.

https://imgshare.io/image/globe.vevKl

I got some inspiration from this: https://world.episerver.com/documentation/developer-guides/CMS/user-interface/command-pattern/Plugging-in-commands/

I still get the URL from the «Options --> view on website»-link. A little hackish.

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

                _execute: function () {
                    var url = document.querySelectorAll('[data-dojo-attach-point="lastPublishedViewLinkNode"]')[0].href;
                    window.open(url);
                }
            });
    }
);

Then add a button to the global toolbar:

//alloy/CustomToolbarProvider
define([
        "dojo/_base/declare",
        "dijit/form/Button",

        "epi-cms/component/command/_GlobalToolbarCommandProvider",
        "alloy/ViewOnWebsiteCommand"
    ],
    function (declare, Button, _GlobalToolbarCommandProvider, ViewOnWebsiteCommand) {
        return declare([_GlobalToolbarCommandProvider],
            {
                constructor: function () {
                    this.inherited(arguments);

                    this.addToTrailing(new ViewOnWebsiteCommand(
                            { label: "View on website" }),
                            { showLabel: true, widget: Button });
                }
            });
    }
);

And kick it all off in an initializer:

//alloy/Initializer.js
define([
    'dojo/_base/declare',
    "epi/dependency",
    "alloy/CustomToolbarProvider"
], function (declare, dependency, CustomToolbarProvider) {
    return declare(null, {
        initialize: function () {
            var commandregistry = dependency.resolve("epi.globalcommandregistry");
            //The first parameter is the "area" that your provider should add commands to
            //For the global toolbar the area is "epi.cms.globalToolbar"
            commandregistry.registerProvider("epi.cms.globalToolbar", new CustomToolbarProvider());
        }
    });
});

And the initializer, is of courde referenced in module.config:

    <clientModule initializer="alloy.Initializer">
      <moduleDependencies>
        <add dependency="CMS" type="RunAfter" />
      </moduleDependencies>
    </clientModule>

    <dojo>
        <paths>
            <add name="alloy" path="Scripts" />
        </paths>
    </dojo>

It kinda works, but I'm not 100% satisfied. I would prefer:

- A link (<a href) that can be clicked, right-clicked. Makes it possible to open in the same tab, open in other tab, open in other window etc.
- Getting the  url of the current page in some way better
- Disabling the button when no URL is available (container page, page not created in current language etc)

Any suggestions for improvements...?

I guess I should hook into the event that fires when a node in the PageNavigationTree is clicked. I'm not sure how to do that, though.

#208488
Edited, Oct 24, 2019 21:36
Vote:
 

I found this: https://world.episerver.com/documentation/developer-guides/CMS/user-interface/Context-sensitive-components/

And changed the Initializer to this, in order to subscribe to the ContextChangeEvent, and I get an alert with the correct URL when I click a node in the page tree.

//alloy/Initializer.js
define([
    'dojo/_base/declare',
    "epi/dependency",
    "alloy/CustomToolbarProvider",
    "dojo/topic"
], function (declare, dependency, CustomToolbarProvider, topic) {
    return declare(null, {
        initialize: function () {
            var commandregistry = dependency.resolve("epi.globalcommandregistry");
            //The first parameter is the "area" that your provider should add commands to
            //For the global toolbar the area is "epi.cms.globalToolbar"
            commandregistry.registerProvider("epi.cms.globalToolbar", new CustomToolbarProvider());

            topic.subscribe("/epi/shell/context/changed", this._contextChanged);
        },
        _contextChanged: function (newContext) {
            if (!newContext) {
                return;
            }
            alert(newContext.publicUrl);
        }
    });
});

I'm not really sure how to update the link target on my toolbar button...

#208490
Edited, Oct 24, 2019 22:01
Vote:
 

I can move the subscription to the command. To be able to have a functional link before the first event is triggered (on page load, before first click in page tree), I get the current context in the constructor.

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

                constructor: function () {
                    var contextService = dependency.resolve("epi.shell.ContextService");
                    var currentContext = contextService.currentContext;
                    viewOnWebsite = currentContext.publicUrl;

                    topic.subscribe("/epi/shell/context/changed", this._contextChanged);
                },

                _execute: function () {
                    window.open(viewOnWebsite);
                },

                _contextChanged: function (newContext) {
                    if (!newContext) {
                        return;
                    }
                    viewOnWebsite = newContext.publicUrl;
                }
            });
    }
);

The variable viewOnWebsite (that contains the URL) is global now? How should I encapsulate that?

#208492
Edited, Oct 24, 2019 22:38
Vote:
 

I figured it out. Will post solution, once it's a bit more polished.

#208509
Oct 25, 2019 11:10
Vote:
 

I got the globe-button added to the toolbar. 

Short blog post, including a link to github repo, with full source code, and package up on nuget.org:
https://blog.novacare.no/put-the-globe-back-in-episerver/

If anyone could tell me how to be able to hide the globe, instead of change the icon, when publicUrl is null - I would greatly appreciate it!
(I'm having a hard time trying to understand all that dojo stuff)

#208597
Edited, Oct 28, 2019 18:00
Praful Jangid - Oct 29, 2019 11:14
Appreciate your efforts. I will try personally and leave some feedback.
Thanks
Vote:
 

Great post Tom.

#208600
Oct 28, 2019 17:45
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.