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

How can we display the top link navigation from another site collection at MySite? We now have a custom master page with some custom code but it only shows the current site menu. We want it to show the menu from another specific site collection.

This is how we create the additional menu:

<%@ Register TagPrefix="PublishingNavigation" Namespace="Microsoft.SharePoint.Publishing.Navigation" Assembly="Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<publishingnavigation:portalsitemapdatasource id="globalmenuSiteMap" runat="server" enableviewstate="false"
                    sitemapprovider="GlobalNavSiteMapProvider" startfromcurrentnode="false" startingnodeoffset="0"
                    showstartingnode="true" trimnoncurrenttypes="Heading" />

<SharePoint:AspMenu ID="TopNavigationMenuV42" runat="server" EnableViewState="false" EncodeTitle="False"
                        DataSourceID="globalmenuSiteMap" AccessKey="<%$Resources:wss,navigation_accesskey%>"
                        UseSimpleRendering="true" UseSeparateCSS="false" Orientation="Horizontal" StaticDisplayLevels="2"
                        MaximumDynamicDisplayLevels="4" SkipLinkText="" CssClass="s4-tn" />
share|improve this question

2 Answers 2

up vote 2 down vote accepted

Unless you want to hard code the links or use some custom data source I only know two different ways to do this, the bad and the horrible way.

The horrible way

Set the current SPWeb to the desired SPWeb and then initialize the menu, for example in a UserControl:

using (var site = new SPSite("http://localhost"))
{
  using (var web = site.OpenWeb())
  {
    var request = new HttpRequest("", web.Url, "");
    var sw = new StringWriter();
    var response = new HttpResponse(sw);
    var originalRequest = HttpContext.Current;
    HttpContext.Current = new HttpContext(request, response);
    SPControl.SetContextWeb(HttpContext.Current, web);
    var siteMapDataSource = new PortalSiteMapDataSource 
    {
      SiteMapProvider = "GlobalNavSiteMapProvider"
    };

    var menu = new AspMenu {DataSource = siteMapDataSource};
    menu.DataBind();
    Controls.Add(menu);
    HttpContext.Current = originalRequest;
    SPControl.SetContextWeb(HttpContext.Current, SPContext.Current.Web);
  }
}

The bad way

(and probably not working properly)

Create your own provider which fetches the navigation directly from the SPWeb:

public class CustomSiteMapProvider : PortalSiteMapProvider
{
  private const string SiteUrl = "http://localhost";

  private static IEnumerable<SPNavigationNode> GetNavigationNodes(string url)
  {
    using (var site = new SPSite(SiteUrl))
    {
      using (var web = site.OpenWeb(url))
      {
        return PublishingWeb.GetPublishingWeb(web).Navigation.GlobalNavigationNodes.
          Cast<SPNavigationNode>().ToList();
      }
    }
  }

  public override SiteMapNodeCollection GetChildNodes(SiteMapNode node)
  {
    var navNodes = GetNavigationNodes(node.Url).ToList();
    var navNode = navNodes.FirstOrDefault(n => n.Url == node.Url);
    if (navNode != null) navNodes= navNode.Children.Cast<SPNavigationNode>().ToList();
    var nodes = navNodes.Select(n => 
      new SiteMapNode(this, n.Url, n.Url, n.Title)).ToArray();
    return new SiteMapNodeCollection(nodes);
  }

  protected override SiteMapNode GetRootNodeCore()
  {
    var publishingNodes = GetNavigationNodes("/");
    var node = publishingNodes.FirstOrDefault();
    if (node == null) return null;
    node = node.Parent;
    return new SiteMapNode(this, node.Url, node.Url, node.Title);
  }
}

Use it like this:

var menu = new AspMenu 
{
  DataSource = new SiteMapDataSource
  {
    Provider = new CustomSiteMapProvider()
  }
};
menu.DataBind();
Controls.Add(menu);

Note that you must call site.OpenWeb for every child SPWeb as SPNavigationNode might have 0 .Children.
Also note that it is using Publishing and Portal, but you can also extend from for example SiteMapProvider for provider (must include more methods) and for nodes you can use web.Navigation.GlobalNodes.

share|improve this answer
    
Mind shedding some light into the dark why the "horrible way" is so horrible? Just out of curiosity ;-) Reason I'm asking is that I was looking for such a way recently without altering the masterpage but rather adding a WebControl via AdditionalPageHead. –  Sig Weber Nov 1 '12 at 17:06
1  
It is horrible because SPContext.Current.SPWeb and HttpContext.Current is temporarily altered to be that of another SPWeb. You see I reset it with the originalRequest variable, if this is not done then every controller and code running after the controller would use wrong SPWeb. I'm not sure how horrible that is, but perhaps if there are several threads using the static properties it would cause havoc. –  eirikb Nov 1 '12 at 17:38
1  
I made my example with a simple UserControl, you can add this to any delegate control, such as AdditionalPageHead, or override the search field and just pad the menu to left with CSS. I also imagine you can use the same "temporary SPWeb hack" to alter the SiteMapSource for the data source delegate as well, with your own DataSource. –  eirikb Nov 1 '12 at 17:42
    
Thanks for clarifying, eirikb. Much appreciated! –  Sig Weber Nov 1 '12 at 18:11

So you already have the navigation bar but need to display the links? I had this issue on My Sites before and to solve it I used a sitemap.

I basically defined all my links for the navigation bar in the sitemap and referenced it in the masterpage. Now whenever a new link is added to the regular site I need to update the sitemap for the My Sites.

Hope that helps!

share|improve this answer
    
Yes we have the custom navigation bar but the links are the same as for MySite. I was hoping there was a easy way doing this without any need for updates... If we only could have the custom navigation bar on the MySite site collection to inherit the navigation from parent site collection it would solve the problem. –  stiangodo Oct 30 '12 at 22:46
    
Hmm, I'm not too sure how you can do that. I was trying to do the same thing and ended up just using the site map as outlined here: blah.winsmarts.com/… , basically all sites I came across mentioned doing it this way so I went with it, although it does mean that you have to update the site map when changes are made to the main site... –  Tudor Oct 31 '12 at 15:33
    
How did you create the custom navigation bar? I just copy/pasted the code for the TopNavBar from the master page of the regular site into the new site and that gave me the abilty to use the sitemap. Here's another resource: michaelbrockman.wordpress.com/2010/07/06/… –  Tudor Oct 31 '12 at 15:34

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.