Customize #TinyMCE at runtime in Episerver 11

Need to customize the TinyMCE buttons at runtime and not at init? here is how.

Published 17th September 2018
Episerver 11
Episerver.Cms.TinyMce > 2.0

Old news for some, but pretty neat when you need to customize the tinyMCE instance depending on context or other logic.

In this example I restrict the use of buttons by role. So in this example the role “Bloggers” has one setup of buttons then other “normal” webeditors.

Solution with EditorDescriptor

An editor descriptor is an class that runs on server just before the property is rendered in browsers. It makes it possible to change the data “on the fly” just before it is showed.

Two steps:

  1. Register the class with EditorDescriptorRegistration
  2. Override ModifyMetadata with your logic

Find the settings:

All settings data are located in metadata.EditorConfiguration[“settings”]

Disable Menubar:

settings[“menubar”] = “false”;

Change the toolbars:

var toolbarList = ((IEnumerable) settings["toolbar"]).Cast<string>().ToList();
if (toolbarList.Count >= 1) toolbarList[0] = "bold italic strikethrough styleselect"; 
if (toolbarList.Count >= 2) toolbarList[1] = ""; 
if (toolbarList.Count >= 3) toolbarList[2] = ""; 
settings["toolbar"] = toolbarList;

Just debug settings variable and you’ll find all the tinymce properties

The cs code (editordescriptor)

gist: https://gist.github.com/LucGosso/822b6e25d954c40117008c062ced7e67

using EPiServer.Core;
using EPiServer.Shell.ObjectEditing.EditorDescriptors;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Gosso.Episerver.Business.EditorDescriptors
{
    [EditorDescriptorRegistration(TargetType = typeof(XhtmlString), EditorDescriptorBehavior = EditorDescriptorBehavior.PlaceLast)]
    public class CustomXhtmlStringEditorDescriptor : EditorDescriptor
    {
        public override void ModifyMetadata(EPiServer.Shell.ObjectEditing.ExtendedMetadata metadata,
            IEnumerable<Attribute> attributes)
        {
            if (HttpContext.Current.User.IsInRole("Bloggers")) // do your own logic
            {
                if (metadata.EditorConfiguration["settings"] is Dictionary<string, object> settings)
                {
                    var toolbarList = ((IEnumerable) settings["toolbar"]).Cast<string>().ToList();
                    if (toolbarList.Count >= 1)
                        toolbarList[0] =
                            "bold italic strikethrough styleselect | epi-link image epi-image-editor | customfaktabuttonplugin customimagebuttonplugin | bullist numlist | removeformat | searchreplace fullscreen";
                    if (toolbarList.Count >= 2) toolbarList[1] = "";
                    if (toolbarList.Count >= 3) toolbarList[2] = "";
                    settings["toolbar"] = toolbarList;
                    settings["menubar"] = "false";
                }
            }

        }
    }
}

Configure the editor on Init

The standard approach is to register your setup in an Episerver init module

Example of setup XhtmlString with a lot of goodies:

using EPiServer.Cms.TinyMce.Core;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;

namespace Gosso.Episerver.Business.Initialization
{
    [ModuleDependency(typeof(TinyMceInitialization))]
    public class CustomizedTinyMceInitialization : IConfigurableModule
    {
        public void ConfigureContainer(ServiceConfigurationContext context)
        {
            context.Services.Configure<TinyMceConfiguration>(config =>
            {
                config.Default().AddSetting("extended_valid_elements",
                        "iframe[src|alt|title|width|height|align|name],picture,source[srcset|media]")
                    .AddPlugin(
                        "epi-link epi-image-editor epi-dnd-processor epi-personalized-content print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists textcolor " +
                        " imagetools colorpicker textpattern help code")
                    .Toolbar(
                        "bold italic strikethrough forecolor | epi-link image epi-image-editor epi-personalized-content | customfaktabuttonplugin customimagebuttonplugin | bullist numlist | searchreplace fullscreen ",
                        "styleselect formatselect | alignleft aligncenter alignright alignjustify | removeformat | table code"
                        , "")//three parameter for first second and third row
                    .Menubar("edit insert view format table tools help")
                    .StyleFormats(
                        new {title = "Paragraf", block = "p"},
                        new {title = "Heading (h2)", block = "h2"}
                    ).BodyClass("main-content infopage-content") //css class in on body in tinymce
                    //.AddSetting("image_class_list", new[]
                    //{
                    //    new {title = "None", value = ""},
                    //    new {title = "class one", value = "one"}
                    //})
                    .AddSetting("image_title", true)//yes have title on images
                    .AddSetting("image_dimensions", false) // dont' automatic have height and width on image
                    .ContentCss("/bundles/yourcss";
            });
        }
        public void Initialize(InitializationEngine context)
        {
        }

        public void Uninitialize(InitializationEngine context)
        {
        }
    }
}

 

SEO-terms
  • Change properties in editor
  • Full example of TinyMceConfiguration
  • TinyMceConfiguration setup

About the author

Luc Gosso
– Independent Senior Web Developer
working with Azure and Episerver

Twitter: @LucGosso
LinkedIn: linkedin.com/in/luc-gosso/
Github: github.com/lucgosso

1 thought on “Customize #TinyMCE at runtime in Episerver 11”

Leave a Reply

Your email address will not be published. Required fields are marked *