Skip to content

Instantly share code, notes, and snippets.

@hawjeh
Last active October 4, 2024 03:27
Show Gist options
  • Save hawjeh/7ef54bed4a1bcfccb99067feaf020168 to your computer and use it in GitHub Desktop.
Save hawjeh/7ef54bed4a1bcfccb99067feaf020168 to your computer and use it in GitHub Desktop.
Sitefinity Navigation
@model Telerik.Sitefinity.Frontend.Navigation.Mvc.Models.INavigationModel
@using Newtonsoft.Json;
@using Progress.Sitefinity.Renderer.Models;
@using Telerik.Sitefinity.Frontend.Mvc.Helpers;
@using Telerik.Sitefinity.Frontend.Navigation.Mvc.Models;
@using Telerik.Sitefinity.Libraries.Model;
@using Telerik.Sitefinity.Services;
@using Telerik.Sitefinity.Web;
@{
// Less efficient old Code
// var pageManager = PageManager.GetManager();
// var pageNodes = pageManager.GetPageNodes().ToList();
// var homePageNode = pageNodes.Where(n => n.Id == homepageId).FirstOrDefault();
// var navPic = homePageNode.GetRelatedItems<Image>("NavPic").FirstOrDefault();
// Access Page property via SiteMapBase instead of PageManager / PageNode
// https://www.progress.com/documentation/sitefinity-cms/for-developers-access-custom-fields-through-the-sitemapnodes
// https://community.progress.com/s/article/how-to-get-the-published-pages-that-are-included-in-the-navigation-from-the-sitemap-via-api
var provider = SiteMapBase.GetCurrentProvider() as SiteMapBase;
// To get homepage
var homepageId = SystemManager.CurrentContext.CurrentSite.HomePageId;
var homePageSiteNode = provider.FindSiteMapNodeFromKey(homepageId.ToString()) as PageSiteNode;
// Access custom field of homepage via PageSiteNode
var navPic = (Image)homePageSiteNode.GetCustomFieldValue("NavPic");
var navLink = JsonConvert.DeserializeObject<List<LinkModel>>(homePageSiteNode.GetCustomFieldValue("NavLink").ToString());
var hideFromNav = (bool)homePageSiteNode.GetCustomFieldValue("HideFromMainNavigation");
}
@model Telerik.Sitefinity.Frontend.Navigation.Mvc.Models.INavigationModel
@using Newtonsoft.Json;
@using Progress.Sitefinity.Renderer.Models;
@using Telerik.Sitefinity.Frontend.Mvc.Helpers;
@using Telerik.Sitefinity.Frontend.Navigation.Mvc.Models;
@using Telerik.Sitefinity.Libraries.Model;
@using Telerik.Sitefinity.Services;
@using Telerik.Sitefinity.Web;
@*Add scripts and stylesheets*@
@Html.Script(Url.Content("~/ResourcePackages/Bootstrap5/assets/dist/js/popper.min.js"), "frameworks", false)
@Html.Script(Url.Content("~/ResourcePackages/Bootstrap5/assets/dist/js/bootstrap.min.js"), "frameworks", false)
@{
// CUSTOM:
// Less efficient old Code
// var pageManager = PageManager.GetManager();
// var pageNodes = pageManager.GetPageNodes().ToList();
// var homePageNode = pageNodes.Where(n => n.Id == homepageId).FirstOrDefault();
// var navPic = homePageNode.GetRelatedItems<Image>("NavPic").FirstOrDefault();
// Access Page property via SiteMapBase instead of PageManager / PageNode
// https://www.progress.com/documentation/sitefinity-cms/for-developers-access-custom-fields-through-the-sitemapnodes
// https://community.progress.com/s/article/how-to-get-the-published-pages-that-are-included-in-the-navigation-from-the-sitemap-via-api
var provider = SiteMapBase.GetCurrentProvider() as SiteMapBase;
// To get homepage
var homepageId = SystemManager.CurrentContext.CurrentSite.HomePageId;
var homePageSiteNode = provider.FindSiteMapNodeFromKey(homepageId.ToString()) as PageSiteNode;
// Access custom field of homepage via PageSiteNode
var navPic = (Image)homePageSiteNode.GetCustomFieldValue("NavPic");
var navLink = JsonConvert.DeserializeObject<List<LinkModel>>(homePageSiteNode.GetCustomFieldValue("NavLink").ToString());
var hideFromNav = (bool)homePageSiteNode.GetCustomFieldValue("HideFromMainNavigation");
}
<div class="@Model.CssClass">
<nav class="navbar navbar-expand-md navbar-light bg-light">
<div class="container-fluid">
@* @Html.Action("GetView", new { viewName = "Dropdown", model= Model}) *@
<a class="navbar-brand" href="/">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target='#@Html.UniqueId("navbar")' aria-controls='@Html.UniqueId("navbar")' aria-expanded="false" aria-label="@Html.Resource("ToggleNavigation")">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id='@Html.UniqueId("navbar")'>
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
@{
int i = 0;
foreach (var node in Model.Nodes)
{
@RenderRootLevelNode(node, i, provider);
i++;
}
}
</ul>
</div>
</div>
</nav>
</div>
@*Here is specified the rendering for the root level*@
@* CUSTOM: Passing down SiteMapBase provider *@
@helper RenderRootLevelNode(NodeViewModel node, int i, SiteMapBase provider)
{
// CUSTOM: Access custom field of node page via PageSiteNode
var pageSiteNode = provider.FindSiteMapNodeFromKey(node.Key) as PageSiteNode;
var navPic = (Image)pageSiteNode.GetCustomFieldValue("NavPic");
var navLink = JsonConvert.DeserializeObject<List<LinkModel>>(pageSiteNode.GetCustomFieldValue("NavLink").ToString());
var hideFromNav = (bool)pageSiteNode.GetCustomFieldValue("HideFromMainNavigation");
if (node.ChildNodes.Count > 0)
{
<li class="nav-item dropdown @GetClass(node)">
<a class="nav-link dropdown-toggle" href="#" id='@Html.UniqueId("navbarDropdownMenuLink" + i)' role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">@node.Title</a>
<ul class="dropdown-menu" aria-labelledby='@Html.UniqueId("navbarDropdownMenuLink" + i)'>
@RenderSubLevelsRecursive(node, i)
</ul>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link @GetClass(node)" href="@node.Url" target="@node.LinkTarget">@node.Title</a>
</li>
}
}
@*Here is specified the rendering for all child levels*@
@helper RenderSubLevelsRecursive(NodeViewModel node, int i)
{
int j = 0;
foreach (var childNode in node.ChildNodes)
{
if (childNode.ChildNodes.Count > 0)
{
<li class="nav-item dropdown @GetClass(node)">
<a class="dropdown-item pe-4 @GetClass(childNode)" href="@childNode.Url">
@childNode.Title
</a>
<span class="p-1 position-absolute top-0 end-0 @GetClass(childNode)" id='@Html.UniqueId("navbarDropdownMenuLink" + i + j)' role="button" data-bs-auto-close="outside" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<svg class="svg-inline--fa fa-w-16" aria-hidden="true">
<use xlink:href="~/ResourcePackages/Bootstrap5/assets/dist/sprites/solid.svg#@GetCaretDirection()"></use>
</svg>
</span>
<ul class="dropdown-menu top-0 start-100 mt-n2" aria-labelledby='@Html.UniqueId("navbarDropdownMenuLink" + i + j)'>
@RenderSubLevelsRecursive(childNode, j)
</ul>
</li>
}
else
{
<li>
<a class="dropdown-item pe-4 @GetClass(childNode)" href="@childNode.Url" target="@childNode.LinkTarget">@childNode.Title</a>
</li>
}
j++;
}
}
@*Resolves the class that will be added for each node depending whether it is selected*@
@helper GetClass(NodeViewModel node)
{
if (node.IsCurrentlyOpened)
{
@Html.HtmlSanitize("active");
}
else if (node.HasChildOpen)
{
@Html.HtmlSanitize("active");
}
}
@*Resolves the caret direction depending on language direction*@
@helper GetCaretDirection()
{
if (Html.RenderDirAttribute().ToString() != "dir=\"rtl\"")
{
@Html.HtmlSanitize("caret-right");
}
else
{
@Html.HtmlSanitize("caret-left");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment