10

मैं एक SharePoint समाधान पर एक कस्टम वर्तमान (बाएं) नेविगेशन पर काम कर रहा हूं।शेयरपॉइंट कस्टम वर्तमान नेविगेशन/पोर्टलसाइटमैपप्रोवाइडर

मुझे क्या चाहिए कि नेविगेशन की जड़ एक भिन्नता वेब है, रूट वेब का तत्काल बच्चा। इस बदलाव के तत्काल बच्चे हैं जो सभी साइटें और पेज दिखाई दे सकते हैं, हालांकि विस्तृत नहीं किया गया है। केवल साइटें जो वर्तमान साइट के पूर्वजों हैं, को विस्तारित किया जाना चाहिए ... वर्तमान साइट/पेज पर सभी तरह से।

एक उदाहरण ... अगर मैं पेज http://spsite.ex/variation/site2/subsite2.1/subsite2.1.1/subsite2.1.1.3/page.aspx पर शुरू मैं देखना चाहिए ...

Site1 
Site2 
    SubSite2.1 
     SubSite2.1.1 
      SubSite2.1.1.1 
      SubSite2.1.1.2 
      SubSite2.1.1.3 
       page.aspx (YOU ARE HERE) 
    SubSite2.2 
    Site2Page1 
    Site2Page2 
Site3 
Site4 
Site5 

मैं तो SubSite2.1 के लिए लिंक पर क्लिक करें यदि मैं कुछ की तरह देखना चाहिए ...

Site1 
Site2 
    SubSite2.1 (YOU ARE HERE) 
     SubSite2.1.1 
    SubSite2.2 
    Site2Page1 
    Site2Page2 
Site3 
Site4 
Site5 

मैं तो http://spsite.ex/variation/site5/subsite5.1/page.aspx पर नेविगेट करते हैं मैं कुछ की तरह देखना चाहिए ...

Site1 
Site2 
Site3 
Site4 
Site5 
    SubSite5.1 
     SubSite5.1.1 
     page.aspx (YOU ARE HERE) 

मैंने समाधान लिखा है, लेकिन मुझे लगता है कि यह ऐसा नहीं है जिसे मुझे गर्व महसूस करना चाहिए; मैंने AspMenu को पास-इनफिनिएंट StaticDisplayLevels दिया है और फिर GetChildNode(node) को वर्तमान वेब के पूर्वजों को छोड़कर, बच्चे नोड्स प्राप्त करने के लिए PortalSiteMapProvider को ओवरराइड किया है।

+0

क्या आपका समाधान काम करता है? –

+0

यूप! मुझे लगता है कि मैं सत्यापन की तलाश में हूं कि मुझे समझ में आया कि मैं क्या कर रहा हूं और मुझे यह कैसे करना चाहिए, या अगर मुझे कुछ खराब कोड ऑफसेट खरीदने की ज़रूरत है: पीआई का मतलब है, निकट-अनंत 'स्टेटिक डिस्प्लेलेवल'। .. और यदि 'PortalSiteMapDataSource' में 0 का प्रारंभिकोडऑफसेट' है (रूट से) मुझे अपवाद मिलते हैं ... इसलिए यह थोड़ा गंध करता है। –

+2

यह ऐसी चीज है जो शेयरपॉइंट को वास्तव में आउट-ऑफ-द-बॉक्स नेविगेशन नियंत्रण के साथ करने की अनुमति देनी चाहिए, यह देखते हुए कि इंटरनेट पर इसका उपयोग आमतौर पर किया जाता है - शायद 2010 के बाद के अगले संस्करण में ... –

उत्तर

1

@ScottE तुलना में बहुत सरल नहीं बनाया जा सकता, मुझे लगता है कि मैं कोड पुन: पेश करने प्रबंधित किया है एक समाधान

using System; 
using System.Web; 
using Microsoft.SharePoint; 
using Microsoft.SharePoint.Publishing; 
using Microsoft.SharePoint.Publishing.Navigation; 

namespace StackOverflow.SharePoint 
{ 
    public class Question2602537PortalSiteMapProvider : PortalSiteMapProvider 
    { 

     public override SiteMapNodeCollection GetChildNodes(System.Web.SiteMapNode node) 
     { 
      bool expandChildNodes = false; 
      if (SPContext.Current != null) 
      { 
       expandChildNodes = NodeIsAncestorOfCurrentNode(node); 
      } 

      if (expandChildNodes) 
      { 
       return base.GetChildNodes(node); 
      } 
      else 
      { 
       return new SiteMapNodeCollection(); 
      } 
     } 

     private bool NodeIsAncestorOfCurrentNode(System.Web.SiteMapNode node) 
     { 
      bool returnvalue = false; 
      SPSecurity.RunWithElevatedPrivileges(delegate() 
      { 
       using (SPSite thisSite = new SPSite(SPContext.Current.Site.ID)) 
       { 
        using (SPWeb nodeWeb = this.OpenWeb(thisSite, node)) 
        { 
         using (SPWeb currentWeb = this.OpenNavWeb(thisSite)) 
         { 
          returnvalue = this.AncestorDescendantWebs(nodeWeb, currentWeb); 
         } 
        } 
       } 
      }); 
      return returnvalue; 
     } 

