<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Oxite - Mr. Roa</title>
        <description>The name is Roa. Mr. Roa</description>
        <link>/Tags/Oxite/RSS</link>
        <language>en</language>
        <image>
            <url>http://mrroa.com/Content/icons/mushroom.png</url>
            <title>Mr. Roa</title>
            <link>/Tags/Oxite/RSS</link>
            <width>64</width>
            <height>64</height>
        </image>
        <item>
            <dc:creator>Admin</dc:creator>
            <title>Oxite: Blog Description &amp; Profile Management</title>
            <description>&lt;p&gt;Following my Oxite blog post series, I add some extra functionality to the administration panel of the blog engine as well as some little changes to the blog engine title, shown on the front-end. Also I'll use this oportunity to give a little insight about Oxite's core and internal structure.&lt;/p&gt;
&lt;h3&gt;Let's vent first...&lt;/h3&gt;
&lt;p&gt;If you search and read reviews you may notice that Oxite it's not considered to be good at all. Actually is not referred as a Microsoft ASP .NET MVC Framework guidance project, not even a starter kit. Adding to that I'm absolutely sure when I say it's not even close to a &quot;Best Practices &amp;amp; Patterns&quot; repository for ASP .NET MVC Framework enthusiasts.&lt;/p&gt;
&lt;p&gt;Instead of wasting time reinventing the wheel, by reviewing the code (again!) or the project as a whole. I'll just summarize what I think of it with a single sentence. Ready? Here it goes. Oxite is an unorthodox, undocumented and untested application made with good intentions. MVC is supposed to enforce the developer to come up with a good application design, but ironically this just makes Oxite a good anti-pattern example providing a high coupled/low cohesive design and incredible complex project structure due to unnecessary&amp;nbsp;abstraction layers. Perhaps it's just because it's not a finished product and it was created in the early stages of a maturing technology. Who knows?!&lt;/p&gt;
&lt;p&gt;I'll admit I like the challenge and that's precisely why I chose this as my starting point for my blog engine. I know the guys who created this have a disclaimer, telling me other &quot;mature&quot; choices, BUT I didn't expect to be abbandoned in this creepy box of moving sand! (Look for Orchard in codeplex).&lt;/p&gt;
&lt;h3&gt;And now... The features&lt;/h3&gt;
&lt;p&gt;So, if you follow other bloggers you may have noticed that they all have a funky/catchy phrase below the blog title. And if you watch closely, you may notice that the funky/catchy phrase is missing here. You may be thinking, so what? it's no biggie. And you might be right. But in the end, advertisement, which should be considered a science, proves you wrong! These phrases have a name! They are called slogans, and they have claimed to be the most effective means of drawing attention (according to &lt;a href=&quot;http://en.wikipedia.org/wiki/Advertising_slogans&quot; target=&quot;_blank&quot;&gt;wikipedia&lt;/a&gt;). But the most interesting thing is that a slogan implies&amp;nbsp;distinction between products, and that's it! that's what we must always pursue when having a web page among millions and millions... DISTINCTION!&lt;/p&gt;
&lt;p&gt;Jumping right into business, achieving this is fairly simple. The Site entity has a property called Description, which is accessible from the Model in the view. This is convenient since we are able to update the description already from the settings tab in the Admin section.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://s.mrroa.com/editsite.PNG&quot; alt=&quot;Edit Site&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Then locate the header.ascx on your skin folder. Change the title div as follows:&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&amp;lt;div id=&quot;title&quot;&amp;gt;
    &amp;lt;h1&amp;gt;&amp;lt;a href=&quot;&amp;lt;%=Url.Posts() %&amp;gt;&quot;&amp;gt;&amp;lt;%=Model.Site.DisplayName %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/h1&amp;gt;
    &amp;lt;%=Model.Site.Description %&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So that's it, nice and simple! Now we have a fancy catch phrase space. Which reminds me, now I need a slogan!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://s.mrroa.com/title.PNG&quot; alt=&quot;title&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The next thing is something that really annoyed me. While browsing through the issues on &lt;a href=&quot;http://www.codeplex.com/oxite&quot; target=&quot;_blank&quot;&gt;oxite's codeplex page&lt;/a&gt;, I learned that in order to change the logged user's display name (in this case the admin, since oxite does not support user management yet ;) you had to go to the database and change it manually. I can't stand the greeting message when I log in, every time I read &quot;Welcome, Oxite Administrator!&quot; I get cranky and bored. So let's fix that and put our name there!&lt;/p&gt;
