Custom Menu Navigation Control
Hi Team,
I need to create custom menu navigation control using MVC thunder.
Kindly help me by providing some code for that.
Hi Mateen,
In order to achieve your desired scenario you have to implement your custom solution. I believe that the following resources could be helpful.
Creating MVC Widgets with Sitefinity Thunder
Using ASP.NET MVC in Sitefinity
Regards,
Kaloyan
Telerik
Hi Kaloyan,
Thanks for the reply. Well I am aware of creating MVC widgets with Sitefinity.
My issue was, I need to develop custom widget for Navigation control, Using Sitefinity API.
I want to fetch all parent pages and their child pages upto "N" level, and want to present in View of MVC widget.
Kindly help me with this.
Thanks in advance.
Regards,
Mateen
Has anyone done this yet? I'm not crazy about working with Webforms in our current environment, and I'd like to avoid reinventing the wheel, if possible.
Hello,
I have created a simple widget that uses the Page Manager and gets all pages and their children recursively. Then you can show them in the view. I have shown only the top 3 levels, however, you can define a recursive method that will show them all in the view, since all pages and children are saved in the Model.
Result Mvc Nav; Result Built-in Nav;
Controller (all pages are get to n levels in-depth):
public
class
MVCNavigationController : Controller
public
List<PageNodeModel> pagesAll =
new
List<PageNodeModel>();
public
List<PageNodeModel> nav =
new
List<PageNodeModel>();
/// <summary>
/// This is the default Action.
/// </summary>
public
ActionResult Index()
var model =
new
MVCNavigationModel();
var manager = PageManager.GetManager();
var pages = manager.GetPageNodes()
.Where(n => n.ShowInNavigation ==
true
&& n.ApprovalWorkflowState ==
"Published"
&& n.ParentId == SiteInitializer.CurrentFrontendRootNodeId)
.Select(PageNodeModel.ToModel).ToList();
pagesAll = pages;
GetChildNodesRecursively(pagesAll);
model.Nav = nav;
return
View(
"Default"
, model);
public
void
GetChildNodesRecursively(List<PageNodeModel> pagesToQuery)
var manager = PageManager.GetManager();
foreach
(var item
in
pagesToQuery)
var pages = manager.GetPageNodes().Where(n => n.ShowInNavigation ==
true
&& n.ApprovalWorkflowState ==
"Published"
&& n.ParentId == item.Id)
.Select(PageNodeModel.ToModel)
.ToList();
if
(pages !=
null
)
if
(item.ParentId == SiteInitializer.CurrentFrontendRootNodeId)
item.ChildNodes = pages;
nav.Add(item);
else
item.ChildNodes = pages;
GetChildNodesRecursively(pages.ToList());
else
nav.Add(item);
@model SitefinityWebApp.Mvc.Models.MVCNavigationModel
@*three levels shown; the url are returned relative ('~/...'), so we get absolute*@
@foreach (var item in Model.Nav)
<
div
>
<
a
href
=
"@item.Url.Substring(2, item.Url.Length - 2)"
>@item.Title</
a
>
<
div
>
@foreach (var child in item.ChildNodes)
<
a
href
=
"@child.Url.Substring(2, child.Url.Length - 2)"
style
=
"margin-left:30px"
>@child.Title</
a
>
foreach (var node in child.ChildNodes)
<
div
><
a
href
=
"@node.Url.Substring(2, node.Url.Length - 2)"
style
=
"margin-left:60px"
>@node.Title</
a
></
div
>
</
div
>
</
div
>
public
class
MVCNavigationModel
public
MVCNavigationModel()
this
.Nav =
new
List<PageNodeModel>();
public
List<PageNodeModel> Nav
get
;
set
;
public
class
PageNodeModel
public
Guid Id
get
;
set
;
public
string
Title
get
;
set
;
public
List<PageNodeModel> ChildNodes
get
;
set
;
public
PageNodeModel()
this
.ChildNodes =
new
List<PageNodeModel>();
public
Guid ParentId
get
;
set
;
public
string
Url
get
;
set
;
public
static
Func<PageNode, PageNodeModel> ToModel
get
return
pn =>
new
PageNodeModel()
Id = pn.Id,
Url = pn.GetFullUrl(),
ParentId = pn.ParentId,
Title = pn.Title,
;
Thanks, Nikola. I'll try that out.
Hi Doug,
I hope the provided widget help you create your custom one and achieve what you wanted. You can use similar approach to the one for getting the pages initially, to create the method for iterating recursively the collection in the view. Write back if you need further assistance.
Regards,
Nikola Zagorchev
Telerik
That helped a lot, thank you. I have it mostly working now, but I can't see where you're getting the method GetFullUrl() for this line in the model:
Url = pn.GetFullUrl()
Is there a Sitefinity assembly I should be using, or am I building that myself? I couldn't see it in Telerik.Sitefinity.Pages.Model.PageNode or your model code.
Doug
Hi Doug,
You should add a reference to Telerik.Sitefinity.Modules.Pages to be able to use the extension method. Another option is to get the URL using the ContentLocationService, but this way you should iterate the pages and get them loaded in the memory:
public
static
string
ItemAbsoluteUrl(
this
PageNode node)
var url = SystemManager.GetContentLocationService().GetItemDefaultLocation(node,
default
(CultureInfo)).ItemAbsoluteUrl;
return
url;
Ah, that's the piece I was missing, thanks! The Telerik.Sitefinity.Modules.Pages reference worked perfectly.
Just wanted to make a note on this: The posted MVC solution doesn't seem to take into account permissions.
What would be great is if we could see the included MVC navigation widget code. It is really close to what I need, but isn't quite there.
Hello
The forum thread is quite old. It is much better to use the built-in Mvc navigation widget coming with Feather. Another option is to built your own navigation using the Sitemap provider since its much faster than querying the pages through the manager plus uses caching. You can also use a helper to recursively show the nodes. You can view a sample in this blog post.
Regards,
Nikola Zagorchev
Telerik