     private SPWeb OpenWeb(SPSite thisSite, System.Web.SiteMapNode node) 
     { 
      // need to use Uri objects, as sometimes the node URL contains a query string 
      // but calling OpenWeb(...) with a ? in your URL throws an exception 
      // using Uri.LocalPath removes the Query String 
      Uri siteUri = new Uri(thisSite.Url); 
      Uri nodeUri = new Uri(siteUri, node.Url); 
      return thisSite.OpenWeb(nodeUri.LocalPath.Split(new string[] { "/_" }, StringSplitOptions.RemoveEmptyEntries)[0], false); 
     } 

     private SPWeb OpenNavWeb(SPSite thisSite) 
     { 
      using (SPWeb currentWeb = thisSite.OpenWeb(this.CurrentWeb.ID)) 
      { 
       SPWeb web = currentWeb; 
       PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web); 

       // Loop all the way up the webs until we find the one which doesn't inherit 
       // (there's gotta be a better way of doing this) 
       while (publishingWeb.InheritCurrentNavigation && 
        !web.ID.Equals(thisSite.RootWeb.ID)) 
       { 
        web = web.ParentWeb; 
        publishingWeb = PublishingWeb.GetPublishingWeb(web); 
       } 

       return web; 
      } 
     } 

     private bool AncestorDescendantWebs(SPWeb ancestor, SPWeb descendant) 
     { 
      // check the URLs to determine if descendant is a subweb or ancestor 
      // (there's gotta be a better way...) 
      if ((descendant.ServerRelativeUrl + "/").ToUpper().StartsWith(ancestor.ServerRelativeUrl.ToUpper() + "/")) 
      { 
       return true; 
      } 
      return false; 
     } 

    } 
} 

शायद नहीं सबसे अच्छा समाधान ... लेकिन: मैं इस समस्या को हल करने के लिए इस्तेमाल किया।

+0

[@Pauli Østerø के उत्तर] पर देख रहे हैं (http://stackoverflow.com/questions/2602537/sharepoint-custom-current-navigation-portalsitemapprovider/4612334#4612334) मुझे आश्चर्य है कि विधि 'SiteMap.CurrentNode।IsEqualToOrDescendantOf (SiteMapNode) 'का उपयोग इतनी सारी' एसपीवेब 'ऑब्जेक्ट्स बनाने से बचने के लिए किया जा सकता है। –

0

यदि आप एक कस्टम कोडेड समाधान करना चाहते हैं तो आप श्रेणीबद्ध डेटाटाउंड कंट्रोल से विरासत में एक वर्ग बना सकते हैं। मास्टरपेज/पेजेलआउट में पोर्टलसाइटमैपडाटासोर्स के साथ इसे हुक करें। यह आपको आउटपुट का पूरा नियंत्रण देगा और जैसा कि अनुकूलित किया जा सकता है।

0

क्या करता है अपने कोड देखो की तरह ... की तरह एक ठेठ मेनू इस का उपयोग कर मानक SiteMapProvider इस

public class SideMenu : Control 
{ 
    private SiteMapNode _rootNode = SiteMap.RootNode; 
    public SiteMapNode RootNode 
    { 
     get { return this._rootNode; } 
     set { this._rootNode = value; } 
    } 

    public SideMenu() 
    { 
     ID = "SideMenu"; 
    } 

    protected override void CreateChildControls() 
    { 
     var div = new HtmlGenericControl("div"); 
     div.Attributes.Add("id", ID); 
     Controls.Add(div); 

     CreateMenuNodes(RootNode, div); 

     base.CreateChildControls(); 
    } 

    protected override void Render(HtmlTextWriter writer) 
    { 
     if (!ChildControlsCreated) 
     { 
      CreateChildControls(); 
     } 

     base.Render(writer); 
    } 

    private void CreateMenuNodes(SiteMapNode node, HtmlGenericControl container) 
    { 
     if (node.HasChildNodes) 
     { 
      var ul = new HtmlGenericControl("ul"); 
      container.Controls.Add(ul); 

      foreach (SiteMapNode child in node.ChildNodes) 
      { 
       var li = new HtmlGenericControl("li"); 
       ul.Controls.Add(li); 

       var a = new HtmlAnchor() 
       { 
        InnerHtml = HttpUtility.HtmlEncode(child.Title), 
        Title = child.Title, 
        HRef = child.Url 
       }; 

       li.Controls.Add(a); 

       if (SiteMap.CurrentNode.IsEqualToOrDescendantOf(child)) 
       { 
        li.Attributes["class"] = "selected"; 

        CreateMenuNodes(child, li); 
       } 
      } 
     } 
    } 
} 
0

यहां एक और विकल्प है जो बहुत अधिक सुरुचिपूर्ण है। http://sharepoint2010customnavigation.blogspot.com/

+0

वह आलेख SharePoint 2010 के बारे में है; मैंने अपने प्रश्न में निर्दिष्ट नहीं किया था, लेकिन यह MOSS2007 के बारे में था –

संबंधित मुद्दे