Oxite: Meets TinyMCE
This is the first of a series of blog posts I'll be doing about Oxite, a simple blog engine written using ASP .NET MVC. Which happens to be the one I'm using to administrate and maintain my blog. On my first post I stated that I intended to modify the blogging engine and complete it my way. I already created a list of features, that I'd like to see in it in order to get things going.
So, according to ME, the first "missing" feature in Oxite, is a wysiwyg. I know it can be integrated with live writer, but c'mon a blog engine shouldn't rely on third party applications, even though integration with those it's a nice feature. A blog engine should provide an easy to use text formatting tool. At least for the body of the blog post, taking care of annoying formatting tasks which involve a lot of html markup. With that said, after this blog post I won't be writing html markup directly into a textarea in order to format my blog posts.
Let's get this thing started then. After a browsing through an extensive list of available TTW ("Through the Web") WYSIWYG Web Editors, I chose to use TinyMCE. It's widely used, it has a lot of plugins, an active community and it seems really easy to implement.
Well, I'm done with the first step. I already chose my formatting tool for my blog posts. Anyways I created a little list of things I MUST be able to do when creating a blog post with it:
- Use default formatting tools such as bold text, italic, underline, text alignment and justification, etc.
- Have a html view in case I need to teak some of the markup after all.
- An option to wrap text between pre or code tags in order to identify code snippets.
- Spellchecker, of course! This is one of the most useful features when creating articles/posts. (isn't it?)
Ok, after getting that out of the way. Let's get started shall we?
TinyMCE & Code Snippet Wrapping
In order to get started we need to download TinyMCE, also since one of our requirements is to wrap code snippets between pre/code tags we will need something to make code snippets look prettier. For that matter I'll be using prettify. After downloading both, the script files must be placed inside the Scripts folder of the Oxite theme being used.

Prettify also comes with a stylesheet that defines the color schema of our code snippets, so we should also place that file inside of the Styles folder of the Oxite theme.

For my taste the code snippet text should be big and clear, so I changed the cascading style sheet to render the code snippet fonts a little bit bigger.

Ok, so now we are closer to having a WYSIWYG with support to paste code snippets in Oxite, but first there are a couple more steps we need to do. In order to be a little bit more organized I created a mrroa.com.js file which is going to contain my client side extensions. Here we are going to place the initialization script for tinymce as follows.
tinyMCE.init({
mode: "exact",
elements: "post_body",
theme: "advanced",
theme_advanced_buttons1: "codetag,code,separator,bold,italic,underline,strikethrough,separator,justifyleft,
justifycenter,justifyright,justifyfull,separator,bullist,numlist,separator,undo,redo,separator,link,unlink",
theme_advanced_buttons2: "",
theme_advanced_buttons3: "",
theme_advanced_toolbar_location: "top",
theme_advanced_toolbar_align: "left",
theme_advanced_statusbar_location: "bottom",
setup: function(ed) {
//Custom button Code (Code Snippet Wrapper)
ed.addButton('codetag', {
title: 'Wrap code tags around selected text',
image: 'http://mrroa.com/Content/images/code.gif',
onclick: function() {
ed.selection.setContent('<pre class="prettify">'
+ ed.selection.getContent({ format: 'text' }) + '</pre>');
}
});
} });
Notice that there's a setup property which contains a javascript function. This is the definition of our code wrapping button, that is not included in TinyMCE's palette of buttons. The setup section in the above snippet, tells TinyMCE to wrap around pre tags our text selection. Also notice how I added the default text formatting tools into the theme_advanced_buttons1 collection. The code button represents the html source viewer, so this WYSIWYG almost has all the features described initially.
SpellChecking
For this feature we need to work a little bit more. First of all we need to download and reference the TinyMCE .NET Package. Among many features embedded, this package contains a handler which implements the old google spellchecking API, which still works (I figure that eventually they will update the hanlder to implement the new one).
After referencing the package we need to add the following code to the httpHandlers section of our web.config.
<add verb="GET,HEAD,POST" path="TinyMCE.ashx" type="Moxiecode.TinyMCE.Web.HttpHandler,Moxiecode.TinyMCE" />
Also we need to add a rule to the Oxite Routing class, in order to tell the ASP .NET MVC routing engine that it shouldn't map to a controller the requests made to the hanlder.
routes.Add(new Route("TinyMCE.ashx", new StopRoutingHandler()))
Now we just need to update the script file containing the TinyMCE initialization to implement the spellchecker plugin.
tinyMCE.init({
mode: "exact",
elements: "post_body",
theme: "advanced",
plugins: "spellchecker",
theme_advanced_buttons1: "codetag,code,separator,bold,italic,underline,strikethrough,separator,justifyleft,
justifycenter,justifyright,justifyfull,separator,bullist,numlist,separator,undo,redo,separator,link,unlink,separator,
spellchecker",
theme_advanced_buttons2: "",
theme_advanced_buttons3: "",
theme_advanced_toolbar_location: "top",
theme_advanced_toolbar_align: "left",
theme_advanced_statusbar_location: "bottom",
spellchecker_languages: "+English=en,Spanish=es",
spellchecker_rpc_url: "/TinyMCE.ashx?module=SpellChecker",
setup: function(ed) {
//Custom button Code (Code Snippet Wrapper)
ed.addButton('codetag', {
title: 'Wrap code tags around selected text',
image: 'http://mrroa.com/Content/images/code.gif',
onclick: function() {
ed.selection.setContent('<pre class="prettify">'
+ ed.selection.getContent({ format: 'text' }) + '</pre>');
}
});
} });
One Final Step
Now we need to reference the scripts and stylesheets on the master pages of the site. In order to achieve this we need to place this snippets in two webusercontrols.
First in HeadCustomAdminContents.ascx
Html.RenderScriptTag("tiny_mce/tiny_mce_src.js");
Html.RenderScriptTag("mrroa.com.js");
And then in HeadCustomContents.ascx
Html.RenderCssFile("prettify.css");
Html.RenderScriptTag("prettify/prettify.js");
The Result
Here's a screenshot of my nice and shiny WYSIWYG with all the features I wanted. I guess you can tell I used it to create this post as well ;)

Summary
In this post, I tried to emphasize on the importance of having text formatting tools like WYSIWYG's in systems used for publishing. Also I tried to show how to implement TinyMCE, which is widely used, and how to extend it for some specific purposes. Furthermore, this series of articles purpose is to demonstrate how the MVC model allows to achieve with ease extensibility, modifiability and testability.
2 Comments
Mr. black hattitude said
October 24, 2009
hello,
Thank you for the great quality of your blog, every time i come here, i'm amazed.
black hattitude.
Mr. Raúl Roa said
October 27, 2009
Thanks for the support, I hope you keep enjoying my blog posts.
-Raul