&lt;p&gt;First we need to locate the routes dictionary class. It's a class file called OxiteRoutes.cs located on the Oxite project. This is how our new route looks.&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;AddRoute(
      &quot;UserChangeProfile&quot;,
      &quot;Admin/ChangeProfile&quot;,
       new { controller = &quot;User&quot;, action = &quot;ChangeProfile&quot;, validateAntiForgeryToken = true },
       null,
       new { Namespaces = controllerNamespaces });
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Cool, so let's take a look to what we did here. We defined a route name: &quot;UserChangeProfile&quot; and mapped an url to it: &quot;Admin/ChangeProfile&quot;, according to our routing engine this url must be mapped to an action, which we defined on the object defaults attribute. We said that the action will be: &quot;ChangeProfile&quot; and that it's going to be located on the UserController.cs. The other parameters are tokens and other optional properties.&lt;/p&gt;
&lt;p&gt;Oxite also has a Helper class for url generations from the views. It's called UrlHelperExtensions.cs and it's located on the Oxite.Mvc project inside of the Extensions folder. We should add this snippet there.&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;public static string UserChangeProfile(this UrlHelper urlHelper)
{
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return urlHelper.RouteUrl(&quot;UserChangeProfile&quot;);
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So now that we are done with the routing, we need to change the EditUser method on the service that is going to be used by the controller. I just modified the signature of the EditUser method interface to look like this:&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;void EditUser(User user, bool passwordUpdate, out ValidationStateDictionary validationState);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I added a small modification to the method implementation, so we don't modify the user password when change the user full name. The implementation looks like this:&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;public void EditUser(User user, bool passwordUpdate, out ValidationStateDictionary validationState)
{
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;validationState = new ValidationStateDictionary();
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;validationState.Add(typeof(User), validator.Validate(user));

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (!validationState.IsValid)
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;{
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (!string.IsNullOrEmpty(user.Password) &amp;amp;&amp;amp; passwordUpdate)
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;{
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;user.PasswordSalt = Guid.NewGuid().ToString(&quot;N&quot;);
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;user.Password = saltAndHash(user.Password, user.PasswordSalt);
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;user.HashedEmail = user.Email.ComputeHash();
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;repository.Save(user);
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ok, so we only need to do two more things and we are done. First we need to add the controller action definition that is going to be called by the routing engine, and second we need to create the view that is going to be rendered by this action.&lt;/p&gt;
&lt;p&gt;First let's edit the UserController. Let's add our actions for HTTP verbs Get/Post.&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;[ActionName(&quot;ChangeProfile&quot;), AcceptVerbs(HttpVerbs.Post)]
public virtual object ChangeProfileSave(User currentUser, FormCollection form)
{
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;string name = form[&quot;displayName&quot;];
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;string email = form[&quot;email&quot;];
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ValidationStateDictionary validationState;

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (string.IsNullOrEmpty(name))
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ModelState.AddModelError(&quot;displayName&quot;, &quot;New Name is not set.&quot;);
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (string.IsNullOrEmpty(email))
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ModelState.AddModelError(&quot;email&quot;, &quot;New Email is not set.&quot;);
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (ModelState.IsValid)
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;currentUser.DisplayName = name;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;currentUser.Email = email;

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;userService.EditUser(currentUser, false, out validationState);

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!validationState.IsValid)
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ModelState.AddModelErrors(validationState);
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!ModelState.IsValid)
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ModelState.SetModelValue(&quot;displayName&quot;, new ValueProviderResult(name, name, CultureInfo.CurrentCulture));
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ModelState.SetModelValue(&quot;email&quot;, new ValueProviderResult(email, email, CultureInfo.CurrentCulture));

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ChangeProfile(currentUser);
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return Redirect(Url.AppPath(Url.ManageUsers()));
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Finally, let's add our view code.&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&amp;lt;%@ Page Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; 
&lt;span style=&quot;white-space: pre;&quot;&gt;	&lt;/span&gt;MasterPageFile=&quot;~/Views/Shared/Admin.master&quot; Inherits=&quot;System.Web.Mvc.ViewPage&amp;gt;&quot; %&amp;gt;
&amp;lt;%@ Import Namespace=&quot;Oxite.Mvc.Extensions&quot; %&amp;gt;
&amp;lt;asp:Content ContentPlaceHolderID=&quot;MainContent&quot; runat=&quot;server&quot;&amp;gt;
    &amp;lt;h2 class=&quot;title&quot;&amp;gt;&amp;lt;%=Model.Localize(&quot;ChangeProfile&quot;, &quot;Change Profile&quot;) %&amp;gt;&amp;lt;/h2&amp;gt;
    &amp;lt;%=Html.ValidationSummary() %&amp;gt;
    &amp;lt;form action=&quot;&quot; method=&quot;post&quot;&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;%=Html.TextBox(&quot;displayName&quot;,  m =&amp;gt; m.User != null ? m.User.DisplayName : &quot;&quot;,&amp;nbsp;
                            Model.Localize(&quot;DisplayName&quot;, &quot;Display Name&quot;), new { size = 42, @class = &quot;text&quot; })%&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;
         &amp;lt;%=Html.TextBox(&quot;email&quot;,  m =&amp;gt; m.User != null ? m.User.Email : &quot;&quot;,
                             Model.Localize(&quot;Email&quot;, &quot;Email&quot;), new { size = 42, @class = &quot;text&quot; })%&amp;gt;
     &amp;lt;/div&amp;gt;
     &amp;lt;div&amp;gt;
         &amp;lt;input type=&quot;submit&quot; name=&quot;submit&quot; class=&quot;submit button&quot;
&lt;span style=&quot;white-space: pre;&quot;&gt;		&lt;/span&gt;  &lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; value=&quot;&amp;lt;%=Model.Localize(&quot;ChangeProfile&quot;, &quot;Change Profile&quot;) %&amp;gt;&quot; /&amp;gt;
         &amp;lt;%=Html.OxiteAntiForgeryToken(m =&amp;gt; m.AntiForgeryToken) %&amp;gt;
     &amp;lt;/div&amp;gt;
     &amp;lt;/form&amp;gt;
 &amp;lt;/asp:Content&amp;gt;
 &amp;lt;asp:Content ContentPlaceHolderID=&quot;Scripts&quot; runat=&quot;server&quot;&amp;gt;
     &amp;lt;% Html.RenderScriptTag(&quot;site.js&quot;); %&amp;gt;
 &amp;lt;/asp:Content&amp;gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;That's it ladies and gentleman! Now we are able to modify our user's email and display name.&lt;/p&gt;
&lt;h3&gt;UPDATE!&lt;/h3&gt;
&lt;p&gt;After making these changes, I noticed that something else had to be done to get a complete solution to the DisplayName fix. After applying the updates above we successfully update the DisplayName to whatever we want, but Admin (which is an username) is still being shown on the comments made by the me, instead of MY NAME. So in order to achieve this we only have to make a mall update to the Comments.ascx file as follows.&lt;/p&gt;
&lt;p&gt;Replace the line of the name paragraph inside of the comment div with this one:&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;Mr.&amp;nbsp;&amp;lt;strong&amp;gt;&amp;lt;%=Html.LinkOrDefault((Model.PartialModel.Child.Creator.Name.ToLower() == &quot;admin&quot;) ?
    Model.PartialModel.Child.Creator.DisplayName : Model.PartialModel.Child.Creator.Name.CleanText(), 
&lt;span style=&quot;white-space: pre;&quot;&gt;	&lt;/span&gt;Model.PartialModel.Child.Creator.Url.CleanHref())%&amp;gt;&amp;lt;/strong&amp;gt;&lt;/pre&gt;</description>
            <link>http://mrroa.com/Blog/Oxite-Blog-Description--Profile-Management</link>
            <guid isPermaLink="true">http://mrroa.com/Blog/Oxite-Blog-Description--Profile-Management</guid>
            <pubDate>Sun, 10 Jan 2010 09:33:00 GMT</pubDate>
            <category>profile</category>
            <category>Oxite</category>
            <category>slogan</category>
        </item>
        <item>
            <dc:creator>Admin</dc:creator>
            <title>Oxite: Customizing the comments area</title>
            <description>&lt;p&gt;Continuing my Oxite series of blog posts I'll address the comments area. For my taste oxite is missing a couple of things on the comments listing and comments posting department. It doesn't have a way to ensure that the comment being posted is not being generated by a bot. I've already been a victim of this and to be honest I'm not a fan of SPAM, so let's stop that!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://s.mrroa.com/oxite-spam.png&quot; alt=&quot;&quot; width=&quot;727&quot; height=&quot;314&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Oxite also doesn't have a special style for comments posted by the site admin. In this blog post we are going to address this issues by implementing a css class that helps the reader identify a site administrator comment from a blog comment's list and a &lt;a title=&quot;Captcha&quot; href=&quot;http://en.wikipedia.org/wiki/CAPTCHA&quot; target=&quot;_blank&quot;&gt;captcha&lt;/a&gt; validation for the comments input.&lt;/p&gt;
&lt;p&gt;For these tasks I'll be using css and &lt;a title=&quot;Re Captcha&quot; href=&quot;http://recaptcha.net/&quot; target=&quot;_blank&quot;&gt;reCAPTCHA&lt;/a&gt;, which is owned by google and it's widely used among popular sites as Facebook, The New York Times, StackOverflow, TicketMaster, etc. It's worth pointing out that reCaptcha was initially conceived in Carnegie Mellon University, where the term &quot;CAPTCHA&quot; was initially coined. The term contrives from the acronym&amp;nbsp; &quot;&lt;strong&gt;C&lt;/strong&gt;ompletely &lt;strong&gt;A&lt;/strong&gt;utomated &lt;strong&gt;P&lt;/strong&gt;ublic &lt;strong&gt;T&lt;/strong&gt;uring test to tell &lt;strong&gt;C&lt;/strong&gt;omputers and &lt;strong&gt;H&lt;/strong&gt;umans &lt;strong&gt;A&lt;/strong&gt;part.&quot;&lt;/p&gt;
&lt;p&gt;So putting the theory to a side, let's start getting things done!&lt;/p&gt;
&lt;h3&gt;Styling the Admin comments&lt;/h3&gt;
&lt;p&gt;When the admin posts a comment Oxite automatically adds an &quot;Admin&quot; class to the li element from the comments list. This means that styling the comment won't be very hard since the only thing to do is add a custom style for this class. I chose a beige tone as the background of the Admin comments and added the following to the site stylesheet (site.css)&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;ul.comments.medium li.Admin
{
    background: #FFFFC0;
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And tha
&lt;script src=&quot;../../../Skins/Default/Scripts/tiny_mce/themes/advanced/langs/en.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;../../../Skins/Default/Scripts/tiny_mce/themes/advanced/langs/en.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
t's it, from now on my comments will have a beige like background. That was easy wasn't it? Good let's keep moving!&lt;/p&gt;
&lt;h3&gt;Implementing reCAPTCHA&lt;/h3&gt;
&lt;p&gt;Moving on to the CAPTCHA part, we have to do a couple things before starting. First register at&amp;nbsp;&lt;a title=&quot;Re Captcha&quot; href=&quot;http://recaptcha.net/&quot; target=&quot;_blank&quot;&gt;reCAPTCHA&lt;/a&gt;, download the .NET dll and reference it from Oxite.Mvc project. After that the first thing to do is create an Action Filter Attribute. There's already a directory containing existing Filters for Oxite on the Oxite.Mvc project so let's place ours there.&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;namespace Oxite.Mvc.ActionFilters
{
&amp;nbsp;&amp;nbsp; &amp;nbsp;public class CaptchaAttribute : ActionFilterAttribute
&amp;nbsp;&amp;nbsp; &amp;nbsp;{
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;private const string ChallengeFieldKey = &quot;recaptcha_challenge_field&quot;;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;private const string ResponseFieldKey = &quot;recaptcha_response_field&quot;;

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;public override void OnActionExecuting(ActionExecutingContext filterContext)
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{
            //Getting the user parameter from the current context
            var user = (Model.User)filterContext.ActionParameters[&quot;currentUser&quot;];
            if (user != null &amp;amp;&amp;amp; user.Name == &quot;Admin&quot;)
            {
                filterContext.ActionParameters[&quot;captchaValid&quot;] = true;
                return;
            }
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;var captchaChallengeValue = filterContext.HttpContext.Request.Form[ChallengeFieldKey];
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;var captchaResponseValue = filterContext.HttpContext.Request.Form[ResponseFieldKey];

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;var captchaValidtor = new Recaptcha.RecaptchaValidator
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PrivateKey = &quot;YOUR PRIVATE KEY GOES HERE&quot;,
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;RemoteIP = filterContext.HttpContext.Request.UserHostAddress,
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Challenge = captchaChallengeValue,
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Response = captchaResponseValue
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;};

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;var recaptchaResponse = captchaValidtor.Validate();
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;filterContext.ActionParameters[&quot;captchaValid&quot;] = recaptchaResponse.IsValid;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;base.OnActionExecuting(filterContext);

&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&amp;nbsp;&amp;nbsp; &amp;nbsp;}
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In order to render the reCAPTCHA widget we are going to add a new helper to the Html helper Extensions class. The helper is going to ease the implementation by encapsulating everything to a method call. Our new extension method should look like this:&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;#region ReCaptcha
public static string RenderCaptcha(this HtmlHelper helper)
{
&amp;nbsp; &amp;nbsp; &amp;nbsp; var captchaControl = new Recaptcha.RecaptchaControl
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ID = &quot;recaptcha&quot;,
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Theme = &quot;clean&quot;,
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PublicKey = &quot;YOUR PUBLIC KEY GOES HERE&quot;,
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PrivateKey = &quot;YOUR PRIVATE &lt;script src=&quot;../../../Skins/Default/Scripts/tiny_mce/themes/advanced/langs/en.js&quot; type=&quot;text/javascript&quot;&gt;&lt;!--mce:2--&gt;&lt;/script&gt;KEY GOES HERE&quot;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;};

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;var htmlWriter = new HtmlTextWriter(new StringWriter());
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;captchaControl.RenderControl(htmlWriter);
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return htmlWriter.InnerWriter.ToString();
}
#endregion&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now we are ready for the implementation. From here we just need to add our Action Filter Attribute on the Controller method that creates the post comment. The Controller is located on the same project as the Action Filers, Oxite.Mvc. The comments are created on the PostController. There we need to add our Action Filter Attribute to the AddComment method. Also we need to change the method signature by adding a new overload by adding a new variable to contain our reCAPTCHA validation result.&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;[CaptchaValidator]
[ActionName(&quot;Item&quot;), AcceptVerbs(HttpVerbs.Post)]
public virtual object AddComment(Area areaInput, PostBase postBaseInput, Comment commentInput, UserBase userBaseInput,&amp;nbsp;
                                   UserBase currentUser,&amp;nbsp;bool? remember, bool? subscribe, bool? captchaValid)&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now the success of the CAPTCHA validation is going to be contained on the added boolean value. Notice that the type is marked as nullable, this is because the method is initialized with null values on the OxiteApplication class.&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;itemActionCriteria.AddMethod(p =&amp;gt; p.AddComment(null, null, null, null, null, null, null, null));&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Great, so now we have almost everything in place. I used a quick &amp;amp; dirty approach in order to raise the form validation when a the introduced string does not match the one displayed by the reCAPTCHA widget. In case the captchaValid variable is false I just set the comment on the&amp;nbsp;&lt;span style=&quot;white-space: pre;&quot;&gt;commentInput object to String.Empty.&lt;span style=&quot;white-space: normal;&quot;&gt;&amp;nbsp;This will set the validationState object IsValid flag to false, which is Oxite's form validation mechanism.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;white-space: pre;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;Now the only thing left to do is go to the&amp;nbsp;CommentFromAnonymous.ascx user control. This is what renders the actual comment form on the post. Here we are going to add our Html helper extension method in order to render the reCAPTCHA widget and finally add some validation to the post comment form. I decided to place my widget under the actual comment text area. The call to the extension method looks like this:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&amp;lt;div class=&quot;recaptcha&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;%= Html.RenderCaptcha() %&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;In this blog post I added an extra, yet important, feature to Oxite: CAPTCHA validation. Once again, I was able to extend the current core with ease and added reCAPTCHA's widget. I'm so glad I did this, since I wont have to deal with spam comments anymore :). Stay tuned for some other Oxite extensions and more praising of the MVC paradigm!&lt;/p&gt;</description>
            <link>http://mrroa.com/Blog/Oxite-Customizing-the-comments-area</link>
            <guid isPermaLink="true">http://mrroa.com/Blog/Oxite-Customizing-the-comments-area</guid>
            <pubDate>Tue, 27 Oct 2009 05:19:00 GMT</pubDate>
            <category>recaptcha</category>
            <category>Oxite</category>
        </item>
        <item>
            <dc:creator>Admin</dc:creator>
            <title>Oxite: Meets TinyMCE</title>
            <description>&lt;p&gt;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 &lt;a title=&quot;Mr. Roa&quot; href=&quot;../../../Blog/Hello-World&quot;&gt;first post&lt;/a&gt;&amp;nbsp;I stated that I intended to modify the blogging engine and complete it &lt;strong&gt;&lt;em&gt;my way&lt;/em&gt;&lt;/strong&gt;. I already created a list of features, that I'd like to see in it in order to get things going.&lt;/p&gt;
&lt;p&gt;So, according to &lt;strong&gt;ME&lt;/strong&gt;, the first &quot;missing&quot; feature in Oxite, is a wysiwyg. I know it can be integrated with &lt;a title=&quot;Using Windows Live Writer to publish in Oxite &quot; href=&quot;http://capitalcoder.com/Blog/Using-Windows-Live-Writer-with-Oxite&quot; target=&quot;_blank&quot;&gt;live writer&lt;/a&gt;, 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.&lt;/p&gt;
&lt;p&gt;Let's get this thing started then. After a browsing through an extensive list of available &lt;span class=&quot;subhead&quot;&gt;&lt;span style=&quot;font-family: Verdana;&quot;&gt;&lt;a href=&quot;http://www.geniisoft.com/showcase.nsf/WebEditors&quot; target=&quot;_blank&quot;&gt;TTW (&quot;Through the Web&quot;) WYSIWYG Web Editors&lt;/a&gt;, I chose to use &lt;a href=&quot;http://tinymce.moxiecode.com/&quot; target=&quot;_blank&quot;&gt;TinyMCE&lt;/a&gt;. It's widely used, it has a lot of plugins, an active community and it seems really easy to implement.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;subhead&quot;&gt;&lt;span style=&quot;font-family: Verdana;&quot;&gt;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:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;subhead&quot;&gt;&lt;span style=&quot;font-family: Verdana;&quot;&gt;Use default formatting tools such as bold text, italic, underline, text alignment and justification, etc.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;subhead&quot;&gt;&lt;span style=&quot;font-family: Verdana;&quot;&gt;Have a html view in case I need to teak some of the markup after all.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;subhead&quot;&gt;&lt;span style=&quot;font-family: Verdana;&quot;&gt;An option to wrap text between pre or code tags in order to identify code snippets.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;subhead&quot;&gt;&lt;span style=&quot;font-family: Verdana;&quot;&gt;Spellchecker, of course! This is one of the most useful features when creating articles/posts. (isn't it?)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ok, after getting that out of the way. Let's get started shall we?&lt;/p&gt;
&lt;h3&gt;TinyMCE &amp;amp; Code Snippet Wrapping&lt;/h3&gt;
&lt;p&gt;&lt;span class=&quot;subhead&quot;&gt;&lt;span style=&quot;font-family: Verdana;&quot;&gt;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 &lt;a href=&quot;http://code.google.com/p/google-code-prettify/&quot; target=&quot;_blank&quot;&gt;prettify&lt;/a&gt;. After downloading both, the script files must be placed inside the Scripts folder of the Oxite theme being used.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://s.mrroa.com/tinymcescripts.png&quot; alt=&quot;&quot; width=&quot;269&quot; height=&quot;285&quot; /&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://s.mrroa.com/tinymcestyles.png&quot; alt=&quot;&quot; width=&quot;269&quot; height=&quot;285&quot; /&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://s.mrroa.com/prettifyfontsize.png&quot; alt=&quot;&quot; width=&quot;751&quot; height=&quot;336&quot; /&gt;&lt;/p&gt;
&lt;p&gt;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 &lt;em&gt;extensions&lt;/em&gt;. Here we are going to place the initialization script for tinymce as follows.&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;tinyMCE.init({&lt;br /&gt;    mode: &quot;exact&quot;,&lt;br /&gt;    elements: &quot;post_body&quot;,&lt;br /&gt;    theme: &quot;advanced&quot;,&lt;br /&gt;    theme_advanced_buttons1: &quot;codetag,code,separator,bold,italic,underline,strikethrough,separator,justifyleft,&lt;br /&gt;    justifycenter,justifyright,justifyfull,separator,bullist,numlist,separator,undo,redo,separator,link,unlink&quot;,&lt;br /&gt;    theme_advanced_buttons2: &quot;&quot;,&lt;br /&gt;    theme_advanced_buttons3: &quot;&quot;,&lt;br /&gt;    theme_advanced_toolbar_location: &quot;top&quot;,&lt;br /&gt;    theme_advanced_toolbar_align: &quot;left&quot;,&lt;br /&gt;    theme_advanced_statusbar_location: &quot;bottom&quot;,       &lt;br /&gt;    setup: function(ed) {&lt;br /&gt;        //Custom button Code (Code Snippet Wrapper)&lt;br /&gt;        ed.addButton('codetag', {&lt;br /&gt;            title: 'Wrap code tags around selected text',&lt;br /&gt;            image: 'http://mrroa.com/Content/images/code.gif',&lt;br /&gt;            onclick: function() {&lt;br /&gt;                ed.selection.setContent('&amp;lt;pre class=&quot;prettify&quot;&amp;gt;' &lt;br /&gt;                     + ed.selection.getContent({ format: 'text' }) + '&amp;lt;/pre&amp;gt;');             &lt;br /&gt;             }         &lt;br /&gt;         });     &lt;br /&gt;      } });&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;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 &lt;span style=&quot;text-decoration: underline;&quot;&gt;&lt;em&gt;code&lt;/em&gt;&lt;/span&gt; button represents the html source viewer, so this WYSIWYG almost has all the features described initially.&lt;/p&gt;
&lt;h3&gt;SpellChecking&lt;/h3&gt;
&lt;p&gt;For this feature we need to work a little bit more. First of all we need to download and reference the TinyMCE &lt;a href=&quot;http://tinymce.moxiecode.com/download.php&quot; target=&quot;_blank&quot;&gt;.NET Package&lt;/a&gt;. 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).&lt;/p&gt;
&lt;p&gt;After referencing the package we need to add the following code to the httpHandlers section of our web.config.&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&amp;lt;add verb=&quot;GET,HEAD,POST&quot; path=&quot;TinyMCE.ashx&quot; type=&quot;Moxiecode.TinyMCE.Web.HttpHandler,Moxiecode.TinyMCE&quot; /&amp;gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;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.&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;routes.Add(new Route(&quot;TinyMCE.ashx&quot;, new StopRoutingHandler()))&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now we just need to update the script file containing the TinyMCE initialization to implement the spellchecker plugin.&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;tinyMCE.init({&lt;br /&gt;    mode: &quot;exact&quot;,&lt;br /&gt;    elements: &quot;post_body&quot;,&lt;br /&gt;    theme: &quot;advanced&quot;,&lt;br /&gt;    plugins: &quot;spellchecker&quot;,&lt;br /&gt;    theme_advanced_buttons1: &quot;codetag,code,separator,bold,italic,underline,strikethrough,separator,justifyleft,&lt;br /&gt;    justifycenter,justifyright,justifyfull,separator,bullist,numlist,separator,undo,redo,separator,link,unlink,separator,&lt;br /&gt;    spellchecker&quot;,&lt;br /&gt;    theme_advanced_buttons2: &quot;&quot;,&lt;br /&gt;    theme_advanced_buttons3: &quot;&quot;,&lt;br /&gt;    theme_advanced_toolbar_location: &quot;top&quot;,&lt;br /&gt;    theme_advanced_toolbar_align: &quot;left&quot;,&lt;br /&gt;    theme_advanced_statusbar_location: &quot;bottom&quot;,      &lt;br /&gt;    spellchecker_languages: &quot;+English=en,Spanish=es&quot;,&lt;br /&gt;    spellchecker_rpc_url: &quot;/TinyMCE.ashx?module=SpellChecker&quot;,&lt;br /&gt;    setup: function(ed) {&lt;br /&gt;        //Custom button Code (Code Snippet Wrapper)&lt;br /&gt;        ed.addButton('codetag', {&lt;br /&gt;            title: 'Wrap code tags around selected text',&lt;br /&gt;            image: 'http://mrroa.com/Content/images/code.gif',&lt;br /&gt;            onclick: function() {&lt;br /&gt;                ed.selection.setContent('&amp;lt;pre class=&quot;prettify&quot;&amp;gt;' &lt;br /&gt;                     + ed.selection.getContent({ format: 'text' }) + '&amp;lt;/pre&amp;gt;');             &lt;br /&gt;             }         &lt;br /&gt;         });     &lt;br /&gt;      } });&lt;/pre&gt;
&lt;h3&gt;One Final Step&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;First in HeadCustomAdminContents.ascx&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;Html.RenderScriptTag(&quot;tiny_mce/tiny_mce_src.js&quot;);&lt;br /&gt;Html.RenderScriptTag(&quot;mrroa.com.js&quot;);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And then in HeadCustomContents.ascx&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;Html.RenderCssFile(&quot;prettify.css&quot;);&lt;br /&gt;Html.RenderScriptTag(&quot;prettify/prettify.js&quot;);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;The Result&lt;/h3&gt;
&lt;p&gt;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 ;)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://s.mrroa.com/tinymce.png&quot; alt=&quot;&quot; width=&quot;945&quot; height=&quot;282&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;In this post, I tried to emphasize on the importance of having text formatting tools like &lt;strong&gt;WYSIWYG&lt;/strong&gt;'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.&lt;/p&gt;</description>
            <link>http://mrroa.com/Blog/Oxite-meets-TinyMCE</link>
            <guid isPermaLink="true">http://mrroa.com/Blog/Oxite-meets-TinyMCE</guid>
            <pubDate>Wed, 16 Sep 2009 10:11:00 GMT</pubDate>
            <category>TinyMCE</category>
            <category>Oxite</category>
        </item>
    </channel>
</rss>
