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 here’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 © @DateTime.Now.Year. All Rights Reserved. |
Site built by <a href="http://www.richardsonandsons.com" target="_blank">Richardson & 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