1 / 59

Cross Site Collection Navigation

Cross Site Collection Navigation. SharePoint Saturday Bend Oregon October 4, 2014. Kyle Petersen kyle@pdxportals.com. SharePoint Architect - Petersen Consulting LLC SharePoint Consulting 2004 – 2014 2012 – Microsoft Certified Solutions Master for SharePoint

bran
Download Presentation

Cross Site Collection Navigation

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Cross Site Collection Navigation SharePoint Saturday Bend Oregon October 4, 2014

  2. Kyle Petersenkyle@pdxportals.com SharePoint Architect - Petersen Consulting LLC SharePoint Consulting 2004 – 2014 2012 – Microsoft Certified Solutions Master for SharePoint Microsoft based application development since 1987

  3. What’s the issue? SharePoint has navigation • SharePoint has lots of navigation • Top level navigation bar • Quick launch • Managed Navigation • Custom Sitemap providers • Site Directory • Search • All work fine within the scope of a single site collection • Sometimes our architecture is not under our control

  4. Organizational Structures

  5. Reasons for multiple site collections • Separation for security • Separation to reduce size of content database • Separate Web applications • Separate Farms • Merging Farms • “It’s always been that way”

  6. Tackle two issues today Part I How can I have a global menu for ALL my sites • Across Sub Sites • Across Site Collections • Across Web Applications Part II (Time permitting) How can I have a directory of all my sites • Automatic registration in the directory • Security trimmed

  7. Cross Site Navigation • Lots of solutions available • Business Process Managed • Every site collection specifies the same top level navigation items • Changes need to be made at every site collection • Custom Sitemap Provider • XML site map was my favorite • Manage XML file on each WFE server (_layouts/…) • Managed Navigation • Pin / Link navigation items • Nightmare to maintain

  8. A new solution Global Navigation Menu Use the Managed Metadata to configure the navigation structure Can create any structure needed Strongly suggest you limit to 2 levels Users get frustrated trying to navigate to tertiary menus

  9. Our Demo Model

  10. Implementation Details • This is not going to replace the top level navigation menu • It could, but in this example this is a NEW global navigation menu • Want to allow Site Collection owners to maintain their own navigation within the site collections • Define Top level navigation • Control Inheritance of sub sites • New Global Navigation will be placed on the SharePoint Bar • SharePoint online requires special consideration

  11. Managed Metadata Benefits • Single location to maintain our menus • Don’t need to manually edit sitemap files on servers • Don’t need to write custom providers • Can edit navigation using a browser • Controlled access so site owners cannot mess up or navigation • Configure who has rights to edit the term set • Leverages the capabilities of Managed Navigation • Configure and test links • Control Display Order • Nested levels of navigation

  12. Implementation There are 4 Components to the solution 1. Define the menu structure in the Managed Metadata 2. Create client side JavaScript to render the menu 3. Use jQuery & CSS to style the menu 4. Package and deploy

  13. 1. Managed Navigation

  14. Sort Order

  15. 2. Script to generate the menu • Use client side JSOM code to access the managed metadata • Couple of hacks: • Manually configure the name of the Managed Metadata provider • Manually configure the GUID of the Term Set

  16. Simplified Example • Access Term Store • Iterate through the terms • Build menu structure in browser DOM • Reposition element in the DOM • Wire up the event handlers

  17. <ulclass="ldd_menu"id="ldd_menu"> <li> <spanstyle="width: 127px; height: 25px;">Contoso</span> <divclass="ldd_submenu"style="display: none;"> <ul> <liclass="ldd_heading">Corporate</li> <li><ahref="http://firefly.pdx.local/contoso/board">Board</a></li> <li><ahref="http://firefly.pdx.local/contoso/corp/finance">Finance</a></li> <li><ahref="http://firefly.pdx.local/contoso/corp/hr">HR</a></li> <li><ahref="http://firefly.pdx.local/contoso/corp/investor">Investor</a></li> <li><ahref="http://firefly.pdx.local/contoso/corp/it">IT</a></li> </ul> <ul> <liclass="ldd_heading">Los Angeles</li> <li><ahref="http://firefly.pdx.local/contoso/la/hr">HR</a></li> <li><ahref="http://firefly.pdx.local/contoso/la/it">IT</a></li> <li><ahref="http://firefly.pdx.local/contoso/la/ops">Ops</a></li> <li><ahref="http://firefly.pdx.local/contoso/la/sales">Sales</a></li> </ul> <ul> <liclass="ldd_heading">Portland</li> <li><ahref="http://firefly.pdx.local/contoso/portland/hr">HR</a></li> <li><ahref="http://firefly.pdx.local/contoso/portland/it">IT</a></li> <li><ahref="http://firefly.pdx.local/contoso/portland/mfg">Mfg</a></li> <li><ahref="http://firefly.pdx.local/contoso/portland/ops">Ops</a></li> </ul> <ul> <liclass="ldd_heading">San Francisco</li> <li><ahref="http://firefly.pdx.local/contoso/sf/hr">HR</a></li> <li><ahref="http://firefly.pdx.local/contoso/sf/it">IT</a></li> <li><ahref="http://firefly.pdx.local/contoso/sf/ops">Ops</a></li> <li><ahref="http://firefly.pdx.local/contoso/sf/sales">Sales</a></li> </ul> <ul> <liclass="ldd_heading">Seattle</li> <li><ahref="http://firefly.pdx.local/contoso/seattle/hr">HR</a></li> <li><ahref="http://firefly.pdx.local/contoso/seattle/it">IT</a></li> <li><ahref="http://firefly.pdx.local/contoso/seattle/mfg">Mfg</a></li> <li><ahref="http://firefly.pdx.local/contoso/seattle/ops">Ops</a></li> </ul> </div> </li> </ul>

  18. $(document).ready(InitSPSGlobalNav); // document.ready function InitSPSGlobalNav() { var scriptbase = _spPageContextInfo.webServerRelativeUrl + "/_layouts/15/"; // Load the Taxonomy Functions we will need to call $.getScript(scriptbase + "SP.Taxonomy.js")..done(function () { var context = SP.ClientContext.get_current(); var taxonomySession = SP.Taxonomy.TaxonomySession.getTaxonomySession(context); // HACK #1 var termStore = taxonomySession.get_termStores().getByName('Managed Metadata Service'); // HACK #2 var termSet = termStore.getTermSet('e093ba58-ba8a-480b-8f4c-0b722b5e0d62'); varterms = termSet.getAllTerms(); context.load(terms, 'Include(IsRoot,Labels,TermsCount, CustomSortOrder,Id, Name, PathOfTerm,Parent, LocalCustomProperties, TermSet.Name)'); navOut = '<ul class="ldd_menu" id="ldd_menu"><li><span style="width:127px;height:25px;">Contoso</span>'; navOut += '<div class="ldd_submenu" style="display:none">';

  19. context.executeQueryAsync(Function.createDelegate(this, function (sender, args) { var termsEnumerator = terms.getEnumerator(); // Create an array for the parent nodes var parents = []; // populate the parents while (termsEnumerator.moveNext()) { var currentTerm = termsEnumerator.get_current(); var children = currentTerm.get_termsCount(); // Save a reference to the parent if (children > 0) { // Save our Parent menu items parents.push(currentTerm); var parent = currentTerm.get_name(); } }

  20. for (var i = 0; i < parents.length; i++) { var parent = parents[i]; var parentID = parent.get_id(); // Write out the Parent entry var item = '<ul><li class="ldd_heading">' + parent.get_name() + '</li>'; navOut += item; termsEnumerator.reset(); while (termsEnumerator.moveNext()) { var currentTerm = termsEnumerator.get_current(); var children = currentTerm.get_termsCount(); // Find the children of this parent varmyParentTerm = currentTerm.get_parent(); varmyParentID = myParentTerm.get_id(); if(myParentID.equals(parentID)) { // Child Term -- write out a LI var item = '<li><a href="' + currentTerm.get_localCustomProperties()['_Sys_Nav_SimpleLinkUrl'] + '">' + currentTerm.get_name() + '</a></li>'; navOut += item; } } // Close out the parent list navOut += '</ul>' }

  21. Create the Placeholder on the SuiteBar publicoverridevoid FeatureActivated(SPFeatureReceiverProperties properties) { SPWebApplication webApp = (SPWebApplication)properties.Feature.Parent; if (webApp != null) { var placeholder = "<div class='ms-core-brandingText' id='GlobalMenu'>Contoso1</div>"; webApp.SuiteBarBrandingElementHtml = placeholder; webApp.Update(); } }

  22. Need to wait for the placeholder to be rendered varinterval = setInterval(function () { // Check if our element is rendered yet if($('#GlobalMenu').length) { // Inject into page $("#GlobalMenu").html(navOut); //Apply Formatting InitMenu(); // all done so stop the timer loop clearInterval(interval); } }, 100);

  23. 3. Custom Rendering • Simple jQuery to handle the hide / show scripting • Create onMouse and onClick handlers to hide / show the menu • Create onMouse to highlight the selected value • Move the menu to where we want it • Simple CSS to handle the styling • Styles for the background color • Styles for the heading • Styles for the menu items • Styles for the footer

  24. function InitMenu() { var$menu = $('#ldd_menu'); $menu.children('li').each(function () { var $this = $(this); var $span = $this.children('span'); $span.data('width', $span.width()); $this.bind('mouseenter', function () { $menu.find('.ldd_submenu').stop(true, true).hide(); $span.stop().animate({ 'width': '850px' }, 300, function () { $this.find('.ldd_submenu').slideDown(300); }); }).bind('mouseleave', function () { $this.find('.ldd_submenu').stop(true, true).hide(); $span.stop().animate({ 'width': $span.data('width') + 'px' }, 300); }); }); }

  25. ul.ldd_menuul{ list-style:none; float:left; border-left:1pxsolid#0072C6; margin:20px0px10px30px; padding:10px; } li.ldd_heading{ font-family: Georgia, serif; font-size: 14px; font-style: italic; font-weight:bold; color:#ffffff; text-shadow:0px0px1px#000000; padding:0px0px10px0px; } ul.ldd_menuullia{ font-family: Arial, serif; font-size:10px; line-height:20px; color:#fff; padding:1px3px; } ul.ldd_menuullia:hover{ -moz-box-shadow:0px0px2px#333; -webkit-box-shadow:0px0px2px#333; box-shadow:0px0px2px#333; background:#0072C6; } ul.ldd_menu{ margin:0px; padding:0; display:block; background-color:#0072C6; list-style:none; font-family:"Trebuchet MS", sans-serif; border-top:1pxsolid#0072C6; border-bottom:1pxsolid#0072C6; border-left:10pxsolid#0072C6; -moz-box-shadow:0px3px4px#0072C6; -webkit-box-shadow:0px3px4px#0072C6; -box-shadow:0px3px4px#591E12; z-index:100; } ul.ldd_menua{ text-decoration:none; } ul.ldd_menu>li{ float:left; position:relative; } ul.ldd_menu>li>span{ float:left; color:#fff; background-color:#0072C6; height:30px; line-height:30px; cursor:default; padding:0px20px; text-shadow:0px0px1px#fff; border-right:1pxsolid#0072C6; border-left:1pxsolid#0072C6; z-index:100; } ul.ldd_menu.ldd_submenu{ position:absolute; top:25px; width:550px; display:none; opacity:0.95; left:0px; font-size:10px; background: #0072C6; border-top:1pxsolid#0072C6; -moz-box-shadow:0px3px4px#0072C6inset; -webkit-box-shadow:0px3px4px#0072C6inset; -box-shadow:0px3px4px#0072C6inset; z-index:100; } a.ldd_subfoot{ background-color:#f0f0f0; color:#444; display:block; clear:both; padding:15px20px; text-transform:uppercase; font-family: Arial, serif; font-size:12px; text-shadow:0px0px1px#fff; -moz-box-shadow:0px0px2px#777inset; -webkit-box-shadow:0px0px2px#777inset; -box-shadow:0px0px2px#777inset; z-index:100; }

  26. 4. Packaging (on-premise) • Deploy the files to the servers (_layouts folder) • Inject our rendering script onto every page • Farm, Web Application or Site Collection scoped feature • Feature adds scriptlinks to every page • Add our placeholder into the suite bar • Call the rendering process at the right time

  27. Packaging <?xmlversion="1.0"encoding="utf-8"?> <Elementsxmlns="http://schemas.microsoft.com/sharepoint/"> <CustomActionScriptSrc="~SiteCollection/_layouts/15/GlobalNavigation/jquery-1.11.1.min.js"Location="ScriptLink"Sequence="90" /> <CustomActionScriptSrc="~SiteCollection/_layouts/15/GlobalNavigation/globalnavigation.js"Location="ScriptLink"Sequence="10000" /> <CustomActionId="MegaCSS"Location="ScriptLink"ScriptBlock="document.write('&lt;link rel=&quot;stylesheet&quot; After=&quot;Corev15.css&quot; type=&quot;text/css&quot; href=&quot;_layouts/15/GlobalNavigation/GlobalNavigation.css&quot;&gt;&lt;/' + 'link&gt;');"Sequence="203" /> </Elements>

  28. Enhancements • Support for Minimal Download Strategy (MDS) • Performance Optimizations • Batch process to generate HTML structure • Cache HTML in memory

  29. SharePoint Online Considerations • Scripting • Lookup the name of the managed metadata provider • Deployment • Can only deploy to a Site Collection (Sandbox Solution) • Separate deployment feature on just the root site collection • Single place to maintain scripts / CSS • Placement • Cannot use SuiteBarBrandingElement technique (no web app in O365) • SharePoint bar has different CSS ID’s and Classes • MS Changes these frequently • Rendering • Need to let Office 365 complete the SharePoint bar rendering

  30. References Global Navigation • http://blog.mastykarz.nl/building-global-navigation-sharepoint-2013/ • http://blog.mastykarz.nl/global-navigation-sharepoint-2013-revisited/ MDS • http://www.wictorwilen.se/the-correct-way-to-execute-javascript-functions-in-sharepoint-2013-mds-enabled-sites Mega menus • http://jaspreetchahal.org/5-best-jquery-css3-navigational-mega-menus

  31. Site Directory

  32. Warning!!! • Entering 400 Level topic • Requires custom application development

  33. Site Directory Issues • Have hundreds or thousands of sites • How do I find them all without just clicking through sites • Don’t want to maintain a manual site directory • Custom SharePoint list with every site listed • Site directory should be security trimmed. You should not see sites you do not have access to. • This is controversial. Sometimes you want to let users discover sites they don’t have access to so they can request access. • Multiple ways to solve this issue.

  34. Need • Need a Directory for all the sites • Need a way to “categorize” sites so we can organize our phone book • Must be security trimmed so we do not know about sites we don’t have access to.

  35. Site Directory Solution • Define metadata on each site to categorize them • Location (Portland, Seattle, LA, …) • Type of site (Intranet, Project, Document Archive, …) • Status of site (Active, Archived, …) • Uses Search Index to find sites • Global Site Directory shows all sites • “Mall Directory” • Search Refiners • Search Term

  36. Site Directory

  37. Site Directory Solution 3 Components to our solution 1. Add Metadata to the site Use web Property bag Describes ways we would want to categorize our sites 2. Add the Metadata to the Search Index Create Search Managed Properties mapped to our Property Bag Values. 3. Custom Search DisplayCreate custom Search Display templates to render our results

  38. Site Metadata • Lots of options • Regions • Portland – Bend – Salem • Oregon – Washington – California - … • North America – Asia – Europe - … • Departments • Sales – HR – Marketing – IT - … • Site Usage • Intranet – Collaboration – Communities – Applications - … • Site Status • Active – Archived – Top Secret (do not list in any directory) • Product / Services • Contoso Electronics – Tailspin Toys – Northwind Bikes - … • Business Units • Contoso - Tailspin - Northwind

  39. Site Level Metadata • Simple for this demo • Location • Portland • Seattle • San Francisco • Los Angeles • Corporate • Site Usage • Intranet - Permanent Sites that are part • Project - Linked to a specific project or initiative • Social – Temporary sites

  40. Metadata • Setting Property Bag Values $web=get-spweb “http://firefly.pdx.local” $web.Properties[“property_name"]= “property_value” $web.Properties.Update() • Secret Sauce (new in 2013) • Adding Property to Indexed Properties $web.IndexedPropertyKeys.Add(“property_value") $web.Update() See PowerShell Script SetSiteProperties.ps1

  41. Property Bag in SharePoint Designer

  42. Search Index • Create Managed Properties in Search Schema • Metadata becomes Searchable • siteLocation:Seattle • siteUsage:Social

  43. Managed Properties • Key Concepts • Create new Managed Properties (siteLocation & siteUsge) • Must be queryable • So we can use siteLocation:Portland • Refinable • So we can include in refinement panels

  44. Search Display • Create a custom Search Display Template • Use the Search Web Parts • Search Results • Search Refiners

More Related