Layout page and Blank Layout Page in ASP.NET MVC

Here’s the scenario: I want a “master” page for most pages on my ASP.NET MVC site, but I also have a few pages that don’t play along.  Maybe these are pop-ups that don’t need the standard menus, maybe they don’t need the left column, etc.  I could create two totally separate Layout.cshtml pages, but I really don’t want to do that.  I really want all the “standard” stuff in both: CSS reset, jQuery references, etc, etc.

Here’s the technique I use.  I create one layout page I’ll call _Blank.cshtml with the core scripts and links but no “chrome” — no content.  I’ll create a second page called _Layout.cshtml with the site theme content in it.  For the majority of pages, I get the standard _Layout.cshtml, for those few pages that need their own custom layout, they can inherit from _Blank.cshtml without having to reinvent the wheel.

Here’s _Blank.cshtml:

<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js ie6 oldie ie" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7 oldie ie" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8 ie" lang="en"> <![endif]-->
<!--[if IE 9]> <html class="no-js ie9 ie" lang="en"> <![endif]-->
<!--[if IE 10]> <html class="no-js ie10 ie" lang="en"> <![endif]-->
<!--[if gt IE 10]> <html class="no-js ie" lang="en"> <![endif]-->
<!--[if !IE]>--> <html class="no-js" lang="en"> <!--<![endif]-->
<head>
 <meta charset="utf-8" />
 <title>@ViewBag.Title</title>
 <meta name="viewport" content="width=device-width,initial-scale=1" />
 <link rel="icon" type="image/x-icon" href="/favicon.ico" />
 <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/2.1.0/normalize.css" />
 <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/start/jquery-ui.css" />
 @RenderSection("head", required: false)
</head>
<body>
@RenderBody()
<!--[if lt IE 9]>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<![endif]-->
<!--[if gte IE 9]><!-->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<!--<![endif]-->
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.11.1/jquery.validate.min.js"></script>
<script src="/js/libs/jquery.unobtrusive-ajax-2.0.30116.0.min.js"></script>
<script src="/js/libs/jquery.validate.unobtrusive-2.0.30116.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.0.0/moment.min.js"></script>
<script src="/js/init.js"></script>
@RenderSection("scripts", required:false)
<script>
var _gaq=[['_setAccount','UA-xxxxxxxx-1'],['_trackPageview']];
(function(d,t){
 "use strict";
 var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
 g.src=('https:'===location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
 s.parentNode.insertBefore(g, s);
}(document,'script'));
</script>
</body>
</html>

And heree’s _Layout.cshtml:

@{
 Layout = "~/Views/Shared/_Blank.cshtml";
}
@section head {
 <link rel="stylesheet" href="/css/Site.css" />
 @RenderSection("head", required: false)
}
@section scripts {
 <script src="/js/layout.js"></script>
 @RenderSection("scripts", required: false)
}
<div class="page">
 <header class="clearfix">
   <img src="/img/logo.jpg" alt="The logo" />
   <nav class="clearfix">
     <ul>
       @if ( Html.CurrentUserIsAuthenticated() ) {
         <li>Welcome @Html.CurrentUserName() @Html.ActionLink("Logout", "Logout", "Account")</li>
       } else {
         <li>@Html.ActionLink("Login / Register", "Login", "Account")</li>
       }
       <li><a href="/">Home</a></li>
       <li><a href="/Home/about-us">About Us</a></li>
       <li><a href="/Home/contact-us">Contact Us</a></li>
     </ul>
   </nav>
 </header>
 <div id="main" class="clearfix">
   @RenderBody()
 </div>
 <footer>
   Copyright My Company &copy; @DateTime.Now.Year. All Rights Reserved. | 
 Site built by <a href="http://www.richardsonandsons.com" target="_blank">Richardson &amp; Sons, LLC</a> | 
   <a href="/Home/terms-of-use" class="bot_hyper">Terms of Use</a> | 
   <a href="/Home/privacy-policy" class="bot_hyper">Privacy Policy</a>
 </footer>
</div>

Of course you may need more or less than this.  Maybe you need to reference lo-dash or don’t need moment.  Maybe your blank page doesn’t need an init script.  The methodology is the same though.  A _Blank.cshtml with “a blank page” (and all the scripts), and a _Layout.cshtml with all the standard template content.

Happy coding!

Rob