Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I'm currently upgrading a SharePoint site with a custom master page from 2007 to 2010. We want to be able to let the user decide when to migrate their site from 2007 L&F to 2010 L&F using the built-in Upgrade option, so what this means is that I need the custom master page to support both UIv3 and UIv4.

I've had some luck with introducing the Ribbon code inside a UIVersionedContent (v4) element, and moving the equivalent header code inside a UIVersionedContent (v3) element. This lets me switch between UIv3 and UIv4 in the site options and go "there's a ribbon; now it's back to normal", although there are bits missing:

I've run into issues whereby I need to have a standard SharePoint ContentPlaceHolder element (e.g. PlaceHolderTitleBreadcrumb, PlaceHolderSiteName, PlaceHolderTopNavBar) inside both the v4 and v3 sections, so the content can appear whether the page is in v3 or v4 UI mode. Despite the fact that the two sections are mutually exclusive, if I do put in duplicate ContentPlaceHolders I always get a parser exception saying that the IDs of the elements aren't unique. I can't work around this by repositioning my UIVersionedContent tags around the ContentPlaceHolders, so it seems to me I can't have a custom master page that fully supports both the old and new UIs.

Example code: (probably badly formatted, I'm JS-limited here)

<SharePoint:UIVersionedContent UIVersion="4">
  <ContentTemplate>
    <SP ribbon code>
      <asp:ContentPlaceHolder id="PlaceHolderSiteName" runat="server">
        <SharePoint:SPLinkButton runat="server" NavigateUrl="~site/" id="onetidProjectPropertyTitle"><SharePoint:ProjectProperty Property="Title" runat="server" /></SharePoint:SPLinkButton>
      </asp:ContentPlaceHolder> 
    </SP ribbon code>
  </ContentTemplate>
</SharePoint:UIVersionedContent>
<SharePoint:UIVersionedContent UIVersion="3">
  <ContentTemplate>
    <Old custom header code>
      <asp:ContentPlaceHolder id="PlaceHolderSiteName" runat="server">
      <!-- Causes an error as the ID is duplicated -->

        <SharePoint:SPLinkButton runat="server" NavigateUrl="~site/" id="onetidProjectPropertyTitle"><SharePoint:ProjectProperty Property="Title" runat="server" /> </SharePoint:SPLinkButton>
      </asp:ContentPlaceHolder> 
    </Old custom header code>
  </ContentTemplate>
</SharePoint:UIVersionedContent>

Is there something I've missed? Some way I can associate two ContentPlaceHolders with one bit of SharePoint's content without having duplicaet IDs? Some neat way of duplicating the content of one ContentPlaceHolder to another?

Or is there some other way I should be doing this rather than having a single master page that supports UIv3 and v4? An easy way to tell a SPWeb "If your UIVersion is 3, use this MasterUrl, but if it's 4, use this one"? A way to hook into a UIVersionChanging event and change the MasterUrl?

share|improve this question

2 Answers 2

You could easily include logic in your feature receiver to detect the version of the web and apply the applicable master, that's not hard at all.

As you point out, you cannot have two placeholders of the same ID, and because the UIVersionedContent tag has to go inside the placeholder, you cannot have them in two different places of the master page. The SharePoint model assumes your page structure is the same, you're just displaying differently formatted content in your placeholder based on the version- like the example Doug posted where the 2007 Recycle Bin/View All Site Content links are in a table and the 2010 version is a UL.

I've never tried to put the placeholder inside the UIVersionedContent tag, but from my understanding of how it works, I don't think it would work.

share|improve this answer

I think your method of having a single master page that supports both UIv3 and UIv4 is fine. I don't truly understand your issue, though. If you have versioned content, you just put the UIVersionedContent tag around the content that you want to be version specific. If you have versioned content that is related to a content placeholder, the UIVersionedContent should go inside the content placeholder tag. For example, here is an excerpt from the default v4.master on a SharePoint 2010 publishing site.

<asp:ContentPlaceHolder id="PlaceHolderQuickLaunchBottom" runat="server">
            <SharePoint:UIVersionedContent UIVersion="3" runat="server" id="PlaceHolderQuickLaunchBottomV3">
                <ContentTemplate>
                    <table width="100%" cellpadding="0" cellspacing="0" border="0" class="s4-die">
                    <tbody>
                    <tr><td>
                    <table class="ms-recyclebin" width="100%" cellpadding="0" cellspacing="0" border="0">
                    <tbody>
                    <tr><td nowrap="nowrap">
                    <SharePoint:SPLinkButton runat="server" NavigateUrl="~site/_layouts/recyclebin.aspx" id="v3idNavLinkRecycleBin" ImageUrl="/_layouts/images/recycbin.gif" Text="<%$Resources:wss,StsDefault_RecycleBin%>" PermissionsString="DeleteListItems" />
                    </td></tr>
                    </table>
                    </td></tr>
                    </table>
                </ContentTemplate>
            </SharePoint:UIVersionedContent>
            <SharePoint:UIVersionedContent UIVersion="4" runat="server" id="PlaceHolderQuickLaunchBottomV4">
                <ContentTemplate>
                    <ul class="s4-specialNavLinkList">
                        <li>
                            <SharePoint:ClusteredSPLinkButton
                                runat="server"
                                NavigateUrl="~site/_layouts/recyclebin.aspx"
                                ImageClass="s4-specialNavIcon"
                                ImageUrl="/_layouts/images/fgimg.png"
                                ImageWidth=16
                                ImageHeight=16
                                OffsetX=0
                                OffsetY=428
                                id="idNavLinkRecycleBin"
                                Text="<%$Resources:wss,StsDefault_RecycleBin%>"
                                CssClass="s4-rcycl"
                                PermissionsString="DeleteListItems" />
                        </li>
                        <li>
                            <SharePoint:ClusteredSPLinkButton
                                id="idNavLinkViewAllV4"
                                runat="server"
                                PermissionsString="ViewFormPages"
                                NavigateUrl="~site/_layouts/viewlsts.aspx"
                                ImageClass="s4-specialNavIcon"
                                ImageUrl="/_layouts/images/fgimg.png"
                                ImageWidth=16
                                ImageHeight=16
                                OffsetX=0
                                OffsetY=0
                                Text="<%$Resources:wss,quiklnch_allcontent_short%>"
                                accesskey="<%$Resources:wss,quiklnch_allcontent_AK%>"/>
                        </li>
                    </ul>
                </ContentTemplate>
            </SharePoint:UIVersionedContent>
            </asp:ContentPlaceHolder>

Notice that the ContentPlaceHolder for the bottom of the quick launch contains both a UIVersionContent for UIVersion="3" and UIVersion="4".

I hope this helps.

share|improve this answer
    
My issue is that I need the placeholders themselves to be in different positions depending on the UI version, and thus I require some of them to be duplicated in different UIVersionedContent blocks. E.g. PlaceHolderSiteName needs to be in the disappearing part of the ribbon in v4, but elsewhere in v3. –  Rawling Aug 9 '11 at 13:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.