Problem/Motivation
When the menu tree is rebuilt during a cache clear that occurs right after database updates (e.g., drush is used with drush updb
), the entries for manually added menu links (Menu Link Content entities) that link to a path aliases are registered without a route. While the menu links still get rendered and link to the alias, the active menu trail doesn't work for these pages. This means if you have a menu block setup to render levels 2+ of the active trail, they won't get shown at all.
This happens because in a cache clear (which occurs at the end of the the db update process), the menu router is rebuilt, which also rebuilds the menu trees. Each menu link plugin is asked for its definition, which includes the route and route options (if the link it to a routed path). Menu links that link to internal paths are stored wiht a uri value of internal:/path/alias/name
. So MenuLinkContent::getPluginDefinition()
checks if the url is routed or not, and to do that it passes the /path/alias/name
through PathProcessorManager::processInbound<code>, which loops through all the registered inbound path processors. One of those processors is <code>AliasPathProcessor
which converts aliased paths to system paths. But this processor is de-registered via UpdateServiceProvider
and doesn't run, so the aliases path if never converted to a routed path.
The menu tree entry for links set up like this have empty values for "route_name" and "route_param_key". This is what leads to issues with menu active trail processing.
A fix is to clear caches again, outside of the update process.
Steps to reproduce
- Fresh install of core with standard profile.
- Add a Basic Page with alias "/parent-page".
- Add a Basic Page with alias "/parent-page/sub-page".
- To the main menu, add a menu link labeled "Parent Page" and type in "/parent-page" for the link path
- To the main menu, add a menu link labeled "Sub-Page" and type in "/parent-page/sub-page" for the link path. Make it a child of Parent Page.
- Visit /parent-page/sub-page in a browser and inspect the
<li>
of the parent menu link for the parent page. Observe CSS class primary-nav__menu-item--active-trail
is present.
- Inspect the
menu_tree
table in the database and look at entries for the parent and sub-page menu links. Observe that the values for route_name
and route_param_key
show the route info for the node route with the proper IDs.
- Add a new post_update hook to
system.post_update.php
with nothing in it. Doesn't matter, just need one pending update hook.
- Visit update.php or use drush updb to run updates.
- Visit /parent-page/sub-page in a browser and inspect the
<li>
of the parent menu link for the parent page. Observe CSS class primary-nav__menu-item--active-trail
is missing.
- Inspect the
menu_tree
table in the database and look at entries for the parent and sub-page menu links. Observe that the values for route_name
and route_param_key
are empty.
Proposed resolution
π
Path aliases are not available in hook_post_update_NAME
Active
is a related issue and it suggests that we stop removing the AliasPathProcessor
from the service container when db updates are being run, as the reason we originally did it (
π
Switch to a null backend for all caches for running the database updates
Fixed
) is not relevant anymore.
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet