Try Now
More in this section
Blogs RSS feed

Dynamic content in navigation

by Vassil Vassilev

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. nav

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)
                    //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 goging to:
                        //Sitefintiy 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 instert the new items under - it will be displayed as a public property int he widget property editor as well
        public string ParentPageToPlaceUnder
                return parentPageToPlaceUnder;
                this.parentPageToPlaceUnder = value;
        //you cna configure a default page to insert the new itmes 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.


Leave a comment