Nested Layouts Not Working with Section Helpers

Posted by Community Admin on 05-Aug-2018 21:37

Nested Layouts Not Working with Section Helpers

All Replies

Posted by Community Admin on 18-Nov-2015 00:00

(This post assumes that Project Feather layout files supersedes the PowerTools approach for root templates—if this assumption is incorrect, perhaps you could direct me to the best practice?)

In an effort to keep my HTML as DRY as possible, I have been attempting to use nested razor layout files with Project Feather layouts/templates. My goal is to establish a single root template for all pages on my site.

In a regular MVC project, nested layouts can easily be achieved using @RenderBody. While I met with some initial success using this approach (the page renders fine, assuming I don't use any section helpers), attempting to use @Html.Section helper extension methods fail at page-load time with:

A section with name "head" could not be found.
Parameter name: head

Where I registered a section called "head" in my root template.

Are nested layouts using @RenderBody fully supported by Project Feather? If so, what am I doing wrong? If not, is there an appropriate alternative to allow for a root template that supports registering @Html.Sections?

Here is the code I have so far (bare minimum to encounter this issue):

Root template: ~/Mvc/Views/Shared/Root.cshtml

@using Telerik.Sitefinity.Frontend.Mvc.Helpers;
 
<!DOCTYPE html>
<html @Html.RenderLangAttribute()>
    <head>
        <title></title>
        @Html.Section("head")
    </head>
    <body>
        @Html.Section("top")
        <h1>Standard Root</h1>
        @RenderBody()
        @Html.Section("bottom")
    </body>
</html>

 

Child template: ~/Mvc/Views/Layouts/Standard.cshtml

@using Telerik.Sitefinity.Frontend.Mvc.Helpers;
 
@
    Layout = "~/Mvc/Views/Shared/Root.cshtml";
 
@Html.Script(Telerik.Sitefinity.Modules.Pages.ScriptRef.JQuery, "head")
 
@Html.Partial("Site/Header")
@Html.SfPlaceHolder("Body")
<h2>Standard Page</h2>
@Html.Partial("Site/Footer")

Thanks for your time!
Matt

Posted by Community Admin on 25-Nov-2015 00:00

Hi Matt,

The jQuery Script reference is getting rendered before the head section is rendered hence it is generating the error as it is not getting the head section. This can be fixed by moving the script reference from the Standard.cshtml to the Root.cshtml after the "head" section.

Example:
Root template: ~/Mvc/Views/Shared/Root.cshtml

@using Telerik.Sitefinity.Frontend.Mvc.Helpers;
<!DOCTYPE html>
<html @Html.RenderLangAttribute()>
<head>
    <title></title>
    @Html.Section("head")
    @Html.Script(Telerik.Sitefinity.Modules.Pages.ScriptRef.JQuery, "head")
</head>
<body>
    @Html.Section("top")
    <h1>Standard Root</h1>
    @RenderBody()
    @Html.Section("bottom")
</body>
</html>

Child template: ~/Mvc/Views/Layouts/Standard.cshtml
@using Telerik.Sitefinity.Frontend.Mvc.Helpers;
@
    Layout = "~/Mvc/Views/Shared/Root.cshtml";
<h2>Standard Page</h2>
<div class="sfPublicWrapper" id="PublicWrapper">
    @Html.SfPlaceHolder("Body")
</div>
@Html.Partial("Site/Header") and @Html.Partial("Site/Footer") can be used as usual if the partial views created. 

It is recommended that there is a DIV tag with class "sfPublicWrapper" and id "PublicWrapper" present inside of the body tag. This is the tag where users are able to drag initial layout elements to.
(Ref. https://github.com/Sitefinity/PowerTools/wiki/Root-Templates#mvc-root-templates)

Documentation to Create layout files (feather) can be found here: http://docs.sitefinity.com/feather-create-layout-files.

Regards,
Arnob Makhlaqur
Telerik
 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 25-Nov-2015 00:00

Hi Arnob,

Thanks for your response!

I came to a similar conclusion after looking through the Feather code. It's unfortunate the custom Section helpers don't work alongside the native RenderBody call. Being able to add section content (from a child template) to a parent layout is kind of the point of "sections" as a concept. In this case, adding jQuery was just an example, but was only meant to be included if that particular child template was being used. Placing it in the parent layout defeats the very point of the requirement.

Also, with the addition of the sfPublicWrapper markup, it's a little disappointing to find that Sitefinity isn't quite as HTML agnostic as I had hoped. One of the main advantages of ASP.NET MVC (compared to say Web Forms) is the control the developer is given with respect to HTML output. Convention over configuration is great for file and class names etc., but doesn't work so well for rendered content (be it HTML, CSS or otherwise). Porting sites to Sitefinity now requires a little more time and tweaking than should be necessary—and I no longer have that great feeling knowing I have full control over my HTML. Oh well, not a deal breaker, at this point.

Thanks again for your feedback, it's much appreciated.

Matt

Posted by Community Admin on 01-Jun-2017 00:00

Is this still the case?

In our scenario we have a master template which defines our basic layout that's used for the majority of the site.  We also have subsections of the site with their own sub-navigations, so we decided to create child templates (using the Sitefinity template designer) which inherit the master template.  These child templates simply add navigation for the subsection.

What we're finding now is that when we call @Html.Script(..., "bottom") from any widget used inside these child layouts, the script is appearing in the head instead of the bottom.

This thread is closed