Presentation is loading. Please wait.

Presentation is loading. Please wait.

Cross Site Collection Navigation

Similar presentations


Presentation on theme: "Cross Site Collection Navigation"— Presentation transcript:

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

2 Kyle Petersen kyle@pdxportals.com
SharePoint Architect - Petersen Consulting LLC SharePoint Consulting 2004 – – 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 There are lots of SharePoint solutions for navigation

4 Organizational Structures
There are lots of various ways in which SharePoint farms are architected. Sometimes you end up making site boundary decisions Sometimes you just inherit new site collections Can’t always contain everything within a single site collection. I’ve always been confused why Microsoft has so many ways to create new site collections and encourages us to do this, but offers no way to tie them together except through search.

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 Want to create a solution so that you can architect your sites freely. Separate into site collection because of size or database requirements Separate into web applications if needed. But still be able to have a single global navigation to move between the sites

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 Manual Method (Business Process) Custom Sitemap Provider Can also easily create a custom data source that reads the nodes in from other storage such as a SharePoint list. Managed Navigation seemed so promising Still limited to a single site collection at a time

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 Going to create a new global menu Not going to take away any of the other options Site collections can still share the top nav bar Webs can still use the quick launch

9 Our Demo Model

10

11 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

12 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 We need somewhere to define and manage the menu structure With managed navigation the TermStore provides us with all of the features we need

13 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

14 1. Managed Navigation

15 Sort Order

16 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

17

18 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

19 <ul class="ldd_menu" id="ldd_menu">
<li> <span style="width: 127px; height: 25px;">Contoso</span> <div class="ldd_submenu" style="display: none;"> <ul> <li class="ldd_heading">Corporate</li> <li><a href=" <li><a href=" <li><a href=" <li><a href=" <li><a href=" </ul> <li class="ldd_heading">Los Angeles</li> <li><a href=" <li><a href=" <li><a href=" <li><a href=" <li class="ldd_heading">Portland</li> <li><a href=" <li><a href=" <li><a href=" <li><a href=" <li class="ldd_heading">San Francisco</li> <li><a href=" <li><a href=" <li><a href=" <li><a href=" <li class="ldd_heading">Seattle</li> <li><a href=" <li><a href=" <li><a href=" <li><a href=" </div> </li>

20 $(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'); var terms = 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">';

21 context. executeQueryAsync(Function
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(); }

22 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 var myParentTerm = currentTerm.get_parent(); var myParentID = 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>'; } // Close out the parent list navOut += '</ul>'

23 Create the Placeholder on the SuiteBar
public override void 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(); }

24 Need to wait for the placeholder to be rendered
var interval = 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);

25 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

26 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); }

