Skip to main content

Customising Sitecore's Rich Text Editor. R u Kidding me?

theProblem:
The front end ( html and css ) is set up such a way that for the description text form a sitecore content needs to have a <p> tag wrapped around it. 
Now, I'm sure just by reading the above 2 lines you are thinking "WOW that's really simple and every RTE does that by default. So, continuing to reading this is useless and this guy is clearly dumb enough."

"sayth whath" - said thor
Well Yes and No.
This is what I found:
So by default the RTE wraps texts in a <p> tag = TRUE. BUT the catch is you will need to hit a enter or copy paste multiple paragraph. Then the RTE will clean the HTML and in the process it will wrap each para in a <p> tag. NICE. Of course there's a setting for it that you can modify and instead of <p> you can have <br/> and so.
<setting name="HtmlEditor.LineBreak" value="p" />
And no you can't have anything that you want there.. there's a limited list of tags that you can put in the settings.
Either way that VERY COOL OF YOU, SITECORE.
But this doesn't solve my problem. Cause I want ( or the client wants or the requirement is) to add a <p> tag regardless of hitting the enter button.
So when someone types in one line in there and hit the "accept" button the text will be wrapped in a <p> tag.
This has been stuck in the head and I had dreams about it.
theResearch:
This is where I start cursing sitecore because of it's lack of documentation and particularly how the RTE is baked into it.
Basically SITECORE uses RADEditor from Telerik ( which is 'probably' not TinyMCE )  as its RTE. In terms of how rad editor is made is flexible enough to customise its behaviour according to the needs BUT the way sitecore has included it makes it somewhat not so much customisable.
AND OFCOURSE THERE IS NO OR VERY LESS DOCUMENTATION ABOUT IT.
I eventually ended up seeing it internal code from Sitecore.client.dll and figure out how they're incorporating the RadEditor.
What I Tried:
"sitecore\shell\Controls\Rich Text Editor\EditorWindow.aspx" is the file that displays the UI of the editor. And one of the JS functions in there is my injection point for my custom snippet to add <p> tag.
BUT obviously I cannot change this file because it won't be in the sourcecontrol and as part of standard practice I should not modify SITECORE's core file as it will lead to inconsistency in different environment and will become difficult to manage (should the need arises to re-install sitecore).
Also, because how RadEditor is baked into SITECORE I could not implement my own custom EditorFilter because according to the RadEditor documentation that would require modifying its declaration in <telerik:RadEditor ID="Editor" Runat="server"> which also is in EditorWindow.aspx. So there goes my golden egg. :( ( I did say F*** Y** SITECORE at this point, ofcourse)
theSolution:
Fortunately, From the dll, one particular function caught my eye: 
protected virtual void SetupScripts()
{
foreach (XmlNode node in Factory.GetConfigNodes("clientscripts/htmleditor/script"))
this.Result.Scripts.AppendFormat("<script src=\"{0}\" language=\"{1}\"></script>\n", (object) XmlUtil.GetAttribute("src", node), (object) XmlUtil.GetAttribute("language", node));
}
NICE, eh ? The developers of SITECORE are clever after all.
So I did this in the webconfig,
<!-- CLIENT SCRIPTS
These script files are included in the client, e.g. '<script src="/myscript.js" language="JavaScript"/>'
-->
<clientscripts>
<everypage />
<htmleditor>
<script src="/assets/js/CustomRTE.js" language="javascript"/>
</htmleditor>
</clientscripts>

And overrode "scSendRequest" function from EditorWindow.aspx.
window.scSendRequest = function(evt, command){
var editor = scRichText.getEditor();
if (editor.get_mode() == 2){//If in HTML edit mode
editor.set_mode(1); //Set mode to Design
}
var htmls = editor.get_html(true);
var regex = /<p[^>]*>.*?<\/p>/i;
var match = regex.exec(htmls);
if(match == null && htmls != null) {
htmls = "<p>" + htmls + "</p>";
}
//$("EditorValue").value = editor.get_html(true);
$("EditorValue").value = htmls;
scForm.browser.clearEvent(evt);

scForm.postRequest("", "", "", command);
return false;
}

AND YAY .. double rainbow and unicorn.

Obviously the JS stuffs didn't come out my head right away. I must confess the struggle.
So with this approach nothing from SITECORE's core has been modified and all the custom code sits out side of sitecore shell making them source controllable too and achieve's what I wanted.

The important thing I learned here is overriding a JS function. Didn't even know that was possible. Weird.
However the question remains, where the F*** is the documentation ?

theEnd:
There might be more straight forward and better way of doing it ( for which what I have done is dumb enough ) .. but until then this will do. 
Either way, this opens few other doors for customising Sitecore's RTE. ( if it helps anyone )

Thank you for reading a lot of texts.

Comments

Popular posts from this blog

Managing devices using Edge Manager

Managing edge devices has been a complex process as traditional IT ops tools fall short in distributed, low-connectivity environment to manage huge quantity of devices.  Red Hat Edge Manager  (Open source project: FlightControl , GA'd by Red Hat on late Jan, 2026) solves these challenges by providing streamlined management of edge devices and applications through a declarative approach . Now, there's a fair bit to unpack here. But for simplicity this is how I am going to map those 3 things here: Management of edge devices: I am mapping this to LCM (including upgrade, patch etc) of the underlying OS (in this case RHEL OS of BootC flavor or at least UBI based RHEL ). Managing applications: Mapping this to deploying applications and LCM of the applications stack on the OS. Declarative approach: This one is super interesting. To me this is very K8s-yy but in the world of edge devices running linux (RHEL OS, as of today). And then this thing also has MCP : This is my next prob...

The story of a Hack Job

"So, you have hacked it" -- Few days ago one of the guys at work passed me this comment on a random discussion about something I built. I paused for a moment and pondered: Do I reply defending how that's not a hack. OR Do I just not bother I picked the second option for 2 reasons: It was late. It probably isn't worth defending the "hack vs" topic as the comment passed was out of context. So I chose the next best action and replied "Yep, sure did and it is working great.". I felt like Batman in the moment. In this post I will rant about the knowledge gap around hacking and then describe about one of the components of my home automation project (really, this is the main reason for this post) and use that as an example how hacking is cool and does not always mean bad. But first lets align on my definition of hacking: People use this term in good and bad, both ways. For example: "He/she did a hack job" -- Yeah, that probably...

Passwordless Auth to Azure Key Vault using External Secret and Workload Identity

I want to fetch my secrets from Azure KV and I don't want to use any password for it. Let's see how this can be implemented. This is yet another blog post (YABP) about ESO and Azure Workload Identity. Why Passwordless Auth: It is a common practice to use some sort of "master password" (spn clienid, clientsecret etc) to access Secret Vaults (in this case it is AZ KV) but that master password becomes a headache to manage (rotate, prevent leak etc). So, the passwordless auth to AKV is ideal.  Why ESO: This is discussed and addressed in the conclusion section. Workload Identity (Passwordless Auth): Lets make a backward start (just for a change). I will try to explain how the passwordless auth will work. This will make more sense when you will read through the detailed implementation section. Here's a sequence diagram to explain it: There's no magic here. This is a well documented process by microsoft  here . The below diagram (directly copied from the official doc...

Deciphering the hype of Service Mesh

Service Mesh is not a new topic anymore. Most of us in the industry are already familiar with it. There are also tons of article in the internet about its why and how. In my opinion, it has a significant influence on the application architecture. Here's a DevSecOps humor to start the discussion (and it will make sense as you read along).  This is part 1 of my 3 parts blog posts on Service Mesh. Part 1:   Deciphering the hype of Service Mesh Part 2:   Understanding The Ingress and The Mesh components of Service Mesh. Part 3:  Understanding the observability component of Service Mesh (TBD).  In this post, I am going approach Service Mesh from an application architecture point of view. I will also score some of its basic features on a scale of 1 to 5, where 1 being the least important to me and 5 being the most important.  Table of contents: Common Q&As Features mTLS Service Discovery Meshing Ingress, Gateways etc Telemetries Enterprise products and offeri...

Speeding using Crossplane and ServiceBinding

Software development and release processes continues to improve to deliver value to the users faster and better to support business growth and relevance in this competitive market. To achieve this we focus on automating the path to production and any people or process related obstacles of a software on its way to the user. Generally, some of the goals of the golden paths, are: Remove interdependency and promote self service and  provider & consumer relationship. Shift left - from people & process to technology & automation . Treat Platform-as-product and provide PaaS Secured and standardised by design In this post, I will describe how Crossplane and ServiceBinding can help achieve these goals in the context of applications development and delivery and their consumption of external resources / services in the process. Note:   Crossplane and  ServiceBinding both are capable of covering beyond just database connectivity. In this blog post I am describing Dat...

A modern cloud native (and self serve) way to manage Virtual Machines

Really!! Are there could native way to deploy, LCM VMs and add Self Serve on top ???? In this post I will describe an art of the possibility using the below tools: RHDH: Red Hat Developer Hub (Open source project: Backstage ) OCP Virtualization: Red Hat OpenShift Virtualization (Open source project: KubeVirt ) AAP: Red Hat Ansible Automation Platform (Open source project: Ansible / AWX ) RHEL BootC: Image mode for Red Hat Enterprise Linux (Open source project: bootc ) GitOps: Red Hat OpenShift GitOps (Open source project: ArgoCD ) Quay Registry or any other OCI compliant registry All of these projects can be run on Red Hat OpenShift (Open source project: OKD ) OR on other Kubernetes distribution or on VMs (you pick your underlying infra. For this post I have used OpenShift for simplicity of deployment, integrated tools and narrowly focusing on the usecases instead of the deployment of the tools).  The main goal here is to: Easily deploy and lifecycle applications and stuffs ...