I’m a big fan of Twitter’s Bootstrap html/css/javascript framework, and use it on practically all new web projects that I work on. It makes it super easy to quickly knock up a slick-looking web application, and since it’s built on less it’s really easy to customize the look of each site.

That said, the markup is complex enough that when developing sites I typically have the docs open in another tab at all times as a reference point, which lead me to start building little HtmlHelper extensions to create the more complicated elements, such as navbars, forms, etc. These extensions have been bounced around from project to project, and have ended up a little scrappy as they’ve been built as-and-when with no real planning, but they have been hugely useful, so I decided it was finally time to look at rewriting them. Check out the Bootstrap Extensions repo over on GitHub, or have a browse through the documentation (design somewhat inspired by the original bootstrap docs!).

The library is by no means complete, as of writing this I’ve only implemented lists, buttons, button groups + toolbars, navbars and progress bars; but it’s a start, and I intend to cover the majority of the more involved elements. I’ll also look at fine tuning the API to make development as pleasurable as possible.

Update: This project has been included on The Big Badass List of Twitter Bootstrap Resources. Check it out, there’s some brilliant useful stuff on there
<div class='box'>
    <h2 style='-webkit-user-select: none;'>Title</h2>
    <div class='boxSlide'>
        <div class='boxBg'>
            <div class='boxContent'>
                content...
            </div>
        </div>
        <div class='boxFooter'><img src='img/ws_box_footer.png'></div>
    </div>
</div>

Apologies for the above code. I realise it’s not very pleasant to look at, but unfortunately I was working on a website not too long ago which was based off of an online template, and this was the structure I’d been asked to use to add some fancy, styled boxes to a whole bunch of pages so as not to break the existing site’s css.

Now that’s quite a lot of markup for a simple section – please understand I’d be far happier using cleaner and more semantic markup, such as section, article, or even a single div if needsbe – but unfortunately that wasn’t an option. However, even if that was the code that I had to use, it sure as hell wasn’t the code I was going to write. Not over and over and over…

I first wrote a HtmlHelper extension method which would allow me to use the syntax @Html.Section(“header”, “content…”), which was definitely a marked improvement on all that code, and lead to much more readable source.

public static MvcHtmlString Section(this HtmlHelper html, string header, string content) {
   return MvcHtmlString.Create(
              "<div class='box'>" +
                  "<h2 style='-webkit-user-select: none;'>" + title + "</h2>" +
                  "<div class='boxSlide'>" +
                      "<div class='boxBg'>" +
                          "<div class='boxContent'>" +
                              content +
                          "</div>" +
                      "</div>" +
                      "<div class='boxFooter'><img src='img/ws_box_footer.png'></div>" +
                  "</div>" +
              "</div>";
}

Job done. Well, kind of. This worked well for just text-only sections. A section containing multiple paragraphs, images, or other html elements was possible, but looked a mess and was harder to read that the original syntax! It completely ruled out the option of using more complicated contents in a section – ie. if I wanted a section to contain a form. Furthermore, these boxes were nestable – so one box could potentially contain multiple. Since they took an string as content and returned an MvcHtmlString, then in addition to these problems I would have had to keep adding .ToString() to the end of each nested Html.Section().

@using (Html.BeginForm()) { ... }

How many times have we all used the above code? And what does it do? Well that’s easy, it’s an HtmlHelper for creating forms. The interesting thing with BeginForm, however, is that unlike most other HtmlHelpers, this allows for start and end tags, but with any other content nested within the curly braces (or if you prefer, open/close mustaches).

Oh what a coincidence, that sounds almost exactly like what I need to do!

So how does it work? Well fortunately, the solution is brilliantly easy. When you call BeginForm, it first outputs the opening

tag, not by returning an MvcHtmlString, but by writing directly to the view context using HtmlHelper’s htmlHelper.ViewContext.Writer.Write(string). It then returns a class implementing IDisposable (in this instance, an MvcForm), which is passed the view context when instantiated. All this class does is to write out to the view context when it is being disposed of – which as we all know is at the close of the braces.

Therefore, the code needed to allow me the freedom to write my sections as

@using (Html.Section("title here")) {
    ... any content I want! ...
}

is as follows:

public static HtmlSection Section(this HtmlHelper html, string title)
{
    html.ViewContext.Writer.Write(
              "<div class='box'>" +
                  "<h2 style='-webkit-user-select: none;'>" + title + "</h2>" +
                  "<div class='boxSlide'>" +
                      "<div class='boxBg'>" +
                          "<div class='boxContent'>"
        );
    return new HtmlSection(html.ViewContext);
}


public class HtmlSection : IDisposable
{
    private readonly ViewContext _viewContext;

    public HtmlSection(ViewContext viewContext)
    {
        _viewContext = viewContext;
    }

    public void Dispose()
    {
        _viewContext.Writer.Write(
                          "</div>" +
                      "</div>" +
                      "<div class='boxFooter'><img src='img/ws_box_footer.png'></div>" +
                  "</div>" +
              "</div>"
        );
    }
}