Posted on:
Categories: CodePlex;SharePoint;Office 365
Description: In a follow up to a previous blog post, an Office 365 compatible tabbed web parts solution is now on CodePlex
​In one of my previous blog posts, I posted a solution on how to integrate tabs (or more precisely, tabbed web parts) into publishing pages in on-premise SharePoint installations. However, since my CodePlex solution relied on deploying a farm-scoped WSP, it could not be used in SharePoint Online/Office 365. Instead of creating a deployable package for SharePoint Online, I took a simpler approach I posted a standalone publishing page layout which could be manually uploaded to the Site Collections Master Page Gallery, and that's it. You can download the page layout directly from CodePlex here https// Or simply copy and paste the source code below (and modify to suit your needs!). <%@ Page language="C#" Inherits="Microsoft.SharePoint.Publishing.PublishingLayoutPage, Microsoft.SharePoint.Publishing,Version=,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="OSRVWC" Namespace="Microsoft.Office.Server.WebControls" Assembly="Microsoft.Office.Server, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="OSRVUPWC" Namespace="Microsoft.Office.Server.WebControls" Assembly="Microsoft.Office.Server.UserProfiles, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="SPSWC" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="SEARCHWC" Namespace="Microsoft.Office.Server.Search.WebControls" Assembly="Microsoft.Office.Server.Search, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="PublishingWebControls" Namespace="Microsoft.SharePoint.Publishing.WebControls" Assembly="Microsoft.SharePoint.Publishing, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <aspContent ContentPlaceHolderID="PlaceHolderPageTitle" runat="server"> <SharePointFieldValue id="PageTitle" FieldName="Title" runat="server" /> </aspContent> <aspContent ContentPlaceholderID="PlaceHolderPageTitleInTitleArea" runat="server"> <SharePointFieldValue FieldName="Title" runat="server"/> </aspContent> <aspContent ContentPlaceHolderId="PlaceHolderPageImage" runat="server" /> <aspContent ContentPlaceHolderId="PlaceHolderTitleBreadcrumb" runat="server" /> <aspContent ContentPlaceHolderId="PlaceHolderBodyAreaClass" runat="server" /> <aspContent ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server"> <PublishingWebControlsEditModePanel runat="server" id="editmodestyles"> <SharePointCssRegistration name="<% $SPUrl~sitecollection/Style Library/~language/Core Styles/edit-mode-21.css %>" After="<% $SPUrl~sitecollection/Style Library/~language/Core Styles/page-layouts-21.css %>" runat="server"/> </PublishingWebControlsEditModePanel> <!-------------------------- DEPLOYMENT INSTRUCTIONS ----------------------------------> <!-- Requirements SharePoint 2013 (Online or On-Premise) Publishing enabled (requires "E" subscription online, or requires Enterprise on-premise) -> enable site collection feature SharePoint Server Publishing Infrastructure -> enable site feature SharePoint Server Publishing Instructions Simply manually upload this file into the Master Page Gallery (site settings -> master pages and page layouts) -> ensure content type is set to "Page Layout" -> give it a title of your choice (you will need this later) -> under Associated Content Type, select "publishing content types", and "page" (unless you have a custom publishing page content type you'd like to utilize) -> save the file -> make sure to check this file in, and publish/approve it if neccessary Now create or navigate to an existing publishing page, and edit the page -> click the "page" ribbon tab, then click the "page layout" ribbon button -> in the page layout dropdown, find this page layout (it will be under the title you chose in the previous step), and click it Any webparts within the tabbed webpart zone will be displayed as tabs once you save the page! --> <!--------------------------------------------------------------------------------------> <script src="//" type="text/javascript"></script> <script src="//" type="text/javascript"></script> <SharePointCssRegistration Name="//" After="Themable/corev15.css" runat="server" /> <SharePointScriptBlock runat="server"> //for reference, http// // http// (function (jQuery) jQuery.fn.wpTabify = function () // if we're not in edit mode if (jQuery('.ms-WPAddButton').size() == 0) // for each this.each(function (i) // create variables needed for assembling tabs within this web part zone var idName = jQuery(this).attr('id'); var tabList = jQuery('<ul class="wpt-ui-tabs-nav"/>'); var panels = jQuery('<div class="wpt-ui-tabs-wrapper"/>'); // for each web part in the web part zone, assemble the tab headers // and tab content in the format JQuery UI tabs() method expects. jQuery(this).find(' > divfirst-child').each(function (j) jQuery(tabList).append('<li><a href="#ui-tab-panel' + idName + i + j + '"><span>' + jQuery(this).find('').text() + '</span></a></li>'); var thisPanel = jQuery('<div id="ui-tab-panel' + idName + i + j + '" class="wpt-ui-tabs-panel"/>'); var panelContents = jQuery(this).detach(); jQuery(thisPanel).append(jQuery(panelContents).find('.ms-wpContentDivSpace')); jQuery(panels).append(thisPanel); ); // if we created any tabs, then push the new tabs structure back into the DOM, // then call the jquery ui method .tabs() if (jQuery(tabList).find('li').size() > 0) jQuery(this).prepend(panels); jQuery(this).prepend(tabList); jQuery(this).tabs(); // remove original webpart zone now that we've tabified // what we wanted out of it jQuery(this).find('').remove(); ); ; )(jQuery); function TabifyFnWrapper() // tabify the appropriate web part zone for this page layout jQuery('#TabbedWebPartZoneWrapper').wpTabify(); //regardless of the tabify result, display the web part zone jQuery('#TabbedWebPartZoneWrapper').css('display', 'inline-block'); // add to sharepoint javascript function queue to be called after page load _spBodyOnLoadFunctionNames.push('TabifyFnWrapper'); </SharePointScriptBlock> </aspContent> <aspContent ContentPlaceHolderID="PlaceHolderMain" runat="server"> <PublishingWebControlsEditModePanel runat="server" CssClass="edit-mode-panel title-edit"> <SharePointTextField runat="server" FieldName="Title"/> </PublishingWebControlsEditModePanel> <div id="TabbedWebPartZoneWrapper" style="displaynone;"> <!-- note, the wrapper around the tabbed web part zone is initally hidden so users don't see the shifting around while the tabs are being assembled --> <WebPartPagesWebPartZone runat="server" Title="Tabbed Web Part Zone" ID="TabbedWebPartZone" /> </div> <div id="PublishingContentZoneWrapper"> <!-- you can still have 1 or more publishing content zones on the page --> <PublishingWebControlsRichHtmlField FieldName="PublishingPageContent" HasInitialFocus="True" runat="server"/> </div> <div id="NonTabbedWebPartZoneWrapper"> <!-- you can still have normal non-tabbed web part zones also on the page --> <WebPartPagesWebPartZone runat="server" Title="Non Tabbed Web Part Zone" ID="NonTabbedWebPartZone" /> </div> </aspContent>