Dynamic content in navigation

Dynamic content in navigation

August 01, 2014 0 Comments

The content you're reading is getting on in years
This post is on the older side and its content may be out of date.
Be sure to visit our blogs homepage for our latest news, updates and information.

Making a dynamic navigation that incorporates product offerings, content or specials can drastically improve the end user experience. This blog post explains a technique that allows you to extend the navigation to include any type of content. 

Currently Sitefinity can display only items of type PageNode (i.e. Pages) in the out of the box Navigation controls.

In order to display dynamic content, you would need custom navigation control, which will be bound to the SitefinitySiteMapDataSource - our control that provides a cached data source of the pages sitemap. You can subscribe to the navigation control's ItemDataBound event, and insert new items under the desired page, by using the Sitefinity API to retrieve a collection of the content items of the desired type.

For example:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MixedNavigation.ascx.cs" Inherits="SitefinityWebApp.SupportSamples.MixedNavigation" %>
<%@ Register TagPrefix="sfNav" Namespace="Telerik.Sitefinity.Web.UI.NavigationControls" Assembly="Telerik.Sitefinity" %>
  
<sfNav:SitefinitySiteMapDataSource id="navDataSource" runat="server" ShowStartingNode="false" />
<telerik:RadMenu id="rmNavigation" runat="server" DataSourceID="navDataSource"></telerik:RadMenu>

and its code-behind logic:

using System;
using System.Globalization;
using System.Linq;
using Telerik.Sitefinity.Modules.Ecommerce.Catalog;
using Telerik.Sitefinity.Services;
using Telerik.Sitefinity.Web;
  
namespace SitefinityWebApp.SupportSamples
{
    public partial class MixedNavigation : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //Subscribe to ItemDataBound so you can insert new items under desired node on data binding
            rmNavigation.ItemDataBound += rmNavigation_ItemDataBound;
        }
  
        void rmNavigation_ItemDataBound(object sender, Telerik.Web.UI.RadMenuEventArgs e)
        {
            if (e.Item.DataItem is PageSiteNode)
            {
                var page = e.Item.DataItem as PageSiteNode;
                //Check if the current item is the desired PageNode
                if (page.Title == ParentPageToPlaceUnder)
                {
                    //Get the collection of items
                    var manager = CatalogManager.GetManager();
                    var products = manager.GetProducts()
                        .Where(p => p.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live && p.visible == true)
                        .ToList();
                    //Get the ContentLocationService - it stores the URL statistics for all Sitefinity data items
                    var contLocationService = SystemManager.GetContentLocationService();
                    //Get the current culture, to ensure you're resolving the correct URL
                    var culture = CultureInfo.CurrentUICulture;
                    //iterate through the collection and add a new item in the navigation with the item's Title and resolved URL
                    foreach (var product in products)
                    {
                        var itemAbsoluteUrl = "";
                        //Please ensure your items are displayed at least on one page in the site, otherwise GetItemDefaultLocation() will be null
                        //You can get a list of the generated item locations by going to:
                        //Sitefinity backend -> Content -> Your desired content type -> Pages where items of your content type are published
                        if (contLocationService.GetItemDefaultLocation(product, culture) != null)
                            itemAbsoluteUrl = contLocationService.GetItemDefaultLocation(product).ItemAbsoluteUrl;
                        e.Item.Items.Add(new Telerik.Web.UI.RadMenuItem(product.Title, itemAbsoluteUrl));
                    }
                }
            }
        }
  
        //You can configure the desired page to insert the new items under - it will be displayed as a public property int he widget property editor as well
        public string ParentPageToPlaceUnder
        {
            get
            {
                return parentPageToPlaceUnder;
            }
            set
            {
                this.parentPageToPlaceUnder = value;
            }
        }
  
        //you can configure a default page to insert the new items under
        private string parentPageToPlaceUnder = "MyTargetPage";
    }
}

For your convenience I've attached the full sample to this blog post here, please feel free to modify it as per your specific requirements. You can also find here a short demonstrative video of the sample used on a  Sitefinity page.

 You can also consider assigning related products or other data directly to pages through custom fields for pages, which will allow your business users to define exactly what custom dynamic content will appear in the mega menu. You can review the documentation for querying custom fields for pages to find out what API methods to use.

 

Vassil Vassilev

View all posts from Vassil Vassilev on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.

Comments
Comments are disabled in preview mode.
Topics
 
 
Latest Stories in
Your Inbox
Subscribe
More From Progress
d12fcc0bdb669b804e7f71198c9619a7
5 Questions Automakers Should Ask to Improve Asset Uptime
Download Whitepaper
 
SF_MQ_WCM
2018 Gartner Magic Quadrant Web Content Management (WCM)
Download Whitepaper
 
What-Serverless-Means-For-Enterprice-Apps-Kinvey
What Serverless Means for Enterprise Apps
Watch Webinar