Disable inserting Web Parts in the SharePoint 2010 Rich Text Editor

Insert Web Parts group disabled on the Ribbon
SharePoint 2010 ships with a brand new Rich Text Editor which has a dozen of new capabilities. One of those capabilities allows you to insert Web Parts in content which can help you add some rich functionality to your content. And while it sounds pretty cool there are scenarios when you might want to turn inserting Web Parts in content off. In this article you can read about how you can disable inserting Web Parts in the SharePoint 2010 Rich Text Editor.

SharePoint 2010 ships with a Rich Text Editor (RTE) which not only has a better User Experience but also is highly customizable. That allows you to tailor the available functionality to your specific needs and provide your users with what they need. One of the configuration options for the new RTE is whether to allow inserting Web Parts in content or not.

Inserting Web Parts in content out of the box

Out of the box SharePoint 2010 uses the new Rich Text Editor in many different places. Depending on the application some of them allow you to insert Web Parts in content while others don’t.

By default all Rich HTML fields allow you to insert Web Parts in content.

Insert Web Part button enabled on the Ribbon while Rich HTML field focused.

On the other hand when editing Rich HTML in the Content Editor Web Part or in the Reusable Content, SharePoint does not allow you to insert Web Parts in content.

Insert Web Part button disabled on the Ribbon while Content Editor Web Part focused.

Inconvenient SharePoint 2010 Rich Text Editor

As I mentioned before the new SharePoint 2010 Rich Text Editor is highly customizable. Unfortunately, if you examine the properties closer you won’t find anything that would allow you to configure restricting inserting Web Parts in content.

So is this yet another configuration option reserved at the moment for Microsoft solutions only or can we configure it after all?

Restricting inserting Web Parts in content by trimming the Ribbon

The first approach that you might consider is by trimming the Ribbon controls. By hiding the Insert Web Parts group from the Ribbon you make it impossible for the user to insert a Web Part.

Insert Web Parts controls hidden from the Ribbon.

This can be easily achieved using the SharePoint and Ribbon API. To do that all you need to do is to create the following control:

using System;  
using System.Web.UI;  
using Microsoft.SharePoint.WebControls;

namespace RestrictingInsertWebPartsInRte.WebControls  
{
    public class RestrictInsertWebParts : Control
    {
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            SPRibbon ribbon = SPRibbon.GetCurrent(Page);
            if (ribbon != null)
            {
                ribbon.TrimById("Ribbon.EditingTools.CPInsert.WebParts");
            }
        }
    }
}

Important: For this code to work you will need a reference to the Microsoft.Web.CommandUI assembly located in the 14\ISAPI folder.

Using the TrimById method, you can hide any piece of the Ribbon. In our scenario we hide the Insert Web Parts group from the Ribbon making it impossible for the user to insert a Web Part into content. Once you have the above control in place all you need to do is to add it to your Page Layout. While the above example is pretty simple, you could easily extend it the code to add things like support for permissions.

Unfortunately there is one drawback to this approach. As you can notice in the above code snippet, all what we do is to trim the Ribbon. We don’t change any of the properties of the Rich Text Editor, so physically it is still possible to add a Web Part in content, and it is even easier than you might have thought.

If you have a Web Part Zone somewhere on the page, you can add a Web Part to it by clicking the Add a Web Part in the Web Part Zone.

Red arrow pointing to the ‘Add a Web Part’ link in a Web Part Zone.

Content Editor Web Part inserted in content in spite of hiding the ‘Insert Web Parts’ group on the Ribbon.

Then, after you select a Web Part (1), all you need to do is to change the Web Part Zone to Rich Content (2) click somewhere in the editor (3), and when you click the Add button (4) the Web Part will be inserted in the editor – so much for a restriction:

Content Editor Web Part inserted into content.

While the above approach is very easy and might work in some scenarios it is not fool-proof and you might need to try something else if you want a more reliable solution.

Restricting Web Parts in content in the Rich Text Editor

As I mentioned before the RichTextField control doesn’t allow you to restrict inserting Web Parts in content. Although there are dozen other properties that you can configure, controlling inserting Web Parts is not among them. And yet there is another way for you to disallow users to insert Web Parts in content.

As you might have heard SharePoint 2010 ships with rich ECMA Script API. Using that API you can read and write data to SharePoint, but you can also display notification and status messages and display dialog messages. Among all the pieces of the new client-side API is the RTE namespace designed to work with the new SharePoint 2010 Rich Text Editor: and this is exactly what we will be needing to restrict inserting Web Parts in contents.

