How to get the CurrentNode or a Node by a key in a view
Closed this issue · 3 comments
What is the best and simplest way to get the CurrentNode of the page (view) so I can in example print the title of node as the page title or h1 header.
In the Nuget package MvcSiteMapProvider you could do it like this:
@Html.MvcSiteMap().SiteMapTitle()
Is it also possible to get a node by an id? Let's say I want to have the ResolvedUrl of a node than I want to get the node by a key and use in example the title and ResolvedUrl to generate a hyperlink.
The reason that I want to do it this was is because I want to write the url of a page once in my application. or get it from a database. In the rest of the application it should be generated.
In MvcSiteMapProvider you could do it like this:
MvcSiteMapProvider.SiteMaps.Current.FindSiteMapNodeFromKey(HereTheKey).ResolvedUrl
This is not MvcSiteMapProvider and does not work like that. There are no static methods. If you expect it to be like MvcSiteMapProvider you will be disappointed. It is completely different architecture and does not try to solve other concerns than navigation menus.
There is an asp.net core viewcomponent which can be invoked and you can optionally pass in a starting node key as shown in the main documentation. to make a menu of child nodes starting from a specific node.
The NavigationViewModel is passed into the view by the view component and it has methods to get the current node etc. But current node can be null if the current url does not correspond to a menu item.
You can make custom views and could possibly use it for headings and such but that is not its purpose, this project is for naivigation menus and breadcrumbs. You can see the included views to understand how the viewmodel works with the views. Other parts of your content such as heading are separate concerns unrelated to the purpose of this project. My advice is don't use it for other things.
Thank you for the fast response. I know that this isn't the MvcSiteMapProvider project. I haven't given enough background information for my specific question.
I'm converting a big application to core. The last thing that I need to convert is the MvcSiteMapProvider. This package isn't working with core. I saw your comments pointing to your package. I implemented you package and read all the code. Looks great (haven't tested it live because I still get build errors).
I saw the code that multiple views are rendered from that one ViewComponent. It is almost exactly what I need. You say that this project isn't designed to get the title of a node and use it for a pagetitle or header. But why not? The project is also used for:
- a sitemap;
- custom attributes;
- dynamic nodes for in example blogposts;
I agree that static methods are not the best way. I just pointed them out for reference so you know what i'm trying to do. I'm only searching for the best performing way to get the CurrentNode or by Key in a view. Creating extra views for the ViewComponent was the idea that I had and when I read you comment, than that is the best way until now.
Ah, ok your scenario migrating an existing app makes sense. From within a custom view you should have no trouble doing what you want. The NavigationViewModel provides RootNode which is the rootnode but also the entire tree hangs from that so you can get a node by key like this:
@{
var myNode = Model.RootNode.FindByKey("yourkey");
}
For new apps I would not myself use this for headings and such but I don't condemn it if someone else wants to do that or needs to for porting an existing app that already does that. I like to keep separate concerns separate. I know that people will use this for purposes beyond what I designed it for, I just want to be careful not to find myself officially supporting other uses or scope creep beyond what I designed it for.
To your other points SiteMap for google is a separate concern and is a separate project and library, but it made sense to be able to use the existing navigation tree as a datasource for the sitemap since we have to build this data anyway, so there is a separate integration library that makes that possible it is not built into the navigation library. The sitemap can have multiple sources and I would not add everything to the menu just to populate the site map. I do not add blog posts to the navigation tree as dynamic nodes I only add dynamic temporary breadcrumbs hanging off of the one actual node that is the index of the blog. I have a separate way that blog posts get added to the site map as a separate data source from the navigation tree. I do add dynamic nodes for cms pages which are in the menu. My idea for custom data-* attributes is main;y to support extra data for wiring up javascript to specific menu nodes if needed.