27 ul.ldd_menu ul{ list-style:none; float:left; border-left:1px solid #0072C6; margin:20px 0px 10px 30px; padding:10px; } li.ldd_heading{ font-family: Georgia, serif; font-size: 14px; font-style: italic; font-weight:bold; color:#ffffff; text-shadow:0px 0px 1px #000000; padding:0px 0px 10px 0px; ul.ldd_menu ul li a{ font-family: Arial, serif; font-size:10px; line-height:20px; color:#fff; padding:1px 3px; ul.ldd_menu ul li a:hover{ -moz-box-shadow:0px 0px 2px #333; -webkit-box-shadow:0px 0px 2px #333; box-shadow:0px 0px 2px #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:1px solid #0072C6; border-bottom:1px solid #0072C6; border-left:10px solid #0072C6; -moz-box-shadow:0px 3px 4px #0072C6; -webkit-box-shadow:0px 3px 4px #0072C6; -box-shadow:0px 3px 4px #591E12; z-index:100; } ul.ldd_menu a{ text-decoration:none; ul.ldd_menu > li{ float:left; position:relative; ul.ldd_menu > li > span{ color:#fff; height:30px; line-height:30px; cursor:default; padding:0px 20px; text-shadow:0px 0px 1px #fff; border-right:1px solid #0072C6; border-left:1px solid #0072C6; 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:1px solid #0072C6; -moz-box-shadow:0px 3px 4px #0072C6 inset; -webkit-box-shadow:0px 3px 4px #0072C6 inset; -box-shadow:0px 3px 4px #0072C6 inset; z-index:100; } a.ldd_subfoot{ background-color:#f0f0f0; color:#444; display:block; clear:both; padding:15px 20px; text-transform:uppercase; font-family: Arial, serif; font-size:12px; text-shadow:0px 0px 1px #fff; -moz-box-shadow:0px 0px 2px #777 inset; -webkit-box-shadow:0px 0px 2px #777 inset; -box-shadow:0px 0px 2px #777 inset;

28 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

29 Packaging <?xml version="1.0" encoding="utf-8"?>
<Elements xmlns=" <CustomAction ScriptSrc="~SiteCollection/_layouts/15/GlobalNavigation/jquery min.js" Location="ScriptLink" Sequence="90" /> <CustomAction ScriptSrc="~SiteCollection/_layouts/15/GlobalNavigation/globalnavigation.js" Location="ScriptLink" Sequence="10000" /> <CustomAction Id="MegaCSS" Location="ScriptLink" ScriptBlock="document.write('<link rel="stylesheet" After="Corev15.css" type="text/css" href="_layouts/15/GlobalNavigation/GlobalNavigation.css"></' + 'link>');" Sequence="203" /> </Elements>

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

31 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

32 References Global Navigation MDS Mega menus
MDS enabled-sites Mega menus

33 Site Directory

34 Warning!!! Entering 400 Level topic
Requires custom application development

35 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.

36 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.

37 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

38 Site Directory

39 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 Display Create custom Search Display templates to render our results

40 Site Metadata Lots of options Regions Departments Site Usage
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

41 Site Level Metadata Simple for this demo Location Site Usage 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

42 Metadata Setting Property Bag Values Secret Sauce (new in 2013)
$web = get-spweb “ $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

43 Property Bag in SharePoint Designer

44 Search Index Create Managed Properties in Search Schema
Metadata becomes Searchable siteLocation:Seattle siteUsage:Social

45 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

46

47

48

49

50 Search Display Create a custom Search Display Template
Use the Search Web Parts Search Results Search Refiners

51 Search Directory

52 Search Display Template
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F B3-11d1-A29F-00AA00C14882"> <head> <title>PDX Site Item</title> <!--[if gte mso 9]><xml> <mso:CustomDocumentProperties> <mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden> <mso:MasterPageDescription msdt:dt="string">Displays a result tailored for a SharePoint site.</mso:MasterPageDescription> <mso:ContentTypeId msdt:dt="string">0x C03B61C64EC4A04F5361F </mso:ContentTypeId> <mso:TargetControlType msdt:dt="string">;#SearchResults;#</mso:TargetControlType> <mso:HtmlDesignAssociated msdt:dt="string">1</mso:HtmlDesignAssociated> <mso:ManagedPropertyMapping msdt:dt="string">'Title':'Title','Path':'Path','SiteLogo':'SiteLogo','SiteDescription':'SiteDescription','CollapsingStatus':'Collapsing Status','DocId':'DocId','HitHighlightedProperties':'HitHighlightedProperties','FileExtension':'FileExtension','ViewsLifeTime':'ViewsLif eTime','deeplinks':'deeplinks','importance':'importance','FileType':'FileType','SiteLocation':'SiteLocation','SiteUsage':'SiteUsage'</m so:ManagedPropertyMapping> </mso:CustomDocumentProperties> </xml><![endif]--> </head>

53 Search Display Template
<body> <div id="Item_Site"> <!--#_ if(!$isNull(ctx.CurrentItem) && !$isNull(ctx.ClientControl)){ var id = ctx.ClientControl.get_nextUniqueId(); var itemId = id + Srch.U.Ids.item; $setResultItem(itemId, ctx.CurrentItem); _#--> <div id="_#= $htmlEncode(itemId) =#_" name="Item" data-displaytemplate="SiteItem" class="ms-srch-item" > _#=ctx.RenderBody(ctx)=#_ </div> } </body> </html>

54 <html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F B3-11d1-A29F-00AA00C14882"> <head> <title>PDX Site Item</title> <!--[if gte mso 9]><xml> <mso:CustomDocumentProperties> <mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden> <mso:MasterPageDescription msdt:dt="string">Displays a result tailored for a SharePoint site.</mso:MasterPageDescription> <mso:ContentTypeId msdt:dt="string">0x C03B61C64EC4A04F5361F </mso:ContentTypeId> <mso:TargetControlType msdt:dt="string">;#SearchResults;#</mso:TargetControlType> <mso:HtmlDesignAssociated msdt:dt="string">1</mso:HtmlDesignAssociated> <mso:ManagedPropertyMapping msdt:dt="string">'Title':'Title','Path':'Path','SiteLogo':'SiteLogo','SiteDescription':'SiteDescription','CollapsingStatus':'CollapsingStatus','DocId':'DocId','HitHighlightedProperties':'HitHighlightedProperties','FileExtension':'FileExtension','ViewsLifeTime':'ViewsLifeTime','deeplinks':'deeplinks','importance':'importance','FileType':'FileType','SiteLocation':'SiteLocation','SiteUsage':'SiteUsage'</mso:ManagedPropertyMapping> </mso:CustomDocumentProperties> </xml><![endif]--> </head> <body> <div id="Item_Site"> <!--#_ if(!$isNull(ctx.CurrentItem) && !$isNull(ctx.ClientControl)){ var id = ctx.ClientControl.get_nextUniqueId(); var itemId = id + Srch.U.Ids.item; $setResultItem(itemId, ctx.CurrentItem); // Get a value from the search results var location = $getItemValue(ctx, "SiteLocation"); _#--> <div id="_#= $htmlEncode(itemId) =#_" name="Item" data-displaytemplate="SiteItem" class="ms-srch-item" > <div>Title: _#=ctx.CurrentItem.Title=#_</div> <div>Path: _#=ctx.CurrentItem.Path=#_</div> <div>SiteDescription: _#=ctx.CurrentItem.SiteDescription=#_</div> <div>SiteLocation: _#=ctx.CurrentItem.SiteLocation=#_</div> <div>SiteUsage: _#=ctx.CurrentItem.SiteUsage=#_</div> <div>variable: _#=location=#_</div> </div> } </body> </html>

55 Multiple Uses Global Site Directory Region / Department Directory
Find any site Region / Department Directory Hosted on Web Page Show all child sites within the parent (region or department for example)

56 Enhancements Create Application page to manage the site properties
Use Dropdown lists to set properties Event Receiver (Web Provisioned) Propagate site properties from parent site

57 SharePoint online Considerations
PowerShell is more complicated Invoke CSOM through PowerShell or write command line utility Can’t control full crawls How to request a site crawl Can’t define a managed property to be refinable Have to use the predefined RefinableString00-99 values Map to our crawled term and create alias

58 Re-index a site in O365

59 Site Directory Summary
Configure Property Bag Values on Sites Add Properties to the Site index Full Crawl Map Crawled Property to Managed Property Define property name (used in search) Set correct attributes (queryable, Refinable) Customize the Search Results Search Results Result Type Search Display Template


Download ppt "Cross Site Collection Navigation"

Similar presentations


Ads by Google