BBCode extension for BlogEngine.NET 1.2

by Mads Kristensen 5. November 2007 01:15

I wrote a little extension for BlogEngine.NET 1.2 that parses BBCode for use in the comments. BBCode allows you to write square bracket syntax to format your text. It’s smart because it gives more power to the people commenting and it gives you total control over the HTML output because BBCode is not HTML – the parsing takes place server side when the comment is served and not when it is saved.

So, when you write a comment you can now use these few BBCode tags. More will come when I find out which ones make most sense.

Bold
[b]some text[/b]

Italic
[i]some text[/i]

Cite
[cite]some text[/cite]

You can easily add new tags your self by adding a single line in the extension. Also, if you want to be able to write BBCode syntax in your posts, you can easily do that by adding a single line to the constructor of the extension. Just type in this line:

Post.Serving += new EventHandler<ServingEventArgs>(Post_CommentServing);

Safety first

A BBCode parser is not as straight forward to write as you might expect. It’s not just a matter of replacing [b] with <strong> since that can lead to trouble. Let’s say someone writes this comment:

It’s a [b]lovely weather today.

If we just replace [b] with <strong> then the entire page will become bold since the tag is never closed. That means a wrong formatted comment can turn your entire website into something very ugly.

Instead we need to make sure that all BBCode tags are closed before we parse them. This extension will parse all the correctly closed BBCode tags even though there is a malformed tag in the same comment. It simply ignores the malformed tag and moves on and thereby doesn’t screw with the design of the site.

Implementation

Download the BBCode.cs file below and paste it into the /App_Code/Extensions/ folder of your BlogEngine.NET 1.2 installation.

BBCode.zip (721 bytes)

* Only $4.95/month ASP.NET & Windows 2008 + IIS 7 Hosting! FREE SQL Included

Tags: ,

BlogEngine

Comments

11/5/2007 1:50:07 AM #

Josh Stodola

Cool!  Does it support any attributes?

Josh Stodola United States |

11/5/2007 1:56:23 AM #

Mads Kristensen

No, not at this moment and I'm not sure I'll implement that. It only makes sense for applying color and font size and I don't think I want people to do that. What do you think?

Mads Kristensen Denmark |

11/5/2007 2:21:29 AM #

Josh Stodola

You're right, you probably shouldn't allow users to change size or color of the text.

However, I think it'd be awesome to actually allow certain HTML tags and attributes.  You see that on Subtext, and on Wordpress too.  I think that is the ultimate solution.  That would allow commenters to give descriptions and tooltips to links, which is good for SEO.

(I emailed Phil a month or so ago and asked him if he'd be willing to write a post on how Subtext achieves this.  He said he put it on his list of things to do.  What a guy!)

Josh Stodola United States |

11/5/2007 2:45:55 AM #

Mads Kristensen

There is a difference in the way BlogEngine and SubText/WordPress handles links in comments. BlogEngine.NET resolves them automatically without having to enter HTML tags which I strongly prefer. Of course as you mention your self, then people can't use descriptions and tooltips. Still, I believe that auto-resolving links are way better than writing HTML. Then again, both scenarios could be implemented at the same time.

Mads Kristensen Denmark |

11/5/2007 2:53:48 AM #

Josh Stodola

Exactly what I was thinking (both could be implemented).

It is very nice just to paste a URL into the message and have it resolved automatically, but the option to use the tags would be great for accessibility.

Josh Stodola United States |

11/5/2007 2:55:46 AM #

Documentation Nut

I like the idea of implementing both for simple SEO reasons.

Also what is the likelyhood of being able to write extensions to override some of the default behaivor's of BE.NET for better SEO optimization?

Documentation Nut United States |

11/5/2007 3:10:43 AM #

Mads Kristensen

Much of the SEO stuff can be modified and improved in the themes. For the auto resolved comment links, I could move that logic to an extension. Then you can change the behavior there. Are there any specific SEO changes you want done?

Mads Kristensen Denmark |

11/5/2007 3:15:15 AM #

Documentation Nut

I found 1 or 2 but can't find the list right now.  When I find them i'll post them up.  They weren't major at all I just didn't want to bother you with them as i know you'd rather probably concentrate on makeing BE.NET better.

Oh and another question is it possible to store custom xml files that we create for configuring plugin information in the App_Data folder? I keep running into funny "can't find location" error when I try.

I'll keep looking for those notes i made.

Documentation Nut United States |

11/5/2007 3:17:40 AM #

Mads Kristensen

Sure, you can always use the App_Data folder. Use BlogSettings.Instance.StorageLocation to get an absolute path to the folder.

Mads Kristensen Denmark |

11/5/2007 3:27:19 AM #

Documentation Nut

Ok, thanks.  Just wanted to be sure. Maybe I just have a server problem to resolve then.

Documentation Nut United States |

11/5/2007 3:47:33 AM #

Joe

Didn't I send in an extension (about a month ago) that did exactlly this?  I thought I did, but I might have just written it and never done anything with it....

In any case, awesome! I'm glad this is a supported feature now.

Joe United States |

11/5/2007 5:01:28 AM #

Mads Kristensen

@Joe, I did get a BBCode extension sent some time ago. I don't remember from who, but it must be from you. I saw this request from the CodePlex issue tracker and thought about writing the extension www.codeplex.com/.../View.aspx?WorkItemId=4274

I know I had the mail, but I couldn't find it - even when I searched all Outlook folders it didn't turn up. So I had to do it from scratch.

Mads Kristensen Denmark |

11/5/2007 5:37:47 AM #

Davis Sousa

Amazing, Mads! Thanks a lot

Laughing

Davis Sousa Poland |

11/5/2007 9:31:25 PM #

Scott Stocker

Check out what WTF allows for BBCode:

www.worsethanfailure.com/Info/BBCode.aspx

Scott Stocker United States |

11/6/2007 3:16:51 AM #

Ingi Gauti

Is there any reason you are not using regular expression to do the parsing?

Ingi Gauti Denmark |

11/6/2007 3:31:49 AM #

Mads Kristensen

@Ingi

Yes, that's because I don't know how to write a regular expression that checks for equal amounts of opened and closed BBCode tags before doing the parsing.

Mads Kristensen Denmark |

11/6/2007 3:46:06 AM #

Mabyre

Mads you should leet it be done by the editor don't you

Mabyre France |

11/6/2007 6:33:50 AM #

Ingi Gauti

I put to gather the code using regex.

  string s = @"Hello World, this is [cite]some text[/cite] that has bold,
    italic, broken bold and broken italic
    and should just [i]work
";
  
  Response.Write(ParseText(s));

  public string ParseText(string s) {
    string pattern = @"(\[(?<Element>b)\])[^\[]*(\[/(?<Element>b)\])
        |(\[(?<Element>i)\])[^\[]*(\[/(?<Element>i)\])
        |(\[(?<Element>cite)\])[^\[]*(\[/(?<Element>cite)\])";

    s = Regex.Replace(s, pattern, new MatchEvaluator(ReplaceText), RegexOptions.IgnoreCase|RegexOptions.IgnorePatternWhitespace);
  }

  Hashtable map = new Hashtable();
  map.Add("b", "strong");
  map.Add("i", "em");

  public string ReplaceText(Match m) {

    string s = m.Value.Replace("[", "<").Replace("]", ">");

    if (map.ContainsKey(m.Groups["Element"].Value)) {
      s = Regex.Replace(s, "(</?)" + m.Groups["Element"].Value + "(>)",
        "$1" + (string) map[m.Groups["Element"].Value] + "$2");
    }

    return s.ToLower(); //ToLower is for xhtml since all elements should be lower case
  }  

The biggest problem with it is the mapping of b to strong, and i to em, which makes the code little longer.

The key to make regex check if the code is valid is this regex: [^\[]* which tells it to look for any character except [ between e.g. [b] and


If we would skip the mapping of b to strong then this regex would be enough: \[b\][^\[]*\[/b\]

Ingi Gauti Denmark |

11/6/2007 6:53:13 AM #

Ingi Gauti

Ups, didn't go as planned. Hope you can understand the code otherwise I can email it to you. Can't seem figure out how to skip all those smiley faces.

Maybe a missing feature that should be below the comment box, Disable BBCode and smileys

Ingi Gauti Denmark |

11/6/2007 7:45:44 AM #

Joe

Mads, here is how I did it in the version I sent you:

private void FormatForPost(ServingEventArgs comment)
{
    RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline;
    Regex boldEX = new Regex(@"\[B\](?<inner>(.*?))\[/B\]", options); //bold
    
    NestedReplace(comment, boldEX, "<b>${inner}</b>");
}

private void NestedReplace(ServingEventArgs comment, Regex regexMatch, string replaceString)
{
    Match m = regexMatch.Match(comment.Body);
    while (m.Success)
    {
        string tStr = replaceString.Replace("${inner}", m.Groups["inner"].Value);
        comment.Body = comment.Body.Substring(0, m.Groups[0].Index) + tStr + comment.Body.Substring(m.Groups[0].Index + m.Groups[0].Length);
        m = regexMatch.Match(comment.Body);
    }
}

Joe United States |

11/6/2007 7:49:10 AM #

Joe

There may be a bug with the emote. code.  In the comment above (see line 8: "NestedReplace" call)

notice the wink? the line of code should be.  What there would have caused a wink?

NestedReplace(comment, boldEX, "<b>${inner}</b> " ) ;

Joe United States |

11/6/2007 3:33:20 PM #

Cristiano

Good work, Mads! I have added this extension and a little toolbar (with a simply javascript) to auto-insert the BBCode in the comment textArea.
You can view how it work in my site ... Enjoy

Cristiano Italy |

11/10/2007 3:22:18 AM #

Domenic Denicola

Hmm, but it doesn't work in live preview... Frown any idea how to hook that in? Seems like it would be difficult.

Domenic Denicola United States |

11/11/2007 6:32:45 AM #

trackback

Trackback from CristianoFino.NET

Una procedura per quotare automaticamente i commenti in un post

CristianoFino.NET |

11/11/2007 10:22:30 AM #

Dan

I have added this extension and a little toolbar (with a simply javascript) to auto-insert the BBCode in the comment textArea.

Crisitano's implementation is fantastic, and a great looking skin to boot!

Dan United States |

11/21/2007 12:30:59 PM #

Garima

Boo !

Garima United States |

11/21/2007 12:36:54 PM #

Garima

i am so so scared...

Garima United States |

7/29/2008 3:27:27 PM #

XXXVII

I want to include images on comments by this extension. Is it possible?

XXXVII Russia |

8/25/2008 9:00:09 AM #

Siam Sunshine

I want to include images on comments by this extension. Is it possible?

Stylesheet perhaps ??

Siam Sunshine Thailand |

11/12/2008 7:50:09 AM #

Vanetino

Great extension, thanks for the note, it uses.

Vanetino Peru |

Comments are closed

About the slave

Mads Kristensen Mads Kristensen
Web developer at ZYB and founder of BlogEngine.NET. More...

LinkedIn ZYB Facebook Last.fm Twitter View Mads Kristensen's profile on Technorati

The Lounge

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008