Geeks With Blogs

News
Elton Stoneman (@EltonStoneman) IT Consultant, integration specialist, @Microsoft MVP and @Pluralsight author.

[Source: http://geekswithblogs.net/EltonStoneman]

Keeping up the fluent work, I've put together a fluent interface which wraps the framework HtmlTextWriter. For ASP.NET MVC, this makes generating HTML in extension methods to HtmlHelper safer than string.Format() and more readable than HtmlTextWriter:

public static string Image(this HtmlHelper helper, string imageRelativeUrl, string altText)

{

return FluentHtmlTextWriter.Begin()

.WriteTag(HtmlTextWriterTag.Img)

.WithAttribute(HtmlTextWriterAttribute.Src, GetImageUrl(imageRelativeUrl))

.WithAttribute(HtmlTextWriterAttribute.Alt, altText)

.End();

}

The equivalent using HtmlTextWriter is:

public static string Image(this HtmlHelper helper, string imageRelativeUrl, string altText)

{

StringBuilder htmlBuilder = new StringBuilder();

HtmlTextWriter writer = new HtmlTextWriter(new StringWriter(htmlBuilder));

 

writer.AddAttribute(HtmlTextWriterAttribute.Src, GetImageUrl(imageRelativeUrl));

writer.AddAttribute(HtmlTextWriterAttribute.Alt, altText);

writer.RenderBeginTag(HtmlTextWriterTag.Img);

writer.RenderEndTag();

writer.Flush();

 

return htmlBuilder.ToString();

}

Unlike the framework writer, you're not constrained to specify attributes in any particular order, and tags which aren't nested can be written with a single WriteTag(), rather than BeginTag() and EndTag() calls. The writer copes with multi-level tag hierarchies - this sample builds a Superfish CSS menu:

FluentHtmlTextWriter writer = FluentHtmlTextWriter.Begin();

 

writer.BeginTag(HtmlTextWriterTag.Ul)

.WithAttribute(HtmlTextWriterAttribute.Id, "menu.Name")

.WithAttribute(HtmlTextWriterAttribute.Class, "sf-menu sf-vertical");

.BeginTag(HtmlTextWriterTag.Li)

.BeginTag(HtmlTextWriterTag.A)

.WithAttribute(HtmlTextWriterAttribute.Class, "sf-with-ul")

.WithAttribute(HtmlTextWriterAttribute.Href, "#")

.WithValue("Link 1")

.WriteTag(HtmlTextWriterTag.Span)

.WithAttribute(HtmlTextWriterAttribute.Class, "sf-sub-indicator")

.WithValue("»")

.EndTag()

.EndTag()

.EndTag();

 

string html = writer.End();

Assert.AreEqual("<ul id=\"menu.Name\" class=\"sf-menu sf-vertical\">\r\n\t<li><a class=\"sf-with-ul\" href=\"#\">Link 1<span class=\"sf-sub-indicator\">&#187;</span></a></li>\r\n</ul>",

html);

The HtmlTextWriter equivalent is unthinkable.

Patrik Hägne has an alternative fluent HtmlTextWriter implementation, which is nicely put together, but I wanted slightly different functionality. Firstly I wanted to get the HTML string from the writer directly, without needing to instantiate a StringBuilder and StringWriter. Secondly I wanted minimal new code – Patrik uses a separate class to manage writing attributes, and has specific functions for known tag types. Thirdly, I didn't really like Patrik's syntax, with the need to specify the tag type when you write an end tag – and when tags aren't nested, I wanted to write them in a single unit:

string html = FluentHtmlTextWriter.Begin()

.WriteTag(HtmlTextWriterTag.Span)

.WithAttribute(HtmlTextWriterAttribute.Id, "id_span")

.WithValue("contents_span")

.End();

Assert.AreEqual("<span id=\"id_span\">contents_span</span>", html);

My version is on MSDN Code Gallery here: FluentHtmlTextWriter. It works by building up a list of actions when you start writing a tag, and flushing them in the correct order to an internal HtmlTextWriter when you start writing the next tag. When you call End() it flushes the internal writer and outputs its contents. An alternative constructor lets you write directly to an output stream, in which case you can Flush() the writer and don't need to call End().

The current implementation only deals with basic tag, attribute and style functionality, and doesn't include optional HTML encoding overloads. It's only 75 lines of code, and extending it should be trivial.

There is a negligible performance hit in using FluentHtmlTextWriter – running the image tag generation code above 20,000 times on my dev machine, the fluent version takes between 0.01and 0.02 seconds longer than the framework version (on average 0.07 seconds compared to 0.05).

Posted on Thursday, September 10, 2009 7:32 PM Code Gallery , Fluent | Back to top


Comments on this post: FluentHtmlTextWriter

# re: FluentHtmlTextWriter
Requesting Gravatar...
This looks very interesting. I have downloaded the source and am anxious to pour over it. Thanks for posting.
Left by Nick Harrison on Apr 14, 2010 8:58 PM

# re: FluentHtmlTextWriter
Requesting Gravatar...
Really its one of the fabulous post and I just like to say you,its very informative blog which I like a lot.Thanks a lot.
Left by scrapbook pages56 on Jun 11, 2010 6:06 AM

# re: FluentHtmlTextWriter
Requesting Gravatar...
Hey I just got through with the pages, I should say Pretty nice work done there.Thanks for sharing your ideas!!I really appreciate it!Keep blogging.
Left by USANA_478 on Aug 30, 2010 5:46 AM

# re: FluentHtmlTextWriter
Requesting Gravatar...
Having written articles that require this much work.I am very happy with your post. Some things in here I have not thought about before.Thanks for the share!Waiting for your next upcoming post.
Left by pain management on Oct 08, 2010 8:26 AM

# re: FluentHtmlTextWriter
Requesting Gravatar...
The latest release of MvcContrib predates FluentHtml, so it’s not in any binary download. You must get the source and build it. There is a file “ClickToBuild.bat” in the trunk which puts the binaries in the “build” folder.
Left by firewall rule audit on Oct 25, 2010 3:21 PM

# re: FluentHtmlTextWriter
Requesting Gravatar...
Good information - I found it helpful
Left by Usana Vitamins on Nov 01, 2010 7:28 PM

# re: FluentHtmlTextWriter
Requesting Gravatar...
I really enjoy participating in this community and see which other people in your industry are getting Shoutouts.
Left by Christian Woman on Nov 11, 2010 4:57 AM

# re: FluentHtmlTextWriter
Requesting Gravatar...
thanks mate. look forward to more of the same.
Left by compare exchange rates on Dec 14, 2010 12:53 AM

# re: FluentHtmlTextWriter
Requesting Gravatar...
really? I didn't realise it was so simple!
Left by ufo videos on Dec 14, 2010 12:54 AM

# re: FluentHtmlTextWriter
Requesting Gravatar...
thanks for this
Left by free home phone service on May 13, 2011 11:41 PM

# re: FluentHtmlTextWriter
Requesting Gravatar...
great information
Left by Weekly options on May 13, 2011 11:43 PM

# re: FluentHtmlTextWriter
Requesting Gravatar...
Incredible article :-) London Indian escorts
Left by Londons Escorts on Jun 05, 2011 12:32 AM

# re: FluentHtmlTextWriter
Requesting Gravatar...
great blog and nice <ahref="http://www.ricksdrivingschoolbristol.co.uk">
escort services
Left by life insurance on Apr 10, 2012 10:38 AM

Your comment:
 (will show your gravatar)


Copyright © Elton Stoneman | Powered by: GeeksWithBlogs.net | Join free