@RenderSection in nested razor templates
Asked Answered
A

1

38

My problem is I can't seem to use @RenderSection from a nested template when @RenderSection is defined in the base template. Currently, I have a nested base template which is linked to a child template which is then used in the view pages. When I define the @RenderSection in the base template and render it in the view pages it throws an error.

Here's the exact problem.

I want to create a RenderSection to allow me to insert custom scripts. My base template....

<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
 @RenderSection("HeaderContent", false) // The region of the header scripts (custom css)

</head>
<body>
@RenderBody()
</body>
</html>

I then skip the child template as I do not want to put any custom head code in there and apply it to the page itself..

@section HeaderContent {
    <script>alert("hi");</script>
}

My problem is that I cant seem to add custom head code in to the base template from my normal pages.

The following sections have been defined but have not been rendered for the layout page ~/Views/Shared/OneColLayer.cshtml": "HeaderContent.

Do I need to include a pointer to the base template in the view page?

@{
    Layout = "~/Views/Shared/BaseTemplate.cshtml";
}

My new base template

<head>
  <link rel="stylesheet" type="text/css" href="@Url.Content("~/content/layout.css")" />
  <link rel="stylesheet" type="text/css" href="@Url.Content("~/content/global.css")" />
  <script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")"></script>
  <script type="text/javascript" src="@Url.Content("~/js/fadeInFadeOut.js")"></script>
  <title>@ViewBag.Title</title>
  @RenderSection("HeaderContent", false)
</head>
<body>
  @RenderBody()
</body>

my new child template

@{
  Layout = "~/Views/Shared/BaseTemplate.cshtml";
}
@RenderSection("HeaderContent", false)
@RenderBody()

my view

@{
  ViewBag.Title = "Home";
  Layout = "~/Views/Shared/OneColLayer.cshtml";
}
@section HeaderContent {
  <h1>Left Content</h1>
}
<div>my view content</div>

the content gets placed in the oneCol template now the base template.

results...

<div id="Content">
   <h1>Left Content</h1>
</div>
Ave answered 20/12, 2011 at 16:42 Comment(0)
P
60

You need to specify the sections that are allowed to pass through in the middle template.

BaseTemplate.cshtml

<!DOCTYPE html>
<html>
  <head>
    <title>@ViewBag.Title</title>
    @RenderSection("HeaderContent", false) @* The region of the header scripts (custom css) *@
  </head>
<body>
  @RenderBody()
</body>
</html>

EDIT

your new child template

@{
  Layout = "~/Views/Shared/BaseTemplate.cshtml";
}
@section HeaderContent {
  @RenderSection("HeaderContent", false)
}
@RenderBody()

If you put the render section inside of a section from the base template, it will render that section in the correct place on the base template.


View.cshtml -> uses MiddleLayout.cshtml as it's layout

@section HeaderContent
{
    <!-- header content that will now render -->
}

<!-- page content -->
Papagena answered 20/12, 2011 at 17:11 Comment(5)
I have tried doing this method. But the content in my view gets displayed on the template it inherits not the base template.Ave
@JamesAndrewSmith per your edits, it's showing up on your middle template because you are not putting the @RenderSection in the middle template inside of your a rendered section. I will edit mine to show you exactly what yours should look like.Papagena
I wish there was a better way to bubble up section declarations. something besides @section script { @RenderSection("script") }Mnemonic
Hi , How to get the rendersection html string to cshtml page. @{ string sampleHeading; } @if (IsSectionDefined("SampleHeading")) { sampleHeading = RenderSection("SampleHeading").ToString(); <h4> @Html.Display("sampleHeading"); </h4>Indaba
This works perfectly. Thank you! It should be passed through automatically, though.Milklivered

© 2022 - 2024 — McMap. All rights reserved.