Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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).

share|improve this question

4 Answers 4

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

@helper ShowIfNotNull(string header) {
    @if (!string.IsNullOrEmpty(header))
        @:<h2>header</h2>
    }
}

<h1>@Model.Title</h1>
@ShowIfNotNull(Model.Subtitle)
share|improve this answer
2  
Hadn't heard of @helper before, that's pretty useful. –  Jeroen Vannevel May 29 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 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 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 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>
}
share|improve this answer
    
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 at 18:07
    
Great! Feel free to give @EricB a well-earned checkmark :) –  Mat's Mug May 29 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

share|improve this answer
    
Outtathebox, +1! With the appropriate selector this may just work, and it's semantically quite "correct" for several of my cases. –  Jeroen May 30 at 16:25
    
could you add more explanation from the outside link into your answer, that way if the link dies the information is still here on the Answer –  Malachi May 30 at 16:41
up vote 0 down vote accepted

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) {
    if (!string.IsNullOrEmpty(header)) {
        <h2>@header</h2>
    }
}

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")
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.