This is very much a draft, and may not be the right approach. However, what I started at the Lille code sprint is now working, and in the process I was able to become familiar with much of the current navigation module code.
Problem/Motivation
Site builders need to be able to customize the Navigation toolbar menu through the user interface, as they can today with the toolbar module.
Currently, the navigation module implements new plugin types for navigation sections. It also directly interacts with routes to build many links, which makes it harder for site builders to customize.
Proposed resolution
First, instead of implementing a brand-new plugin type, we add a NavigationBlock type that overlaps and extends the Block plugin definition. This gives us some flexibility in that:
- We can easily generate blocks for all system menus (included in this MR).
- We can in a future issue add a "developer mode" option or submodule that derives all regular blocks into navigation blocks for placement in the navigation menu. For example, if environment indicator exposes a block, then a developer will be able test out their module, or adventurous site builders can play with unsupported blocks.
- We can choose later to derive regular block plugins from all navigation block plugins. Since they implement a superset of the Block annotation attributes, and the same interface methods, they should work reasonably well.
Second, we ship and generate the links for a new Content menu. That way, site builders can turn off specific entity bundle links for the "add" links, or add their own. They could even add an external link if key content is actually managed outside of Drupal. This MR implements this dynamically (similar to some existing code) so things don't break if a module (like media) doesn't exist or a view is deleted.
Third, we place the blocks into the navigation menu with a few hardcoded calls. In a future issue, this would be replaced with a UI that allows users to select from all exposed NavigationBlocks and place them in the content or footer sections.
Remaining tasks
Discuss!
User interface changes
We add a new top-level Content menu: Here's an example of the current menu in Umami:

And part of the Content menu:

