Easy HTML Formatting for Comments in Orchard Using Markdown

I recently moved this site from BlogEngine.NET to Orchard, and I decided I wanted to offer some basic HTML formatting (bold, italic, hyperlinks, etc.) functionality for comments, but I didn't want to do any significant amount of coding. After some research I realized that Markdown syntax would be the easiest way to let my visitors add HTML to their comments, and I could enable it with just a few bits of JavaScript.

This solution involves three parts:

  1. Enable Markdown->HTML conversion on the client side using JavaScript.
  2. Add a JavaScript function to trigger the conversion when comments are displayed to site visitors.
  3. Update the Orchard ListOfComments shape to support the scripts in steps 1 and 2.

Enabling Markdown->HTML conversion

First, we need to enable Markdown->HTML conversion in the browser via JavaScript. For this, I chose PageDown, which is what StackOverflow uses for Markdown previewing. The PageDown project includes three JavaScript files:

  1. Markdown.Converter.js - This does the Markdown->HTML conversion.
  2. Markdown.Sanitizer.js - This lets you whitelist the HTML tags you want to allow. For example, you don't want to render script tags.
  3. Markdown.Editor.js - This enables a live preview of the Markdown->HTML conversion. I decided not to use this now because I am am only allowing extremely basic functionality like hyperlinks, lists, bolds and italics. Maybe someday I will revisit this.

Download the Markdown.Converter.js and Markdown.Sanitizer.js from the PageDown project source. You may want to change the list of HTML tags that you want to render. If so, open the Markdown.Sanitizer.js file and find the following line to remove or add tags as appropriate.

var basic_tag_whitelist = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i;  

Once you have made any changes to the Markdown.Sanitizer.js file, update your theme to include them in your Orchard-generated pages. In my case, I added them to my theme's Scripts directory and then added these two lines to my Layout.cshtml file:

 Script.Include("Markdown.Converter.js");  
 Script.Include("Markdown.Sanitizer.js");

Rendering and displaying HTML-formatted comments

Once you have the PageDown scripts added to your theme, you will have the capability to render HTML from Markdown, but you need to actually turn it on for comments. I found the easiest way to do this was to use JavaScript to replace the text of the body of each comment with the PageDown-generated HTML when the comment list is displayed. With jQuery this is simple. Just write a function that does the transformation for every P element of a specific class. Here's the code:

$(document).ready(function () {  
 //var converter = new Markdown.Converter();  
 var converter = Markdown.getSanitizingConverter();  
 $('p.commentbody').each(function (ix, commentbody) {  
 var convertedhtml = converter.makeHtml($(commentbody).html());  
 $(commentbody).html(convertedhtml);  
 })  
});

I created a separate JavaScript file to hold that function that I call CommentMarkdownApply.js. This file also is placed in my theme's Scripts folder and loaded via a Script.Include call in the Layout file.

Updating the shape

Finally you need to wrap the comments' body text with the "commentbody" class that is used in the CommentMarkdownApply script and remove the automatic conversion of newlines to
tags that Orchard does when it renders comments. Individual comments are rendered via the ListOfComments shape, so you can create or update an alternate ListOfComments.cshtml file with the changes. To override the standard comment body display, you would just change this

<p class="text">@(new MvcHtmlString(Html.Encode(comment.Record.CommentText).Replace("\r\n", "<br />\r\n")))</p>  

to

<p class="commentbody">@(new MvcHtmlString(Html.Encode(comment.Record.CommentText)))</p>  

Upload all your new theme files and you're done. Happy blogging!

comments powered by Disqus