Make it easier for extensions to add Navigation Menu items
Background
Extensions have a few ways of adding to the navigation menu, and none of them are great.
-
hook_civicrm_navigationMenu()
- brute-forces an item into the menu. It's relatively easy to implement (thanks to some extra fudging thatcivix
does for you) but defeats the whole configurability idea; users and administrators have no control over the item. -
install
/uninstall
hooks - this is hard to implement as there are a lot of edge cases to consider (domains, weights, etc) and you have to manage the full lifecycle yourself (install, disable, enable, uninstall). -
hook_civicrm_managed()
- this handles the lifecycle for you, but not the domains, and the weights are completely by guesswork. Changes made by the user (e.g. deleting the menu item) might be undone byManaged::reconcile
. -
.aff.php
- Afforms allow you to declare a navigation menu as part of the form - this gets delegated tohook_civicrm_managed()
, with all the same problems that carries, plus the additional problem that user-changes to the item can lose sync with the Afform settings (see #4364 (closed)).
IMO items 1 and 2 are unfixable, but item 3 has promise, and item 4 could be deprecated in favor of 3.
Outstanding problems with Managed Navigation Menu Items.
-
1. ManagedEntities cannot be deleted. If a user deletes a managed Navigation item, it will respawn with the next Managed::reconcile
. -
2. Navigation BAO doesn't even call hooks, defeating the ManagedEntity update=unmodified
mode. -
3. ManagedEntities are not domain-aware; if you want your navigation item to appear on all domains (which you do, since your extension will be enabled globally - there are no per-domain extensions), you have to declare a managed navigation item once per domain (which is a bit awkward). -
4. Picking a weight
is pure guesswork. You just have to put in an integer and hope it lands in the right spot. Picking0
will pretty reliably place it at the top; anything else is a roll of the dice.
Proposed Solutions
- Fixed via ManagedEntities - Recreate deleted records at discretion of update policy.
- Fixed via dev/core#4364 Use writeRecord for Navigations so menu changes for managed entities don't reset.
- Fixed via ManagedEntity - Replicate multi-domain entities when multisite is enabled.
-
Here is a PR to add a
previous
andnext
join in APIv4 which would allow you to specify the name of the menu item you wish to insert next to. For example, to add a menu item just below the "Find Contacts" menu item, you'd say['previous.name' => 'Find Contacts']
in your managed declaration (in lieu of `'weight' => 5'). - To deprecate the Afform navigation handling, we can still support it in the Admin form, but instead of writing to the
.aff.json
file and that getting picked up byafform_civicrm_managed()
the admin form could just save the navigation item directly. We can also teach the newcivix export
command to generate a.mgd.php
for every navigation menu item associated with an Afform.
Edited by colemanw