Rich text editor customization
The rich text editor in Xperience can be extended by defining custom editor configurations and by developing custom plugins.
Additionally, the system allows developers to exactly control which rich text editor configurations are loaded, and to make dynamic adjustments of the configuration content. This can be done by providing a custom implementation of the IRichTextEditorConfigurationProvider
service. In most cases, we recommend extending the default implementation via the decorator pattern.
The sections below provide examples of scenarios that use this customization pattern:
Replace the default editor configuration
When adding fields with the Rich text editor form component in the field editor, the selected Configuration name determines which options and plugins are available in the editor toolbar. If the user leaves the Configuration name empty, the field uses a default editor configuration.
You can use the IRichTextEditorConfigurationProvider
service to replace the default configuration with a custom editor configuration that is preferred for your project. With this change, users no longer need to select your custom configuration for every rich text field.
- Open your Xperience solution in Visual Studio.
- Add a custom assembly (Class Library project) with class discovery enabled to the solution, or re-use an existing assembly.
- Create a new custom class in the assembly, and implement the
IRichTextEditorConfigurationProvider
interface. - Add the
GetConfigurationByName
method:- The
configurationName
parameter contains the identifier of the configuration that was requested. Write a condition to detect the configurations that you want to replace.- Access the
IDENTIFIER
constant in the following classes to get the identifier of the system’s default configurations:RichTextEditorWebsitesStructuredContentConfiguration
– for page fieldsRichTextEditorStructuredContentConfiguration
– for reusable content item fieldsRichTextEditorHeadlessStructuredContentConfiguration
– for headless item fieldsRichTextEditorEmailContentForAutoresponderConfiguration
– for emails with the Form autoresponder purposeRichTextEditorEmailContentConfiguration
– for all other emails
- For rich text editor fields with the default “empty” configuration outside of the above locations, the
configurationName
isnull
.
- Access the
- Use the decorator customization pattern to call the default implementation for cases where you do not wish to replace the requested configuration.
- The
- Register the implementation using the
RegisterImplementation
assembly attribute.
using System;
using CMS;
using Kentico.Xperience.Admin.Base.Forms;
using Kentico.Xperience.Admin.Websites;
// Registers the custom IRichTextEditorConfigurationProvider implementation
[assembly: RegisterImplementation(typeof(IRichTextEditorConfigurationProvider), typeof(CustomDefaultRichTextEditorConfigurationProvider))]
public class CustomDefaultRichTextEditorConfigurationProvider : IRichTextEditorConfigurationProvider
{
private readonly IRichTextEditorConfigurationProvider richTextEditorConfigurationProvider;
public CustomDefaultRichTextEditorConfigurationProvider(IRichTextEditorConfigurationProvider richTextEditorConfigurationProvider)
{
// Gets an instance of the default IRichTextEditorConfigurationProvider service
this.richTextEditorConfigurationProvider = richTextEditorConfigurationProvider;
}
// Loads the configuration for instances of the rich text editor in the administration
public string GetConfigurationByName(string configurationName)
{
// The 'configurationName' parameter contains the identifier of the requested editor configuration
// This condition replaces the system's default editor configuration for page fields
if (string.IsNullOrEmpty(configurationName) ||
string.Equals(configurationName, RichTextEditorWebsitesStructuredContentConfiguration.IDENTIFIER, StringComparison.OrdinalIgnoreCase))
{
// Use the identifier of your preferred custom configuration
// For example, access the IDENTIFIER constant of the class used to register the configuration
return richTextEditorConfigurationProvider.GetConfigurationByName(CustomDefaultEditorConfiguration.IDENTIFIER);
}
// Calls the default implementation and returns the unmodified configuration in all other cases
return richTextEditorConfigurationProvider.GetConfigurationByName(configurationName);
}
}
Add custom CSS to the rich text editor
The following example demonstrates how to adjust the appearance and design of the rich text editor by inserting custom styles. The recommended approach is to create a custom plugin containing the required elements and CSS, and then use the IRichTextEditorConfigurationProvider
service to dynamically insert your plugin into the appropriate editor configurations.
- Create a custom JavaScript module for the admin UI.
- Use the client development boilerplate project to simplify the set up. Make sure the project has the Kentico.Xperience.Admin NuGet package installed so it can access admin UI-related APIs.
- Within the module, create a React component file for the plugin.
- Import any required styles. You do not need to return any custom markup.
JSCustomCSSRichTextEditorPlugin.tsximport React from 'react'; // Imports custom styles import './CustomCSSRichTextEditorPlugin.css'; // The plugin component's name must have the 'RichTextEditorPlugin' suffix export const CustomCSSRichTextEditorPlugin = () => { return ( // No markup to return <></> ); };
- Add files containing the styles that you wish to import.
- You can use basic CSS, or any CSS extension language supported by your module’s environment.
CSSCustomCSSRichTextEditorPlugin.css/* Examples of custom styles for the fr-view class, which is applied to the editor's content area */ .fr-view h2 { font-size: 3em; } .fr-view { background-color: red; }
- Export the plugin component from the module:TSXentry.tsx
export * from './path/CustomCSSRichTextEditorPlugin';
- Create a class in the admin module, and implement the
IRichTextEditorConfigurationProvider
interface. - Add the
GetConfigurationByName
method and insert thecustomPlugins
array with your custom CSS plugin into every configuration:C#Adding the custom CSS plugin to rich text editor configurationsusing System.Text.Json; using System.Text.Json.Nodes; using CMS; using Kentico.Xperience.Admin.Base.Forms; // Registers the custom IRichTextEditorConfigurationProvider implementation [assembly: RegisterImplementation(typeof(IRichTextEditorConfigurationProvider), typeof(CustomCssRichTextEditorConfigurationProvider))] public class CustomCssRichTextEditorConfigurationProvider : IRichTextEditorConfigurationProvider { private readonly IRichTextEditorConfigurationProvider richTextEditorConfigurationProvider; public CustomCssRichTextEditorConfigurationProvider(IRichTextEditorConfigurationProvider richTextEditorConfigurationProvider) { // Gets an instance of the default IRichTextEditorConfigurationProvider service this.richTextEditorConfigurationProvider = richTextEditorConfigurationProvider; } public string GetConfigurationByName(string configurationName) { // Gets the requested rich text editor configuration var configuration = richTextEditorConfigurationProvider.GetConfigurationByName(configurationName); // Adds the custom CSS plugin to the configuration's JSON content var jsonObj = JsonNode.Parse(configuration); if (jsonObj?["customPlugins"] is JsonArray optionsArray) { var newOption = new JsonObject { // Replace 'orgName' and 'projectName' with the values for your client admin module. // The final part of the plugin name must match the name of // the plugin's React component without the 'RichTextEditorPlugin' suffix. ["pluginName"] = "@orgName/projectName/CustomCSS" }; optionsArray.Add(newOption); } // Returns the modified configuration content, including the custom CSS plugin return jsonObj?.ToJsonString(new JsonSerializerOptions { WriteIndented = true }); } }
In thepluginName
configuration value, replaceorgName
andprojectName
with your own values. By default, the boilerplate project usesacme
andweb-admin
respectively. The final part of the plugin name must match the name of the plugin’s React component without the RichTextEditorPlugin suffix (CustomCSS in this example).
The custom IRichTextEditorConfigurationProvider
service dynamically inserts the custom CSS plugin into every rich text editor configuration, and the imported CSS is applied to the editor in the admin UI.