Thursday, 24 May 2012

SharePoint 2010 - An easier way to hide Ribbon Items and Ribbon Dropdown List Items without Code

My client recently had a requirement to lock down the set of styles available to users whilst editing content (using the standard SharePoint 2010 Rich Text editor control). The rationale was that if you give users free reign ("enough rope to hang themselves") and absolute freedom on a site, there is a serious risk that it will end up like something that Pro Hart cobbled together with a paintball gun. Needless to say this would not be a great mess to be in (depending on your artistic viewpoint)!

Unfortunately, SharePoint 2010 provides the ability to add new styles to the rich text editor - but NOT to remove those that come with SharePoint out of the box.

SharePoint does provides for an ability to hide controls through the SPRibbon Object model like so:
            SPRibbon ribbon = SPRibbon.GetCurrent(this.Page);
            ribbon.TrimById("ribbon.editingtools.cpedittab.styles.styles");

You can also do this declaratively via a Custom Action as described on MSDN here - http://msdn.microsoft.com/en-us/library/ff408060.aspx

Unfortunately, it doesn't get any more granular than that - you can just hide or show controls but not their content. I suppose you could do a recursive FindControl() to get at the rendered components - but that would be a performance killer if it had to run on every page load. It is also painful to hook into the list with jQuery as the HTML list is rendered dynamically as the ribbon tabs change and different content is selected in the page - so a PageComponent would need to be created as described at http://msdn.microsoft.com/en-us/library/gg552606.aspx.

Yes another alternative approach is through SharePoint's ability to use the PrefixStyleSheet flag on the SharePoint 2010 PublishingWebControls:RichHtmlField - but this would only be for Page Content fields on page layouts. This wouldn't cater for Content Editor Web Parts (CEWP) that also allow for entry of Rich Text. To control that you would also have to make a custom web part to replace the CEWP and hide the out of the box one - this is also a bit of work.
Based on the KISS principle, there has to be an easier way - and there is:
As an example, if you want to hide Heading 4, then you can just use the following CSS:
#Ribbon\.EditingTools\.CPEditTab\.Paragraph\.ElementWithStyle\.Menu\.Styles a[title="Heading 4"]
{
 display:none;
}

This will hide the "Heading 4" item in the Styles Menu. Note that because the controls use the full stop to fully qualify the html element name, you must escape them with a backslash ("\").

To me, the CSS solution seems the lesser of 3 performance evils (CSS vs jQuery vs Server side recursion) and several higher maintenance evils (code complexity and additional solution/feature elements that need to be deployed in your wsp).

Too easy!
DDK

No comments: