If you’ve ever worked on a project that uses a StringBuilder to build up their html in some way or another you may agree that it can get pretty messy and hard to maintain.

One improvement we have made recently in a project that I am involved in is to make use of an html tag library to assist in this regard. I particularly like the implementation that FubuMVC has come up with so I’ll show you some of the things we are doing with it in our ASP.NET MVC web project.

In order to reference the HtmlTag library you will need to pull down the Fubu source and compile it, after which you can take the .dll and place it in your lib folder and add a reference as normal.

Most operations you can perform with the HtmlTag class will return ‘this’ enabling you to chain your calls in fluent interface fashion.

In ASP.NET MVC you get an HtmlHelper property called Html that is accesible to your view that is a nice place to hook up extension methods to make use of the tag library. One of the first things we did was this:

public static HtmlTag Link(this HtmlHelper helper, string linkText, string url)
{
    return new HtmlTag("a").Text(linkText).Attr("href", url).UnEncoded();
}

The UnEncoded portion is just to let you use characters that would otherwise be escaped such as this right arrow: ► (&#9658) because HtmlTag writes its content out via HtmlTextWriter.WriteEncodedText by default unless you instruct it not to.

So now say you want those links to open in a new browser.

<%= Html.Link("Google", "http://www.google.com").Attr("target", "_blank") %>

However this is common enough thing that we can put it behind a reusable extension method like this:

public static HtmlTag OpenNew(this HtmlTag tag)
{
    return tag.Attr("target", "_blank");
}

And from then on simply call:

<% Html.Link("Google", "http://www.google.com").OpenNew() %>

We style offsite links differently to inform users that what they are clicking on is going to navigate them away from the site they are currently on.

With the tag library as is, we can already do this:

<% Html.Link("Google", "http://www.google.com").OpenNew().AddClass("off-site") %>

But again, if we are going to be doing this often enough and want other developers to be consistent in the way they approach this, its nice to put it behind another extension method.

public static HtmlTag Offsite(this HtmlTag tag)
{
    return tag.AddClass("off-site").OpenNew();
}

And then on our page:

<%= Html.Link("Google", "http://www.google.com").Offsite() %>

Find yourself setting a particular attribute often? A good candidate for something like this:

public static HtmlTag TabIndex(this HtmlTag tag, int index)
{
    return tag.Attr("tabindex", index.ToString());
}

Instead of writing out <a href="mailto:asdf@asdf.com">asdf@asdf.com</a> you can create the following:

public static HtmlTag MailLink(this HtmlHelper helper, string emailAddress)
{
    return helper.Link(emailAddress, string.Format("mailto:{0}", emailAddress));
}

And then call:

<%= Html.MailLink("asdf@asdf.com") %>

If you can identify some consistent patterns of what your markup needs to look like to achieve a particular look and feel, you can abstract it away using an approach like this and hopefully make it easier to reuse.

blog comments powered by Disqus