Share

LinkedIn

Customizing Sitecore’s Rich Text Editor Dialogs [video interview]

One of my cohorts recently posed a great question: How hard would it be to customize the hyperlink manager dialog in Sitecore’s rich text editor?

While there is a well established protocol for creating a completely custom dialog, customizing one of the built-in dialogs was not something I had seen before.  Of course, I couldn’t let the question go unanswered.

Video 1 - Overview: Customizing Sitecore’s Hyperlink Manager


Video 2 – Bonus! Customizing the Hyperlink Manger for Google Analytics Event Tracking

Initially, it seemed that it would be rather difficult to customize those dialogs.  The dialogs consist of window chrome wrapped around an iframe.  The page hosted in the iframe is actually an HTTP handler that dynamically loads the appropriate controls based on query string parameters that are passed to it.  The control classes and even the user controls that define the markup of the dialogs are embedded in the assembly.

Wait… User controls?  Why would they use user controls unless they wanted to let you modify the markup?  A little Googling reveals that, normally, the RadEditor is shipped with a folder full of user controls.  Unfortunately, Sitecore decided not to include those files with their product.  So, once again, it’s Reflector to the rescue.

The Setup
If you open the Telerik.Web.UI.dll assembly in reflector, you can browse the embedded resources.  Expand the Telerik.Web.UI node and the resources folder below it and a short way down the list you will find a bunch of items named something like Telerik.Web.UI.Editor.DialogControls.DialogName.ascx.  These resources contain the user control markup for all of the RadEditor’s built-in dialogs.  In our case we want to customize the hyperlink manager dialog, so we right click the Telerik.Web.UI.Editor.DialogControls.LinkManager.ascx resource and choose “Save As…” from the context menu.

A good place for this user control is going to be with the rest of the Rich Text Editor files. I chose to create a Dialogs folder within the /sitecore/shell/Controls/Rich Text Editor folder, but as long as you put it somewhere under the web root, it will work. If you develop outside the Sitecore installation and use build scripts or TDS to copy files over, you will want to put it somewhere in your Web application project folder structure and then include it in your project. Be sure to remove the “Telerik.Web.UI.DialogControls” from the name and just save it as “LinkManager.ascx” in which ever folder you choose.

Now that you have extracted your user control from the assembly, you have to let the editor know where to find it. In Sitecoe 6.4.0 and later, you need to edit the /sitecore/shell/controls/rich text editor/EditorPage.aspx file. We need to add a ExternalDialogsPath attribute to the <telerik:RadEditor> tag and set its value to the path of the folder where we saved the LinkManager.ascx user control file.

<telerik:RadEditor ID="Editor" Runat="server" 
    LocalizationPath="~/sitecore/shell/controls/rich text editor/Localization/"
    ExternalDialogsPath="~/sitecore/shell/controls/rich text editor/Dialogs/"
    OnClientLoad="OnClientLoad" />

From here, you just need to modify the user control file to suit your needs. In my case, I wanted to add a Body field to the E-mail tab of the hyperlink manager dialog. This would allow content authors to create email links that started the user off with a standard message in the body of the email. Conveniently, this customization is simple enough to describe in a blog post.

The Execution
The functionality associated with the Body field that I wanted to add is pretty much the same as the Subject field which is included with the default dialog. This is very handy since it allows me to just duplicate and modify the elements and javascript for that field.

The First step is to create the markup for the field. I just copied the table row for the subject field and pasted it below. Then, I changed the label text and changed the <input type=”text”> tag to a <textarea> tag. 

<tr>
    <td class="reLabelCell">
        <label for="EmailSubject" class="reDialogLabel">
            <span>
                <script type="text/javascript">document.write(localization["LinkSubject"]);</script>
            </span>
        </label>
    </td>
    <td class="reControlCell">
        <input type="text" id="EmailSubject" />
    </td>
</tr>
<tr>
    <td class="reLabelCell">
        <label for="EmailBody" class="reDialogLabel">
            <span>Body</span>
        </label>
    </td>
    <td class="reControlCell">
        <textarea id="EmailBody" style="width: 240px; height: 50px;"></textarea>
    </td>
</tr>

Note that the standard fields use JavaScript to output localized strings for the labels. Unfortunately, I could not figure out a way to add localized strings for my label to this script. The control that outputs the script does it by iterating over the properties of a sealed class. This user control also cannot contain any server-side code since it is loaded via the Page.ParseControl method. If you can figure out how to add custom localized strings to these dialogs, post a comment and I will give you a gold star.

The next step is to customize the JavaScript component that handles the functionality of the dialog. There are four locations where additions or changes need to be made to the script.

1. Add a member to hold a reference to the textarea:

setupChildren: function () {
    //...Edited for brevity...
    this._emailSubject = $get("EmailSubject");
    this._emailBody = $get("EmailBody");
    this._emailCssClass = $find("EmailCssClass");
    //...Edited for brevity...
}

2. Clear the field when the dialog opens:

_cleanInputBoxes: function () {
    //...Edited for brevity...
    this._emailSubject.value = "";
    this._emailBody.value = "";
    this._linkCssClass.set_value("");
    this._emailCssClass.set_value("");
},

3. Parse the current link for existing values:

_loadEmailAddressAndSubject: function () {
    var currentHref = this._clientParameters.get_value().getAttribute("href", 2);
    this._emailAddress.value = RegExp.$2;
  
    if (currentHref.match(/(\?|&)subject=([^&]*)/i)) {
        var val = RegExp.$2.replace(/&/gi, "&");
        val = unescape(val);
        this._emailSubject.value = val;
    }
    if (currentHref.match(/(\?|&)body=([^&]*)/i)) {
        var val = RegExp.$2.replace(/&/gi, "&");
        val = unescape(val);
        this._emailBody.value = val;
    }
},

4. Build the new link href from the form values:

getModifiedLink: function () {
    var resultLink = this._clientParameters.get_value();
    var selectedIndex = this._tab.get_selectedIndex();
  
    if (selectedIndex == 0)//"link"
    {
        //...Edited for brevity...
    }
    else if (selectedIndex == 1)//"anchor"
    {
        //...Edited for brevity...
    }
    else //"email"
    {
        resultLink.href = "mailto:" + this._emailAddress.value;
  
        var bodyDelimiter = "?";
  
        if (this._emailSubject.value != "") {
            resultLink.href += "?subject=" + this._emailSubject.value;
            bodyDelimiter = "&";
        }
  
        if (this._emailBody.value != "") {
            resultLink.href += bodyDelimiter + "body=" + this._emailBody.value;
        }
        //...Edited for brevity...
    }
  
    return resultLink;
},

 

 

Sitecore development, Sitecore custom code, video

Comments

Add a Comment

*
*

Please confirm you are human by typing the text you see in this image: