Rich Text Editor style sheets in a Multi Site Sitecore solution

In the Sitecore web.config, there is a setting to point to a style sheet file, so that Rich Text Editors (RTE) all can point to a set of classes that all content editors can use. The setting is:

<setting name="WebStylesheet" value="/default.css" />

Style classes show up based on the style sheet pointed to in the web.config setting

The default setting is ‘default.css’, which comes with Sitecore – you can either add to this file, or change it to point to your own custom .css file. This all works great – unless you have a multisite solution that requires content editors to have different style sheets for each site. The setting allows you to point to only one .css file, and sometimes you may be able to get away by putting @import statements, but if you need the Rich Text Editor to be site aware while in the content editor, you’ll need to extend the control that comes with Sitecore.

In pre-Sitecore 6.4, the control that was used was Telerik RADEditor – there is an article on SDN that explains how to extend the control that if you are using versions prior to 6.4 (or 6.3).

In Sitecore 6.5, it uses a slightly different version of this control and the implementation isn’t quite the same; When ‘Show Editor’ button is clicked on the RTE control, a page pops up with the control loaded. The page that pops up is Editor.aspx, and it is located at: [your webroot]\sitecore\shell\Controls\Rich Text Editor. The first thing we need to do is to make a class to extend the Sitecore.Shell.Controls.RichTextEditor.EditorPage

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sitecore.Web;
using Sitecore.Shell.Controls.RichTextEditor;
using Sitecore.Security.Accounts;
using Sitecore.Data.Items;
using Sitecore.Configuration;
using Telerik.Web.UI;
using System.Threading;
using System.Net;
using System.Configuration;

namespace MyCustomNamespace
{
    public class RTEStyleLoader : Sitecore.Shell.Controls.RichTextEditor.EditorPage
    {
        
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (!base.IsPostBack && !string.IsNullOrEmpty(WebUtil.GetQueryString("id")))
            {
                string id = WebUtil.GetQueryString("id");
                Item item = Sitecore.Context.ContentDatabase.GetItem(id);

                //This is here so that the CSS file doesn't cache
                string strNoCache = "?noCache=" + DateTime.Now.Ticks.ToString();
                
                //DO YOUR LOGIC HERE TO DETERMINE THE STYLE SHEET THAT SHOULD BE USED
                string siteCssPath = "/Styles/SiteSpecific.css"

                this.Editor.CssFiles.Add(new EditorCssFile(siteCssPath));

            }
        }

    }

}

Step-by-step Code Breakdown

1. First, make a new class in your project that inherits from Sitecore.Shell.Controls.RichTextEditor.EditorPage

public class MultiSiteEditorPage : Sitecore.Shell.Controls.RichTextEditor.EditorPage

2. Override the OnLoad method of the control

protected override void OnLoad(EventArgs e)

3. Make sure the logic in here is executed only when there is no postback and the item ID exists (when you click ‘Show Editor’, the ID of the item being edited is passed into the control)

if (!base.IsPostBack && !string.IsNullOrEmpty(WebUtil.GetQueryString("id")))

4. Get the item in context using the ID from the URL

string id = WebUtil.GetQueryString("id");
Item item = Sitecore.Context.ContentDatabase.GetItem(id);

5. Once you have your item ID and the item, determine the site in context, and then use the style sheet path to add a new css file into the RTE control. You can actually add multiple CSS files into the control – the result will be a concatenation of all the files.

//DO YOUR LOGIC HERE TO DETERMINE THE STYLE SHEET THAT SHOULD BE USED
string siteCssPath = "/Styles/SiteSpecific.css"

this.Editor.CssFiles.Add(new EditorCssFile(siteCssPath));

You can make the class in your Sitecore project or in a custom class library (although in a custom class library you may have issues trying to determine the item, etc). Once the class is complete, go to the Editor.aspx page, and change the page directive to point to your class:

change:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="EditorPage.aspx.cs" Inherits="Sitecore.Shell.Controls.RichTextEditor.EditorPage" %>

to this:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="RTEStyleLoader.aspx.cs" Inherits="HMyCustomNamespace.RTEStyleLoader" %>

That should be it. Now if you load the Content Editor, any items with the RTE control should show the list of classes based on the style sheet that was loaded.


Note: This is a change to components that comprise of Sitecore’s core functionality, and there are different schools of thought as to whether one should customize Sitecore to this level, as any future changes to how Sitecore implements the RTE control may break the concept shown here. Given the requirement, this is the best way I’ve found to get this done (let me know if you know a better way). Make sure all changes of this sort are documented, and it shouldn’t be an issue. You can check how future implementations are done by looking in the RTE control folder.