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.
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.
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).
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,
{
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.
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>";
}
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;
$("EditorValue").value = htmls;
scForm.browser.clearEvent(evt);
scForm.postRequest("", "", "", command);
scForm.postRequest("", "", "", command);
return false;
}
AND YAY .. double rainbow and unicorn.
}
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.
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.
Thank you for reading a lot of texts.
Comments
Post a Comment