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.
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.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites
Progress collects the Personal Information set out in our Privacy Policy and the Supplemental Privacy notice for residents of California and other US States and uses it for the purposes stated in that policy.
You can also ask us not to share your Personal Information to third parties here: Do Not Sell or Share My Info
We see that you have already chosen to receive marketing materials from us. If you wish to change this at any time you may do so by clicking here.
Thank you for your continued interest in Progress. Based on either your previous activity on our websites or our ongoing relationship, we will keep you updated on our products, solutions, services, company news and events. If you decide that you want to be removed from our mailing lists at any time, you can change your contact preferences by clicking here.