Feature request: Automatic navigation generation from razor pages folder
Closed this issue · 10 comments
This issue is related to #62 .
The feature request is the following: It would be nice if the side navigation could be generated dynamically from a Razor Pages folder such as a docs folder for example.
Such a feature can be found for example in some documentation generators which use Front Matter headers in md files and js files to configure the navbar dynamically.
Content copied from other issue to this one as it doesn't really relate to the other issue's original intent.
@joeaudette
I thought of some potential challenges for what @os1r1s110 is wanting to do, was waiting for the new issue to be created to continue the discussion.
@os1r1s110
Quick update, I'm trying to find a way to implement the feature I talked about but there are some concerns that I'm stumbling on and I'd like your opinion on it.
If I go through the directory to find pages (or use the actionDescriptorCollectionProvider), there's no way to enforce a certain order in the navigation menu (which might be problematic). Is that a valid concern? One potential solution would be to use specially formatted headers in the razor pages in which we could specify the order, but I don't know if that's overkill or not.
Even if I do implement a custom header in the razor pages that is parsed when generating the navigation menu, there is still no way to define in which order each folder will be rendered in navigation.... would anyone have a suggestion?
^I thought maybe we could manually add a node in the navigation.xml for each folder, and then use the pages discovery to generate the sublinks, but that would defeat part of the "automatic discovery" feature....
There might also be some challenges related to the new routing system used with Razor Pages in which users can specify different routes and templates directly inline with the @page directive.
yeah order of pages is one problem that occurred to me last night, I don't have any good ideas for that. Also what if you want nested parent child structures?
Another problem is what about pages that are protected by roles or authorization polices? in the xml you can specify allowedRoles or authorizationPolicy and the menu items are filtered based on the users being in an allowed role or meeting the policy. I haven't been using Razor pages so not sure how it is done there, but in controllers you can decorate an action method with [Authorize(Policy="SomePolicyName")] and in navigation.xml you can put authorizationPolicy="SomePolicyName" to get automatic menu filtering. Maybe if there is a similar attribute in razor pages you could use reflection to get the policy name and assign it to the node.
So with all these challenges to get the behavior you want, just using navigation.xml starts to look like it isn't so bad, it lets you have full control of order and nesting or parent child urls. In my projects I declare all administrative type pages in navigation.xml and only cms pages which come from the db are built using a nested treebuilder.
Effectively using the navigation.xml seems like the best approach if you need to specify all these kind of properties. But that doesn't mean it wouldn't be feasible though as theses properties could be specified in each razor page.
The idea I had was to use a special header (json format enclosed by special delimiters) where we could put the NavigationNode properties (as what's done in the navigation.xml) and deserialize them using Json.Net (or other) when parsing the pages for navigation generation.
The fact is though that this almost completely removes the "automated" part of the process as now instead of having a centralized navigation spec, you need to put the properties into each razor (which might be good for some but bad for others).
yeah needing special headers doesn't make a very generic solution.
Plus to me there is some benefit to seeing the site hierarchy in the navigation xml and having that file in my git repo. It is easy to reason about the site navigation having it there in one place.
you mentioned before:
Such a feature can be found for example in some documentation generators which use Front Matter headers in md files and js files to configure the navbar dynamically.
but that probably works out much easier because the md files can be nested in folders exactly how you want the menu structure, and documentation is usually public so they don't have security concerns like Razor pages may have.
^Yes exactly, and what I'm currently working on is a documentation site, so I effectively didn't have any authorization/security concerns as you say.
That's where the automatic generation could be useful, but even then the ordering problem is still very much present hehe :)
I might have found a potential solution for the ordering problem, I'm putting x- (where x is the numbering) in front of the folders and razor pages so that the ordering is how I want it to be, then I created a new class implementing IPageRouteModelConvention
in which I remove the numbering from the route templates.
This might be enough for simple cases like documentation sites, without supporting all the other features such as authorization, roles etc....
Don't know if that could be useful to you though as it might be a bit too specific but if you think it would, I could try to provide a first working version during the weekend maybe....
yeah I don't think that is something I would want baked in. It could be a separate companion nuget. Probably should be in your own repo, you can take a nuget dependency on cloudscribe.Web.Navigation and put your treebuilder in a class library and ship it as your own nuget. Anything that goes into this code repo I'm on the hook to support it for a long time and I don't really want to have to support that functionality given the limitations of it, would be different if it was more widely useful and obvious how t use it.
Understood and agreed :)