# How to write elegant conditional bits of markup in Razor views?

Suppose the following model:

public class ViewBookModel
{
public string Title { get; set; }
public string Subtitle { get; set; }
}


I'm currently rendering it like this in my Razor view:

<h1>@Model.Title</h1>
@if (Model.Subtitle != null)
{
<h2>@Model.Subtitle</h2>
}


My question is about the Subtitle bit. The above approach feels a little clunky, and can get repetitive (which is probably a bad sign) at times.

Are there any better, less verbose, more elegant ways to handle this situation?

I had considered (a) the option now mentioned in Mat's Mug's answer, as well as (b) moving the condition to the model:

public class ViewBookModel
{
// ...
public string ShowSubtitle {
get { return string.IsNullOrEmpty(Subtitle); }
}
}


With this change to the view:

@if (Model.ShowSubtitle)


However, that doesn't address my main issue: the verbosity (i.e. 4 lines of view code just to display Subtitle).

-

If you find a pattern getting too repetitive, you can use @helper instead:

@helper ShowIfNotNull(string header) {
}
}

<h1>@Model.Title</h1>
@ShowIfNotNull(Model.Subtitle)

-
Hadn't heard of @helper before, that's pretty useful. –  Jeroen Vannevel May 29 '14 at 17:00
Welcome to Code Review! Nice first post, I hope you keep reviewing! Feel free to meet the regulars in Code Review Chat :) –  Mat's Mug May 29 '14 at 17:02
Thanks again. After some tweaks for syntax (I've suggested it as an edit) this worked for me. I've also added a version that is exposed as an HtmlHelper extension, that allows you to choose the wrapper tag. –  Jeroen Jul 6 '14 at 9:40
@EricB: Alas, my edit was rejected as "too radical". A fair point I guess, though if you agree with my suggestions feel free to merge it into yours and I'll happily change my "Accept" mark to your answer again and delete my own. –  Jeroen Jul 6 '14 at 15:15

Subtitle being a string, a more elegant way of testing whether it's null would be to use string.IsNullOrEmpty(Model.Subtitle), like this:

<h1>@Model.Title</h1>
@if (!string.IsNullOrEmpty(Model.Subtitle))
{
<h2>@Model.Subtitle</h2>
}

-
Thanks for your review! I had considered this (should've had a "What I've tried" section in my question, I guess; but as an answer it may help future visitors here equally well). My main concern however was with the verbosity, as addressed by Eric B's answer. –  Jeroen May 29 '14 at 18:07
Great! Feel free to give @EricB a well-earned checkmark :) –  Mat's Mug May 29 '14 at 18:24

To give an alternate solution: you can do this with pure CSS(3) using the :empty selector.

h2:empty{
display:none
}


The :empty selector will match on all empty tags. 'Empty' can include html comments, but not white space.

here's a more detailed explanation

-
Outtathebox, +1! With the appropriate selector this may just work, and it's semantically quite "correct" for several of my cases. –  Jeroen May 30 '14 at 16:25

My answer was originally an edit to @EricB's post, but that edit got rejected by a mod, suggesting it was better suited as a competing answer. If this answer helps you, please consider responding to (upvoting ;)) his answer.

If you find a pattern getting too repetitive, you can use @helper instead:

@helper ShowIfNotNull(string header) {
}
}


And use it like this:

<h1>@Model.Title</h1>
@ShowIfNotNull(Model.Subtitle)


Alternatively, you can create an HtmlHelper extension that does the same thing:

public static class StringExtensions
{
public static IHtmlString ShowIfNotNull(this HtmlHelper htmlHelper, string text, string tagName)
{
var builder = new TagBuilder(tagName);
builder.SetInnerText(text);
return new HtmlString(builder.ToString());
}
}


Which can be called like this:

@Html.ShowIfNotNull(Model.Subtitle, "h2")

-