Accessing Grandparent Content Placeholder in Master Pages
Asked Answered
S

1

8

I've been searching the web and not finding any answers (there were a couple close questions on stack overflow but they didn't seem to get answered or be identical), so I thought I'd pose one of my own. It revolves around nested master pages and a content page accessing the Content PlaceHolder of the grandparent master even if it is not re-exposed in the parent nested master. I'm wondering if this is not possible.

Core Site.Master

<html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">

        <title>
                <asp:ContentPlaceHolder ID="TitleContent" runat="server">
                    <%= Html.GlobalModel().PageTitle %>
                </asp:ContentPlaceHolder>
            </title>

            <asp:ContentPlaceHolder ID="HeadContent" runat="server">
            <link rel="shortcut icon" 
                href="<%= ViewContext.ClientContent( "Content/Tiki.ico" ) %>" 
                type="image/x-icon"/>
        </asp:ContentPlaceHolder>
    </head>
    <body>
        <asp:ContentPlaceHolder ID="SiteContent" runat="server"/>
    </body>
</html>

Nested Site.Master (notice how TitleContent and HeadContent weren't customized, so the 'default' content from Core Site.Master should take affect)

<%@ Master Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
    Inherits="System.Web.Mvc.ViewMasterPage" %>

<asp:Content ContentPlaceHolderID="SiteContent" runat="server">
    <asp:ContentPlaceHolder ID="SiteContent" runat="server">

        <h1>Nested Header</h1>
        <asp:ContentPlaceHolder ID="NestedContent" runat="server"/>

    </asp:ContentPlaceHolder>
</asp:ContentPlaceHolder>

ContentView.aspx (referencing Nested Site.Master, the attempted TitleContent replacement will not work.)

<%@ Page Language="C#" MasterPageFile="Site.Master" %>

<asp:Content ContentPlaceHolderID="NestedContent" runat="server">
    <p>Nested content.  This will work.</p>
</asp:Content>

<asp:Content ContentPlaceHolderID="TitleContent" runat="server">
    Nested Title.  This will **not** work.
</asp:Content>
Sepaloid answered 2/9, 2011 at 16:32 Comment(3)
Since you're using MVC, have a look at Razor. It's much better about handling this type of thing. I haven't yet found a satisfactory solution to this problem in webforms.Liquidity
You ought to credit Jon Adams below with the answer. It may not be pretty, but it's what we're stuck with...Hydrated
Well, I can give him credit, but essentially the 'duplication' of code is what we ended up with and wasn't really the answer I was hoping for. But I guess an answer of 'no' is a valid answer. One of these days when we have time to migrate to Razor I'll have to check out their support.Sepaloid
H
7

ContentPlaceHolderIDs can only reference their immediate parent when listed declaratively.

The easiest fix, though not the most elegant, would be to copy the ContentPlaceHolders to Nested Site.Master with the same default code. Requires some code duplication, but gets the job done.

<%@ Master Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
    Inherits="System.Web.Mvc.ViewMasterPage" %>

<asp:Content ContentPlaceHolderID="TitleContent" runat="server">
    <asp:ContentPlaceHolder ID="NestedTitleContent" runat="server">
        <%= Html.GlobalModel().PageTitle %>
    </asp:ContentPlaceHolder>
</asp:ContentPlaceHolder>

<asp:Content ContentPlaceHolderID="SiteContent" runat="server">
    <asp:ContentPlaceHolder ID="SiteContent" runat="server">
        <h1>Nested Header</h1>
        <asp:ContentPlaceHolder ID="NestedContent" runat="server"/>
    </asp:ContentPlaceHolder>
</asp:ContentPlaceHolder>

If you don't want to do that, you could replace the placeholders with custom controls that know what to show when.

Or if you need to keep it this way, you could run a bunch of code to force early rendering to an in-memory string/buffer and replace child controls with it — but that would be a ton of hassle, and it's doubtful if it would be worth the effort.

But any of those solutions depends on your situation. If you provided more context, we could provide more specific advise.

Headband answered 22/9, 2011 at 14:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.