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);

You can also do this declaratively via a Custom Action as described on MSDN here -

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

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"]

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!

Wednesday 23 May 2012

SharePoint 2010 - Content Editor Web Part (CEWP) Versioning

I've been seeing (and hearing) a lot of misinformation about the SharePoint 2010 Content Editor Web Part (CEWP) from people that assume it behaves exactly the same as it did in SharePoint 2007. This is also then used as a rationale as to why you should use page fields as part of page layouts (i.e. the "Page Content" field) to store content - "if you want versioning, you have to use page fields and page layouts. Period! CEWPs just don't support versioning". This is incorrect!

On the contrary, the SharePoint 2010 CEWP does support versioning and you can easily roll back to a previous version of a page with the content of all your Content Editor Web Parts still intact from that old version. It would appear that this is one of the less-well publicised "new" features of SP 2010.

While "page content" fields within page layouts (and their supporting content types) still have a role (when you want more control over layout or don't want javascript put into your pages), a more flexible combination of basic page layouts (e.g. for a column-based structure), with the CEWP provides for more options to end users - particularly when requirements are not set in stone (are they ever?).

Some entries on the blogosphere which indicate (erroneously) that content isn't versioned within CEWP in SharePoint 2010: