.NET Forge CMS

english russian
Hello, Guest! Log In Registration

How to add syntax highlighting to .NET Forge CMS forum

How to add syntax highlighting to .NET Forge CMS forum

In this article I will show how to add syntax highlighting feature to .NET Forge CMS forum, by writing about 50 lines of code.

.NET Forge CMS forum post editor allows you to insert code snippets to you post, but when you add post you’ll see gray text like this:

image

Unfortunately, our system do not have code highlighting feature in forums, but on sites such as ours or gotdotnet.ru highlighting do exists. It is made as a custom feature, using third-party free highlighting javascript plugin. It could be easily integrated in any our site. So, let’s begin.

First of all, to make an example integration I installed “Community site” solution from the list of available fast to deploy sites in CMS installation wizard. I have chosen that solution because it have forum with some posts ready to work with. Of course, our intergration won’t depend on this particular solution.

Now we have a forum, let’s get highlighting plugin itself. It is called Syntax Highlighter, and can be downloaded on product download page on site of it’s developer. The product archive contains quite a lot of files, basically we need these:

  • /scripts/shCore.js – plugin core script
  • /styles/shCore.css – common styles
  • /styles/shCoreDefault.css – default color scheme styles
  • Js files from brushes folder – we need to select highlighting brushes for needed languages, in this example we will use files for C# and SQL - shBrushCSarp.js, shBrushSql.js

Then we put these scripts to /js folder in our site, and style – to /css folder. Now, we have to incude references to them in our template.master, between <head> and </head> tags:

<<%= "link" %> rel="stylesheet" type="text/css" href="<%= SitePath %>/css/shcore.css" /> 
<<%= "link" %> rel="stylesheet" type="text/css" href="<%= SitePath %>/css/shcoredefault.css" /> 
<script type="text/javascript" src="<%= SitePath %>js/shCore.js"></script> 
<script type="text/javascript" src="<%= SitePath %>js/shBrushSQL.js"></script> 
<script type="text/javascript" src="<%= SitePath %>js/shBrushCSharp.js"></script> 

Now we need to write some code on our own, the code that will find all blocks that have to be highlighted and will call highlight method of our plugin on all them. Let’s create main.js file in /js folder in fill it with the following code:

if (typeof (MySite) == "undefined")
	MySite = new Object();
//helper method, searches brush from collection by name
MySite.findBrush = function (brushName, brushes) {

	for (var brush in brushes) {
		if (!brushes.hasOwnProperty(brush))
			continue;
		var br = brushes[brush];
		if (!br.aliases)
			continue;
		for (var i = 0; i < br.aliases.length; i++)
			if (br.aliases[i] == brushName)
				return true;
	}
	return false;
}
//find all blocks of code that requires highlighting and calls SyntaxHighlighter.highlight for all of them
MySite.HighlightCode = function () {

	var element = document.getElementById('content');
	if (!element)
		return;

	var tagss = element.getElementsByTagName('PRE');
	if (!tagss || !tagss.length)
		return;

	var tags = [];
	for (var i = 0; i < tagss.length; ++i)
		tags.push(tagss[i]);

	for (var i = 0; i < tags.length; ++i) {
		var tag = tags[i];
		var parentNode = tag.parentNode; if (!parentNode || parentNode.tagName != 'DIV' || (parentNode.className != 'forum-code-box' && parentNode.className != 'blog-code-box'))
			continue;

		var brush = tag.className;
		if (MySite.findBrush(brush, SyntaxHighlighter.brushes))
			SyntaxHighlighter.highlight({ brush: brush }, tag);
		else
			SyntaxHighlighter.highlight({ brush: "c#" }, tag);
	}
}
//Creates forum quotation processor for right displaying code when qouting, this code executes
//when user click on "quote" link and returnes code text without makrup added by syntax highlighter. Next this text will
//become quote text 

if (typeof (Bitrix) == "undefined")
	Bitrix = new Object();
if (typeof (Bitrix.ForumQuotationProcessors) == "undefined")
 Bitrix["ForumQuotationProcessors"] = new Object();

Bitrix.ForumQuotationProcessors["SyntaxHighlighter"] = function (html) {

	var m = null;
	if (typeof (window.SyntaxHighlighter) != "undefined"){
		var m = (/\<div[^\>]*?class=\"syntaxhighlighter[^\"]*\"[^\>]*?\>/i).exec(html);
		if(m!=null){
			m = (/\<div[^\>]*?id=\"?(\w+)\"?[^\>]*?\>/i).exec(m[0]);

			if(m!=null && m[1] in window.SyntaxHighlighter.vars.highlighters)
				return window.SyntaxHighlighter.vars.highlighters[m[1]].code;
			}
		}
	return null;
} 

Adding another reference to main.js to template.master between <head> and </head>:

<script type="text/javascript" src="<%= SitePath%>js/main.js"></script>

And the last thing – we have to register a call to our HighlightCode method as startup script, so it will be executed after a page is successfully loaded. Let’s use RegisterStartupScript of Page.ClientScript object to achieve this. We can put this code in template.master or just in forum page:

protected override void OnLoad(EventArgs e)
{
   base.OnLoad(e);		    
Page.ClientScript.RegisterStartupScript(Page.GetType(), "highlightcode", "MySite.HighlightCode();", true);
}

Now, if everything was done right, we’ll see our code highlighted after page reload:

image