Because empty tags are bad
By eidias on (tags: mvc, categories: code)Well, not always, but there are times when they are so…what can I do to avoid them.
Up to asp.net mvc 3 there’s a problem – if I want to render something wrapped in let’s say a paragraph, but I don’t want that paragraph to appear if the content is empty, then the markup looks like this:
1: @if (!string.IsNullOrEmpty(content)) {
2: <p>@content</p>
3: }
That’s a bit verbose. If I skip that check, then an empty hole is rendered on the page so again – not good.
What I came up with today is this:
1: @Html.SafeWrap(@<text>@content</text>)
The <text> tags are Razors way of saying render pure so as a result, this will render just the value of content variable. The nice thing about this is that you can do things like this:
1: @Html.SafeWrap(
2: @<text>
3: <h2>@title</h2>
4: <span class="hint">@hint</span>
5: <blockquote>@content</blockquote>
6: </text>, "div", new { @class = "fancy" })
The two last parameters are optional and have defaults but are there for greater flexibility. So without further ado, here’s the code:
1: public static class HtmlHelperExtensions
2: {
3: public static IHtmlString SafeWrap(this HtmlHelper html, Func<ViewContext, HelperResult> innerHtml, string tagName = "p", object attributes = null)
4: {
5: return SafeWrap(html, innerHtml, tagName, HtmlHelper.AnonymousObjectToHtmlAttributes(attributes));
6: }
7:
8: public static IHtmlString SafeWrap(this HtmlHelper html, Func<ViewContext, HelperResult> innerHtml, string tagName, IDictionary<string, object> attributes)
9: {
10: var gut = innerHtml(html.ViewContext).ToHtmlString().Trim();
11: if (string.IsNullOrEmpty(gut))
12: return MvcHtmlString.Empty;
13:
14: var builder = new TagBuilder(tagName);
15: builder.MergeAttributes(attributes, true);
16: builder.InnerHtml = gut;
17:
18: return new MvcHtmlString(builder.ToString());
19: }
20: }
Cheers