Skip to content

Instantly share code, notes, and snippets.

@poke
Created September 20, 2017 13:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save poke/10a085c78b58689a6cbc98801bfce9ef to your computer and use it in GitHub Desktop.
Save poke/10a085c78b58689a6cbc98801bfce9ef to your computer and use it in GitHub Desktop.
[ASP.NET Core] RazorPage.ForwardSection extension to forward sections in intermediate layouts to the base layout
using Microsoft.AspNetCore.Mvc.Razor;
namespace AspNetCoreUtilities
{
public static class ForwardSectionRazorPageExtensions
{
/// <summary>
/// Forward a section to the parent layout. This allows views to define
/// sections that are rendered in a parent layout without intermediate
/// layouts having to render and re-define the sections themselves.
///
/// Just have a call to <c>ForwardSection</c> in the intermediate
/// layout to allow views to define sections of the base layout.
/// </summary>
/// <param name="page">Razor page.</param>
/// <param name="sectionName">Name of the section to forward.</param>
/// <example>
/// This example assumes a <c>_BaseLayout.cshtml</c> that renders a
/// section <c>scripts</c> for example using the following:
///
/// <code>
/// @await RenderSectionAsync("scripts")
/// </code>
///
/// An intermediate layout <c>_Layout.cshtml</c> could then forward
/// this section to the base layout like this:
///
/// <code>
/// @{
/// Layout = "_BaseLayout";
/// this.ForwardSection("scripts");
/// }
/// </code>
///
/// This is approximately equivalent to the following, with the added
/// benefit that it will not involve additional rendering:
///
/// <code>
/// @if (IsSectionDefined("scripts"))
/// {
/// @section scripts
/// {
/// @await RenderSectionAsync("scripts")
/// }
/// }
/// </code>
/// </example>
public static void ForwardSection(this RazorPage page, string sectionName)
{
// if the section is defined by the view
if (page.IsSectionDefined(sectionName))
{
// Forward the section writer from the previous view to the
// current view. This will essentially move the section
// definition to the parent layout.
page.DefineSection(sectionName, page.PreviousSectionWriters[sectionName]);
// Finally, ignore the section to avoid having to render it for
// the current view. Since the section is being forwarded to
// the parent layout, it will be rendered there, so we do not
// need to render it here. Ignoring the section puts it on a
// list which will allow it to be skipped in the check whether
// all required sections were rendered.
page.IgnoreSection(sectionName);
}
}
/// <summary>
/// Forward multiple sections using <see cref="ForwardSection(RazorPage, string)"/>.
/// </summary>
/// <param name="page">Razor page.</param>
/// <param name="sectionNames">Names of the sections to forward.</param>
public static void ForwardSections(this RazorPage page, params string[] sectionNames)
{
foreach (var sectionName in sectionNames)
{
ForwardSection(page, sectionName);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment