Pregunta

¿Cómo podemos mostrar la navegación de enlace superior desde otra colección del sitio en MySite? Ahora tenemos una página maestra personalizada con algún código personalizado, pero solo muestra el menú del sitio actual. Queremos que muestre el menú de otra colección específica del sitio.

Así es como creamos el menú adicional:

<%@ 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" />

¿Fue útil?

Solución

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.

Otros consejos

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!

Licenciado bajo: CC-BY-SA con atribución
scroll top