Razor helpers with razor content

Adding a little more DRY to Razor scripts.

If you find yourself adding the same boilerplate code over and over again in your razor scripts:

<div class="this">
  <div class="that">
    foo
  </div>
<div>

You’ll do yourself a favour if you add a helper:

@helper DivThisThat(string contents)
{
    <div class="this">
        <div class="that">
            @contents
        </div>
    </div>
}

Which means you can write:

@DivThisThat("foo")

– Ok. But. What if we want this to be available globally? In every Razor script.

Just add the helper to a Razor file inside the App_Code folder, call it /App_Code/GlobalHelpers.cshtml , that way you can use it everywhere like:

@GlobalHelpers.DivThisThat("foo")

– Ok. But. Simple text is not enough, I like to use this and include custom razor.

Like this:

@GlobalHelpers.DivThisThat(
  @<div class="thus">foo</div>
)

You can, just change the signature of your helper to this:

@helper DivThisThat(Func<string, HelperResult> template)
{
    <div class="this">
        <div class="that">
            @template("")
        </div>
    </div>
}

– Ok. But. What’s that empty string?

It writes text out to your template. Let’s say you like to do a helper for displaying a list, and you like to optionally write something special if the list is empty. Then you can create this helper:

@helper ListIfContent(List<string> someList, Func<string, HelperResult> liTemplate, Func<string, HelperResult> emptyTemplate)
{
    if (someList.Any())
    {
    <ul>
        @foreach (var i in someList)
        {
            @liTemplate(i)
        }
    </ul>
    } else {
        @emptyTemplate("")
    }
}

Use like this:

@GlobalHelpers.ListIfContent(someList,@<li class="whatever">@item</li>,@<p>No data</p>)

And the result is this if the list is not empty:

<ul>
  <li class="whatever">one</li>
  <li class="whatever">two</li>
</ul>

And this if the list is empty:

<p>No data</p>

Notice “@item” in the first template, that’s where the helper writes the string content.

– Cool. But I tried it and got errors:

@GlobalHelpers.DivThisThat(
  @<div class="thus">foo</div>
  @<div class="the">bar</div>
)

You can only add one helper result to the function, but you can easily use them together by adding the text tag:

@GlobalHelpers.DivThisThat(@<text>
  <div class="thus">foo</div>
  <div class="the">bar</div>
</text>)

2 thoughts on “Razor helpers with razor content