When you create a minimal master page in SharePoint 2013, it creates a nice HTML master page that is supposed to allow people that do not have experience editing the normal ASP.NET master pages design your site easily. Whether this task is “easy” or not is a matter of opinion, of course, but the ribbon is one of the headaches that I encountered.

You will find something that resembles the following in your new HTML master page.

<!--SID:02 {Ribbon Snippet}-->

In fact, besides some tags around preview of the ribbon that is pretty much all you get. This is all well and good, except what you get is the PublishingRibbon, not the SPRibbon that the out of the box Microsoft master pages use. What is the difference you ask? Well, a huge amount of flexibility!

We actually only need to look at the markup in ASP.NET to see the vast difference in flexibility.

PublishingRibbon

<PublishingRibbon:PublishingRibbon runat="server" />

SPRibbon

<SharePoint:SPRibbon
				runat="server"
				PlaceholderElementId="RibbonContainer"
				CssFile="" >
				<SharePoint:SPRibbonPeripheralContent
					runat="server"
					CssClass="ms-core-defaultFont ms-dialogHidden"
					Location="TabRowLeft">
				</SharePoint:SPRibbonPeripheralContent>
				<SharePoint:SPRibbonPeripheralContent
					runat="server"
					Location="TabRowRight"
					ID="RibbonTabRowRight"
					CssClass="s4-trc-container s4-notdlg ms-core-defaultFont">
					<SharePoint:SPSharePromotedActionButton runat="server"/>
					<SharePoint:DelegateControl runat="server" ControlId="PromotedActions" AllowMultipleControls="true" />
					<SharePoint:SPSyncPromotedActionButton runat="server"/>
					<SharePoint:PageStateActionButton id="PageStateActionButton" runat="server" Visible="false" />
<span id="fullscreenmodebox" class="ms-qatbutton">
	<span id="fullscreenmode">
		<SharePoint:ThemedClusteredHoverImage
			runat="server"
			ID="fullscreenmodeBtn"
			ThemeKey="spcommon"
			TouchMode="true"
			TouchModeWidth="30"
			TouchModeHeight="30"
			TouchModePaddingLeft="7"
			TouchModePaddingTop="7"
			TouchModePaddingRight="7"
			TouchModePaddingBottom="7"
			ImageUrl="/_layouts/15/images/spcommon.png?rev=23"
			Width="16"
			Height="16"
			OffsetX="143"
			OffsetY="178"
			HoverOffsetX="125"
			HoverOffsetY="178"
			NavigateUrl="#"
			onclick="SetFullScreenMode(true);PreventDefaultNavigation();return false;"
			AlternateText="<%$Resources:wss,multipages_fullscreenmodelinkalt_text%>"
			ToolTip="<%$Resources:wss,multipages_fullscreenmodelinkalt_text%>"
			/>
	</span>
	<span id="exitfullscreenmode" style="display: none;">
		<SharePoint:ThemedClusteredHoverImage
			runat="server"
			ID="exitfullscreenmodeBtn"
			ThemeKey="spcommon"
			TouchMode="true"
			TouchModeWidth="30"
			TouchModeHeight="30"
			TouchModePaddingLeft="7"
			TouchModePaddingTop="7"
			TouchModePaddingRight="7"
			TouchModePaddingBottom="7"
			ImageUrl="/_layouts/15/images/spcommon.png?rev=23"
			Width="16"
			Height="16"
			OffsetX="107"
			OffsetY="178"
			HoverOffsetX="179"
			HoverOffsetY="96"
			NavigateUrl="#"
			onclick="SetFullScreenMode(false);PreventDefaultNavigation();return false;"
			AlternateText="<%$Resources:wss,multipages_fullscreenmodelinkalt_text%>"
			ToolTip="<%$Resources:wss,multipages_fullscreenmodelinkalt_text%>"
			/>
	</span>
</span>
<SharePoint:DeveloperDashboard runat="server" />
<SharePoint:DeveloperDashboardLauncher
	ID="DeveloperDashboardLauncher"
	ThemeKey="spcommon"
	TouchMode="true"
	TouchModeWidth="30"
	TouchModeHeight="30"
	TouchModePaddingLeft="7"
	TouchModePaddingTop="7"
	TouchModePaddingRight="7"
	TouchModePaddingBottom="7"
	NavigateUrl="javascript:return false"
	OnClick="ToggleDeveloperDashboard(window.g_ddHostBase);return false"
	OuterCssClass="ms-dd-button ms-qatbutton"
	runat="server"
	ImageUrl="/_layouts/15/images/spcommon.png?rev=23"
	AlternateText="<%$Resources:wss,multipages_launchdevdashalt_text%>"
	ToolTip="<%$Resources:wss,multipages_launchdevdashalt_text%>"
	OffsetX="145"
	OffsetY="196"
	HoverOffsetX="163"
	HoverOffsetY="196"
	Height="16"
	Width="16" />
				</SharePoint:SPRibbonPeripheralContent>
			</SharePoint:SPRibbon>

Obviously if you want full control over your page, SPRibbon is the best choice, afterall it is what Microsoft uses in seattle.master. The problem with the Publishing Ribbon is it does everything for you, in the way that it is programmed.

Figure 1: SharePoint 2013 status bar content that is added by the Ribbon.

Figure 1: SharePoint 2013 status bar content that is added by the Ribbon.

For example, the message on a page that says it is checked out to you is displayed directly after the ribbon. In some custom master pages, you need this to be somewhere else. With the PublishingRibbon, you are out of luck, but the SPRibbon does not automatically add that element and you can create your own block to take care of it elsewhere.

<SharePoint:AjaxDelta ID="DeltaPageStatusBar" BlockElement="true" runat="server">
	<div id="pageStatusBar"></div>
</SharePoint:AjaxDelta>

Now you can display that message basically anywhere in the page instead of where PublishingRibbon wants you to display it. The ribbon javascript will automatically inject it properly in the correct place, in this case in the pageStatusBar <div>.

That is just a single example, there are others as well. The bottom line is if you need more control, you can look at the out of the box seattle.master and use SPRibbon the same way. The problem comes when you try and use HTML master pages. It appears that if the parser that goes through and transforms an HTML master does not find the ribbon snippet, it automatically is added. Worse, if you already have a ribbon on the page, now you have two, and everything does not work then.

The trick is that the code Microsoft uses to add the ribbon luckily checks to see if a ribbon is on the page already. These are two different code paths. If you don’t have the snippet, then a duplicate ribbon is added. If you do have the snippet, then it checks to see if a ribbon is already on the page. So in order to make sure that the HTML master page parser does not add a ribbon to your page and allow you to do it manually, you will need to add the following snippet.

<!--CS: Start fake ribbon to trick design manager-->
	<!--SID:01 {Ribbon}-->
<!--CE: End fake ribbon to trick design manager-->

SID:01 is actually the SPRibbon (internally it is Ribbon, SmallRibbon is SID:02, the PublishingRibbon). The following enum specifies them, 0, 1, 2 respectively.

namespace Microsoft.SharePoint.Publishing.Design
{
	internal enum KnownSnippetType
	{
		PageHead,
		Ribbon,
		SmallRibbon
	}
}

Now you can have a manually created and fine-tuned SPRibbon in your HTML master pages.