It is important to have a consistent look and feel across
all of the pages within your web-site/application. ASP.NET 2.0 introduced
the concept of “master pages” which helps enable this when using .aspx based
pages or templates. Razor also supports this concept using “layout pages”
– which allow you to define a common site template, and then inherit its look
and feel across all the views/pages on your site.
Simple Layout Example
Below is a simple example of a layout page – which we’ll
save in a file called “SiteLayout.cshtml”. It can contain any static HTML
content we want to include in it, as well as dynamic server code. We’ll
then add a call to the “RenderBody()” helper method at the location in the
template where we want to “fill in” specific body content for a requested URL:
We can then create a view template called “Home.cshtml” that
contains only the content/code necessary to construct the specific body of a
requested page, and which relies on the layout template for its outer content:
Notice above how we are explicitly setting the
“LayoutPage” property in code within our Home.cshtml file. This indicates
that we want to use the SiteLayout.cshtml template as the layout for this
view. We could alternatively indicate the layout file we want to use
within a ASP.NET MVC Controller invoking Home.cshtml as a view template, or by
configuring it as the default layout to use for our site (in which case we can
specify it in one file in our project and have all view templates pick it up
automatically).
When we render Home.cshtml as a view-template,
it will combine the content from the layout and sub-page and send the following
content to the client:
Compact, Clean, Expressive Code
One of the things to notice in the code above is that the
syntax for defining layouts and using them from views/pages is clean and minimal.
The code screen-shots above of the SiteLayout.cshtml and Home.cshtml files
contain literally all of the content in the two .cshtml files – there is no
extra configuration or additional tags, no <%@ Page%> prefix, nor any
other markup or properties that need to be set.
We are trying to keep the code you write compact, easy and
fluid. We also want to enable anyone with a text editor to be able to
open, edit and easily tweak/customize them. No code generation or
intellisense required.
Layout/MasterPage Scenarios – Adding Section Overrides
Layout pages optionally support the ability to define
different “sections” within them that view templates based on the layout can
then override and “fill-in” with custom content. This enables you to
easily override/fill-in discontinuous content regions within a layout page, and
provides you with a lot of layout flexibility for your site.
For example, we could return to our SiteLayout.cshtml file
and define two sections within our layout that the view templates within our
site can optionally choose to fill-in. We’ll name these sections “menu”
and “footer” – and indicate that they are optional (and not required) within
our site by passing an optional=true parameter to the RenderSection() helper
call (we are doing this using the new C# optional parameter syntax that I’ve previously blogged about).
Because these two sections are marked as “optional”, I’m not
required to define them within my Home.cshtml file. My site will continue
to work fine if they aren’t there.
Let’s go back into Home.cshtml, though, and define a custom
Menu and Footer section for them. The below screenshot contains all of
the content in Home.cshtml – there is nothing else required in the file.
Note: I moved setting the LayoutPage to be a site wide setting – which is why
it is no longer there.
Our custom “menu” and “footer” section overrides are being
defined within named @section { } blocks within the file. We chose not to
require you to wrap the “main/body” content within a section and instead to
just keep it inline (which both saves keystrokes and enables you to easily add
sections to your layout pages without having to go back through all your
existing pages changing their syntax).
When we render Home.cshtml as a view-template again, it will
now combine the content from the layout and sub-page, integrating the two new
custom section overrides in it, and send down the following content to the
client: