Question

My site is dynamically creating the sitemap from both database and xml data. This is working great, however, for a portion of the site that lists news articles it was decided to not put the news article detail pages in the site map. So if you were to click on the title of a news article (from the listing page that is in the sitemap) it would take you to the page with the article, but that page/url is not in the sitemap.

I have controls and logic in the master pages that use

SiteMap.CurrentNode

Essentially, on page load I would like to change SiteMap.CurrentNode to the node of the news article listing page (which is in the sitemap). So essentially all of the logic running on this page will treat the page as if it was the listing page. I can't find anyway to do this.

This code will get me the node that I want as I know its key.

SiteMapDataSource siteMapDataSource1 = new SiteMapDataSource();
    siteMapDataSource1.SiteMapProvider = "Main";
    SiteMapNode newsListingPageNode = siteMapDataSource1.Provider.FindSiteMapNodeFromKey(siteMapKey);

So basically I wish I could do this:

SiteMap.CurrentNode = newsListingPageNode;

But CurrentNode can't be set.

Any suggestions on how I could do this? I appreciate the help.

Was it helpful?

Solution

According to this article, you can create a custom handler for the SiteMapResolve event, and presumably you could return a custom node from that.

OTHER TIPS

Here is the solution I came up with, though it's a little too complexed for my liking. Remember the issue is the currently viewed page is not in the sitemap and navigation, controls, and other logic is expecting to use the sitemap provider. Since the page isn't in the sitemap, the sitemap provider is not available, thus the reason I have to manually set the sitemap and the current node. We choose not to have the news pages in the sitemap as it would significantly increase the overall size of the sitemap.

First, I use a custom ThisNode property of the dynamic sitemap provider rather than the SiteMap.CurrentNode property.

     public static SiteMapNode ThisNode
    {
        get
        {
            if (_thisNode == null)
            {
                if (SiteMap.CurrentNode != null)
                {
                    return SiteMap.CurrentNode;
                }
                else
                {
                    return null;
                }
            }
            else
            {
                return _thisNode;
            }
        }
        set
        {
            _thisNode = value;
        }
    }

On the News detail page (/news-and-events-detail.aspx) I call a utility method created in the dynamic provider.

    // Set the ThisNode property to the /news-and-events-list.aspx node.
    // This will allow all sitemap driven controls and logic (such as navs, info bar, and dynamic links) to function since these detail pages are not in the sitemap.
    DynamicSiteMapProviders.SetThisNodeToAlternateNode("/news-and-events-list.aspx");

This is the utility method:

    /// <summary>
    /// Sets the DynamicSiteMapProviders.ThisNode property to the node of specified URL.
    /// </summary>
    /// <param name="urlOfNodeToSetTo">The URL of the node to set from.</param>
    public static void SetThisNodeToAlternateNode(string urlOfNodeToSetTo)
    {
        SiteMapDataSource siteMapDataSource = new SiteMapDataSource();
        siteMapDataSource.SiteMapProvider = "Main";
        DynamicSiteMapProviders.ThisNode = siteMapDataSource.Provider.FindSiteMapNode(urlOfNodeToSetTo);
    }

Now in the base master page I have to reset the DynamicSiteMapProviders.ThisNode property since its static and I don't want the next page I visit to still use the manually set node. I do this when the page is done running logic and rendering by utilizing the OnUnload() event of the page life cycle. Look at the logic of Get/Set of the ThisNode property above.

// This ensures that DynamicSiteMapProviders.ThisNode is not set to the node of a previously viewed page.
// This is mainly for news and events pages that are not in the sitemap and are using the news and events listing page node as the current node.
protected override void OnUnload(EventArgs e)
{
    DynamicSiteMapProviders.ThisNode = null;
    base.OnUnload(e);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top