Hooking to a page dojo widget inside EPiServer TinyMCE link


Hooking to a page dojo widget inside EPiServer TinyMCE link

Hooking to a page dojo widget inside EPiServer TinyMCE link


OBSOLETE, please read the same idea - revisited.

This post assumes you have read Extending of Episerver link inside the TinyMCE to support anchors.

Getting started

The way I started was taking the original code for the TinyMCE link and trying to rewrite pieces of code. The first part, setting and getting anchor from and to HTML markup was the easy part and is explained here.

Fetching the Page widget

What this code already contained was hooking to on fieldCreated event for the linkEditor:

    linkEditor.on("fieldCreated", function (fieldname, widget) {})

The function accepts a fieldname (which is a widget name and it can be href, anchorOnPage, etc. - these are the properties defined by ExtendedEPiLinkModel). However, href contains any of what is defined inside Link model:

  • Page
  • Email
  • External link
  • Anchor (not the one we need though -> this one is populated only with the anchors found inside the XHtmlString we are currently editing).

This is the reason why I couldn't render our anchor bellow the Page widget (which would certainly be clearer for the editor) without further code changes. In case this needs to be achieved, LinkEditorDescriptor needs to be rewritten as well and a different editor descriptor needs to be referenced in ExtendedEPiLinkModel.

But, let's go back to fetching the page widget. To get it, the code bellow is used:

    var getPageWidget = function (widgetList) {
        return array.filter(widgetList, function (wrapper) {
            return "Page" == wrapper.name || "Sida" == wrapper.name;

As you can see, unfortunately, the wrapper name is localized. So, in case you have languages other than English and Swedish, you will need to add them to the equation or figure out a better way of comparing a wrapper name. See forum post here.

Hook to Page widget onChange event

Now, this is the core part. After you get the page widget, you need to connect to its onChange event. In order to use dojo.connect, an include in the definition is needed ("dojo/_base/connect").

    var pageWidget = getPageWidget(wrappers);

    if (pageWidget && pageWidget.length > 0) {
        var inputWidget = pageWidget[0].inputWidget;

        dojo.connect(inputWidget, "onChange", dojo.partial(pageSelected, anchorOnPageWidget));

where anchorOnPageWidget is previously set when a fieldname in on fieldCreated event was anchorOnPage.

In pageSelected method, you will get a pageId (which might be with a version) and from there you can develop any logic that suits you. What I do is forward the param to a webapi controller and get text/value pairs for the dropdown. You can see the pageSelected method in editor_plugin.js.

An example of fetching the anchors can be seen in AnchorService. (In our project, anchors are created from page Heading and each block Heading). You could as well use HtmlAgilityPack and select all anchors from any XHtmlString fields or add custom logic.

Next challenge

Unfortunately, the code cannot be reused for links in LinkItemCollection. While it's easy to add AnchorOnPage field to each link in LinkItemCollection, fetching the Page widget is equally challenging. So, let's head to that!