| Comment | File | Size | Author |
|---|---|---|---|
| #8 | SCR-20231109-kpg.png | 661.65 KB | deviantintegral |
| #4 | SCR-20231026-rpm.png | 220.18 KB | deviantintegral |
| #3 | SCR-20231026-rmd.png | 377.21 KB | deviantintegral |
Issue fork navigation-3397058
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
deviantintegral commentedComment #3
deviantintegral commentedComment #4
deviantintegral commentedComment #6
deviantintegral commentedYesterday, we had a call reviewing this with @ckrina, @laurii, @ted.bowman, @tim.plunkett, and myself, along with some followup chats.
This is from my own notes on the call, feel free to comment if I misrepresent anything!
In terms of functionality, site builders:
Developers:
From a technical perspective, this is actually the first time plugin implementations have been subclassed in core. @tim.plunkett pointed out that there's real dragons as far as backwards compatibility goes, especially with constructors. There are instances of contrib modules doing this (like superfish), but in practice we may make things simpler and just ditch the whole aspect of subclassing. As well, it may be easier to alter in additional block annotation properties than to try and do an entirely separate annotation type.
We also discussed shipping a single block plugin that renders other blocks, instead of literally deriving block plugins.
For next steps, I would like to:
Comment #7
lauriiiComment #8
deviantintegral commentedI've redone how the plugins are handled and I'm much happier with the approach. IMO it's simpler and more robust.
Instead of a separate annotation, we now look for
navigationon the normal Block annotation. I've defined it as an array, so we can add keys like default_region, weight, and so on. To do this, we add our own plugin manager that wraps the block manager (it's not really decoration because we don't swap the service). It handles filtering available plugins and validating the additional keys.Then, I implemented the announcements feed as a demo block. An interesting side effect is that the Announcements menu item works as is, showing the dialog of announcements on the left hand side.
For next steps, it would be great for someone else to look at what I've done with the navigation block manager and share any compatibility concerns or similar I may have missed.
Comment #9
deviantintegral commentedTo followup and summarize on next steps for this:
There's some skepticism that it will be possible to have a single block implementation that can ever work in both a navigation and non-navigation context.
The block system has intentionally been designed to not include any sort of real rendering context in the `build()` method.
There's also some worry that if there are separate blocks implemented to handle these cases, that the regular block admin could have duplicate blocks.
While Blocks have a context system (
\Drupal\layout_builder\Plugin\Block\ExtraFieldBlockdoes this to associate an entity object), in practice they are best used for data and not theme or rendering information.A good next step would be to walk this back to having a separate plugin implementation, _but_ still have Navigation blocks implement or extend
\Drupal\Core\Block\BlockPluginInterface. That interface already defines most of what we need for navigation blocks, and would provide a familiar pattern for contrib modules to implement navigation support, or to more easily extend and share code for existing blocks if it does make sense.Comment #11
prashant.c@deviantintegral,
Thanks for your efforts!
@ckrina,
The following tasks have been completed by @deviantintegral; please correct me if I've missed anything:
src/Plugin/Block/NavigationMenuBlock.phprenders the menu links from the "Content" menu.While there are various other changes made, for now, I suggest focusing on incorporating the Navigation Block and related code to display "Content" menu links in the sidebar from the backend.
I am ready to commence integrating the necessary modifications into https://www.drupal.org/project/navigation/issues/3408298
Thanks!
Comment #12
deviantintegral commentedThanks Prashant! I see two next steps depending on your comfort and interest.
\Drupal\Core\Block\BlockPluginInterface. But, the discovery, namespace, and directory should be separated out again.I've had some things come up that will limit my availability for this, so I'm really glad to see you here offering to help. Thanks!
Comment #13
ckrinaThanks @deviantintegral for the directions!
Then work from 1 can be addressed in #3408298: Create the Content menu, and this issue can focus on 2.
Comment #14
m4oliveiWill be working on this early next week. I have some things done locally, will aim to get a more complete MR ready.
Comment #15
m4oliveiI've pushed up my work. I'm not totally convinced this is done, would appretiate thoughts / opinions. In summary, I have:
Comment #16
prashant.c@m4olivei I tested it manually and seems to be working fine and changes are reflecting properly in the frontend for the following:
1. Rearrange menu items.
2. Disabling menu items.
3. Adding menu items.
Comment #17
prashant.c@m4olivei,
It appears that the merge request has conflicts. Would you mind checking and resolving them at your convenience?
Changing the issue status to NW.
Thank you.
Comment #18
m4oliveiThanks @Prashant.c. I'm expecting more merge conflicts when #3408298: Create the Content menu is merged, which feels like it will be soon. Once that lands, I'll sort it all out here.
Comment #19
m4oliveiI've resolved the conflicts that the recent merges to 1.x brought.
Comment #22
m4oliveiJust to note, Tugboat is not happy ATM b/c I bumped the core_version_requirement to ^10.2. It fails on trying to enable the module b/c of that.
This shouldn't be an issue b/c we're declaring a tag of
q0rban/tugboat-drupal:10for the Tugboat image. Per the docs that should net us the latest 10.x release (at time of writing 10.2.0). Looks like the images live on DockerHub, and the last tagged images were posted 6 months ago. Latest 10.1.x is 10.1.0 (despite latest being 10.1.7) and there are no 10.2.x tagged images. I've reached out to the Tugboat support folks on this.Comment #23
m4oliveiThanks @deviantintegral. I've made all the suggested changes.
I think I could go further here, but it's as good a place as any to stop. I'm thinking that when we start to tackle an admin UI for placing Navigation Sections, we're going to need a new config entity type that is like the block config entity type in order to store config for each instance of a Navigation Section placed. Just like Blocks. The next step in my mind is to create that config entity, and then arrange for navigation module to be installed with the default instances of Navigation Section config entity in the navigation side bar that we have now. But I think that's distinct enough that we're at a good stopping point.
@ckrina I've marked all threads in the MR with ✅ indicating they are resolved. I don't see any pending feedback from @Prashant.c. Also as a bonus, Tugboat is back in action for this MR! The Tugboat support folks fixed an issue where the Drupal 10.2 images were missing in action.
Given @deviantintegral's thumbs up, I'll go ahead and mark this as RTBC. Feel free to adjust if I'm overstepping.
Comment #25
ckrinaSeeing this as RTBC is great news! I understand this can go further but it can happen in follow-ups, so merging this to be sure the follow-ups are easier to address.
Thanks all!
Comment #26
m4oliveiYay! Thansk @ckrina!