Changing the body class of the WYSIWYG (TinyMCE) Editor

  • May 15, 2015
  • EPiServer
  • EditorDescriptor
  • TinyMCE
  • |

Last week I ran into a styling problem with the WYSIWYG (inline) editor of EPiServer. In the Admin mode a stylesheet can be configured which will be loaded whenever the TinyMCE plugin is displayed on the screen. This can be handy if you want your WYSIWYG editor to show the styling as how it would be rendered in the site. The problem that occurred was that some CSS styling was targeted from the body class. The WYSIWYG (TinyMCE) editor is loaded into a iFrame, so the styling from my CSS file wasn’t applied to my elements in the editor.

 

Problem situation

 

I have created an empty EPiServer site to show the problem and solution. The source code can be found on my GitHub account.

Below the stylesheet, as you can see the li element is targeted from the body class ‘container’.

body.container ul li {
    color: red;
    font-weight: bold;
    list-style-type: square;
}
View

 

The HomePage contains the MainBody property which is of type XhtmlString. The view has a reference to the stylesheet. The body contains the class ‘container’.

@model EPiServerXhtmlStringSettings.Models.Pages.HomePage
 
<!DOCTYPE html>
 
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <link href="~/Static/style.css" rel="stylesheet" type="text/css" />
</head>
<body class="container">
    <div>
        @Html.PropertyFor(p => p.MainBody)
    </div>
</body>
</html>

 

View rendered

 

The screenshot below shows how the view is rendered in the browser. The list has a bold and red color, also the square is shown for each item.

 

WYSISWYG Editor rendered

 

In the WYSIWYG editor the style isn’t applied to the list while the stylesheet is configured in the admin mode.

So the problem is caused because the WYSIWYG editor is loaded in a iFrame, that means that the style isn’t targeted because the body element of the iFrame doesn’t contains the class ‘container’. I’ve used Chrome developer tools for looking up the below snippet. As you can see the body class has some other class values, but not the ‘container’ class.

 

Solution: custom XhtmlString editor descriptor

 

This problem can be fixed by creating an EditorDescriptor that inherits from the XhtmlStringEditorDescriptor. EPiServer sets a couple of configuration settings that’s used by the DOJO widget. One of those settings is de uiParams, which is a dictionary object. The uiParams contains an item ‘body_class’, this item is set by the XhtmlStringEditorDescriptor and has the value ‘epi-inline’. The DOJO widget makes sure that this value is set on the class attribute of the body element. The below code snippet shows how you can add an additional class to the body element.

[EditorDescriptorRegistration(TargetType = typeof (XhtmlString), UIHint = "custom-xhtmlstring")]
   public class CustomXhtmlStringEditorDescriptor : XhtmlStringEditorDescriptor
   {
       public CustomXhtmlStringEditorDescriptor() : base()
       {
 
       }
 
       public override void ModifyMetadata(EPiServer.Shell.ObjectEditing.ExtendedMetadata metadata,
           IEnumerable<Attribute> attributes)
       {
           base.ModifyMetadata(metadata, attributes);
 
           dynamic data = metadata.CustomEditorSettings["uiParams"];
           var dictionary = (Dictionary<string, object>) data.GetType().GetProperty("inlineSettings").GetValue(data, null);
           dictionary["body_class"] = dictionary["body_class"] + " container";
       }
   }

When you look again with the Chrome developer tools the body class now contains the value ‘container’.

And of course a screenshot of the WYSIWYG editor.

 

You can find the full source code on my GitHub account.

Comments