Capabilities of a Rich Text Editor are determined by restrictions. Restrictions are basically attributes set on the HTML div tag of an RTE. There are quite a few restrictions which allow you to customize the functionality of an RTE, among which the AllowWebParts restriction.

When in Rich Text Editor you can set a restriction as follows:

var rte = RTE.Canvas.currentEditableRegion();  
if (rte != null) {  
    RTE.Canvas.setRestriction(rte, RTE.Canvas.allowWebParts, false);
}

First you get the current editable region of the active Rich Text Editor, and then set the desired restriction. This code will result in the allowWebParts attribute being set on the RTE’s div which will disable the Insert Web Parts group on the Ribbon for this specific RTE.

'Insert Web Parts’ group disabled on the Ribbon.

In the above code snippet we used the currently focused RTE to set the restriction on, but what if you would like to do this beforehand?

For such situations I came up with the following control:

public class RestrictInsertWebParts : Control  
{
    public string RteId { get; set; }

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        string restrictInsertWebPartsFunction = @"var restrictInsertWebParts = function(rteId) {
    SP.SOD.executeOrDelayUntilScriptLoaded(Function.createDelegate(this, function() {
        var rteNode = document.getElementById(rteId);
        if (rteNode != null) {
            var rte = RTE.Canvas.getEditableRegion(rteNode);
            if (rte != null) {
                RTE.Canvas.setRestriction(rte, RTE.Canvas.allowWebParts, false);
            }
        }
    }), 'sp.ui.rte.js');
}
";

        Page.ClientScript.RegisterClientScriptBlock(typeof(RestrictInsertWebParts), "RestrictInsertWebParts", restrictInsertWebPartsFunction, true);
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        string script = @"SP.SOD.executeOrDelayUntilScriptLoaded(function() {{ restrictInsertWebParts('{0}'); }}, 'sp.ui.rte.publishing.js');";

        if (SPContext.Current != null &&
            (SPContext.Current.FormContext.FormMode == SPControlMode.New ||
            SPContext.Current.FormContext.FormMode == SPControlMode.Edit))
        {
            if (!String.IsNullOrEmpty(RteId))
            {
                RichHtmlField rte = FindControlRecursive(Page, RteId) as RichHtmlField;
                if (rte != null)
                {
                    SP.SOD.executeOrDelayUntilScriptLoaded(function() {{ restrictInsertWebParts('{0}'); }}, 'sp.ui.rte.publishing.js');
                }
            }
        }
    }

    public static Control FindControlRecursive(Control root, string id)
    {
        if (root.ID == id)
        {
            return root;
        }

        foreach (Control c in root.Controls)
        {
            Control foundControl = FindControlRecursive(c, id);
            if (foundControl != null)
            {
                return foundControl;
            }
        }

        return null;
    }
}

The RteId property contains the ID of the RichHtmlField for which you want to disable adding Web Parts. Next, in the OnInit Event Handler, a common JavaScript function is being registered with the page. Using this function we can easily set the allowWebParts restriction on a given RTE. Then, just before the rendering process starts, we check if the page is in New or Edit mode (the mode when RTE works) and if so, we try to retrieve the specific RichHtmlField. If we find it, we pass the ID of its HTML editor (the V4RTEClientId property) to the previously defined JavaScript function.

The important part here is, that any restriction that you set on the Rich Text Editor must be set after the SP.UI.RTE.Publishing.js script has loaded. Otherwise your restriction will be overwritten by the default settings and/or restrictions set directly on the Rich HTML field.

One more thing

While testing disabling Web Parts inserting in a Rich Text Editor by setting a restriction, I noticed, that while the Insert Web Parts group is being disabled as expected, you can still insert a Web Part by using the workaround I described earlier in this article. It turns out that the RTE restrictions are for UI trimming purposes only rather than physical restrictions on the RTE.

As a workaround, to make inserting Web Parts into content a little more difficult, you could use jQuery to remove the Rich Content option from the Web Part Adder so that it’s not possible for the user to insert a Web Part in content. You could do this using the following jQuery snippet:

$(".ms-wpadder-zoneArea option:contains('Rich Content')", $("#WebPartAdderUpdatePanelContainer")).remove()

‘Rich Content’ zone removed from the Web Part Adder.

Summary

SharePoint 2010 ships with a new Rich Text Editor. One of its new capabilities is the ability of inserting Web Parts into content which can help you enrich your content with dynamic data. While this functionality definitely adds value to your content there are scenario’s when you might want to disable the option of inserting Web Parts into content. Although it seems that this can be done in a supported fashion, you can disable inserting Web Parts into the Rich Text Editor content using the extensibility API of the new RTE provided with SharePoint 2010.

Technorati Tags: SharePoint 2010

Comments

comments powered by Disqus