Appearance
Are you an LLM? You can read better optimized documentation at /views/layout.md for this page in Markdown format
Layout
This document provides a detailed technical overview of the main layout file, _Layout.cshtml, which serves as the master template for all pages in the application. It defines the common HTML structure, navigation, static assets, and extension points for page-specific content.
_Layout.cshtml: The Master Layout Template
The primary layout of the application is defined in TheExampleApp/Pages/_Layout.cshtml. This Razor view acts as the master page, providing a consistent structure and appearance across the entire site.
Its application to all views is configured globally in _ViewStart.cshtml:
csharp
// TheExampleApp/Pages/_ViewStart.cshtml
@{
Layout = "_Layout";
}1
2
3
4
2
3
4
This simple configuration ensures that any Razor Page view rendered by the application will be wrapped by the _Layout.cshtml template unless explicitly overridden.
_ViewImports.cshtml: Global View Configuration
The _ViewImports.cshtml file (TheExampleApp/Pages/_ViewImports.cshtml) provides global configuration that applies to all Razor views, including the layout. This file is responsible for:
csharp
// TheExampleApp/Pages/_ViewImports.cshtml
@namespace TheExampleApp.Pages
@using Microsoft.AspNetCore.Http;
@using Microsoft.AspNetCore.Mvc.Localization
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Contentful.AspNetCore
@addTagHelper *, TheExampleApp
@inject IViewLocalizer Localizer
@inject TheExampleApp.Configuration.IContentfulOptionsManager Manager1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
Key elements:
- Namespace: Sets the default namespace for all pages to
TheExampleApp.Pages. - Using Directives: Imports common namespaces like
Microsoft.AspNetCore.HttpandMicrosoft.AspNetCore.Mvc.Localization. - Tag Helper Registration: Registers Tag Helpers from ASP.NET Core MVC, Contentful, and the application itself. This enables the use of custom tags like
<vc:meta-tags>,<vc:selected-api>,<vc:locales>, and attributes likeasp-append-versionthroughout the application. - Dependency Injection:
IViewLocalizer Localizer: For internationalization (i18n) of all static text.IContentfulOptionsManager Manager: To access Contentful configuration settings (e.g., Space ID, API keys).
Layout Structure
The _Layout.cshtml file defines the complete HTML5 document structure, from <!DOCTYPE html> to the closing </html> tag. The body is organized using a BEM-like CSS methodology into three main sections within a <main class="main"> container: a header, a content area, and a footer.
<head> Section
The <head> section is responsible for loading metadata and core stylesheets.
html
<!-- TheExampleApp/Pages/_Layout.cshtml -->
<head>
<vc:meta-tags title="@ViewData["Title"]"></vc:meta-tags>
<link rel="stylesheet" href="~/stylesheets/style.css" />
</head>1
2
3
4
5
2
3
4
5
<vc:meta-tags>: This is a custom View Component responsible for rendering all<meta>tags, including the page title. It receives the title from theViewData["Title"]dictionary, which should be set by individual page views. See the View Components documentation for more details.- Stylesheet: The primary application stylesheet is located at
/wwwroot/stylesheets/style.cssand is linked here.
<body> Section
The body contains the visible structure of every page.
html
<!-- TheExampleApp/Pages/_Layout.cshtml -->
<body>
<main class="main">
<div class="main__header">
<!-- Header content -->
</div>
<div class="main__content">
@RenderBody()
</div>
<div class="main__footer">
<!-- Footer content -->
</div>
</main>
<!-- Modal and Scripts -->
</body>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<main class="main">: The primary container for all page content..main__header: Wraps the entire header section..main__content: The container for page-specific content, rendered via@RenderBody()..main__footer: Wraps the entire footer section.
A modal dialog, <section class="modal" id="about-this-modal">, is also defined at the root of the <body>. This modal provides information about the example application and is likely toggled via JavaScript by interacting with elements like <a id="about-this-modal-trigger" ...>.
Navigation
The application features a consistent header and footer on every page, both containing navigation links.
Header
The header is split into two horizontal bars: an upper utility bar and a lower primary navigation bar.
html
<!-- TheExampleApp/Pages/_Layout.cshtml -->
<header class="header">
<div class="header__upper-wrapper">
<div class="header__upper layout-centered">
<!-- "What is this app" link -->
<!-- "View on Github" link -->
<div class="header__controls">
<vc:selected-api current-path="@rawTarget"></vc:selected-api>
<vc:locales></vc:locales>
</div>
<!-- "Settings" link -->
</div>
</div>
<div class="header__lower-wrapper">
<div class="header__lower layout-centered">
<!-- Logo -->
<nav class="header__navigation main-navigation">
<ul>
<li><a href="/" class="@isActive("Home")">@Localizer["homeLabel"]</a></li>
<li><a href="/courses" class="@isActive(null)">@Localizer["coursesLabel"]</a></li>
</ul>
</nav>
</div>
</div>
</header>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- Utility Navigation (
header__upper): Contains links to GitHub, a settings page, and controls for the application's behavior. It notably includes two View Components:<vc:selected-api>: Allows the user to switch between Contentful's Preview and Delivery APIs.<vc:locales>: A language switcher.
- Primary Navigation (
header__lower): Contains the application logo and main navigation links to "Home" and "Courses". - Active State: The
activeCSS class is applied to navigation links using a C# helper function defined at the top of the layout. This function checks the value ofViewData["ActivePage"].
csharp
// TheExampleApp/Pages/_Layout.cshtml
@{
Func<string, string> isActive = (s) => { return ViewData["ActivePage"]?.ToString() == s ? "active" : ""; };
}1
2
3
4
2
3
4
Individual pages are responsible for setting this ViewData key to ensure the correct navigation item is highlighted.
Footer
The footer mirrors the primary navigation and includes disclaimers, branding, and social media links. All text is sourced from localization resources.
RenderBody
The @RenderBody() method is a mandatory placeholder in an ASP.NET Core layout file. It designates the exact location where the content of a specific page view will be rendered.
html
<!-- TheExampleApp/Pages/_Layout.cshtml -->
<div class="main__content">
@RenderBody()
</div>1
2
3
4
2
3
4
When a request is made for a page like /courses, the content of Courses.cshtml is executed and its resulting HTML is injected into the layout at the position of @RenderBody(). For more information on how individual pages are constructed, see Page Views.
RenderSection
The layout provides an optional section for scripts, allowing individual pages to include page-specific JavaScript files or inline scripts.
html
<!-- TheExampleApp/Pages/_Layout.cshtml -->
<script src="~/scripts/index.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
<environment include="Heroku">
@Html.Partial("Analytics")
</environment>1
2
3
4
5
6
2
3
4
5
6
@RenderSection("Scripts", required: false): This directive defines a section named "Scripts".required: false: This parameter specifies that pages are not required to implement this section. If a page does not define a "Scripts" section, nothing will be rendered.
A page can inject content into this section using the @section directive:
csharp
// Example usage in a page like Courses.cshtml
@section Scripts {
<script src="~/js/course-filter.js"></script>
<script>
// Page-specific inline script
console.log("Courses page scripts loaded.");
</script>
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
View Components in Layout
The layout makes extensive use of View Components to encapsulate and reuse complex UI logic that is present on every page.
| Component | Location | Purpose |
|---|---|---|
<vc:meta-tags> | <head> | Renders page title and meta tags for SEO. |
<vc:selected-api> | Header | Renders a dropdown to switch between Contentful's Delivery and Preview APIs. |
<vc:locales> | Header | Renders a dropdown for language/locale selection. |
Using View Components keeps the _Layout.cshtml file cleaner and separates concerns, as the logic for fetching data (e.g., available locales) is contained within the component itself. For more details, refer to the View Components documentation.
Responsive Design
The HTML structure is built with responsiveness in mind.
layout-centered: This class is used on wrapperdivs in the header and footer, suggesting a common pattern where content is centered within a max-width container on larger screens while remaining fluid on smaller screens.- BEM-style Naming: The use of class names like
header__upper-wrapperandmain__contentis indicative of a modular CSS architecture (like BEM) that is well-suited for managing complex responsive layouts.
The specific responsive behavior is implemented in /wwwroot/stylesheets/style.css.
Static Assets
The layout is responsible for loading all globally required static assets.
- CSS: The main stylesheet is loaded via
<link rel="stylesheet" href="~/stylesheets/style.css" />. - JavaScript: The main script file is loaded at the end of the
<body>tag:<script src="~/scripts/index.js" asp-append-version="true"></script>.asp-append-version="true": This is a Tag Helper that appends a version hash to the file path (e.g.,index.js?v=Abc123...). This is a critical feature for cache-busting, ensuring that users receive the latest script file after a new deployment.
- Images & Icons: The layout references SVG images for logos and uses an SVG sprite (
/icons/icons.svg) for UI icons. This is an efficient method that reduces HTTP requests. - Analytics: The layout conditionally includes analytics scripts.htmlThe
<environment include="Heroku"> @Html.Partial("Analytics") </environment>1
2
3environmentTag Helper ensures that theAnalytics.cshtmlpartial view (which contains Google Analytics and Snowplow tracking scripts) is only rendered when the application is running in an environment named "Heroku". This prevents tracking during local development.
For more information on how static assets are managed and served, see the Static Files documentation.