Last updated September 18, 2008. Created on December 9, 2006.
Edited by Senpai, robertDouglass, redndahead, ax. Log in to edit this page.

The Drupal menu system was always much more than what the name suggests. It's not only used to display visible navigation menus but also to map Drupal paths to their callbacks with proper access checking. This second task is called dispatching. The likely rationale behind this; once you define a link to a page, you might want to define what happens when you click that link.

This eventually led to a very complex data structure which was stored as a serialized array in the database -- per user. Unserializing this on every non-cached page load uses tons of memory. Altering this either on build or run time needs dirty hacks.

Some misunderstandings about how access to an element applies to their children led to grave security holes with some contributed modules. This stresses the need for thought out, cleanly defined inheritance rules.

We have a new menu system in Drupal 6.x. The data is divided between two tables: {menu_router} and {menu_links}. The {menu_router} table is built based on the callbacks defined by implementations of hook_menu, and Drupal now looks in this table to determine access and the appropriate callback function when a site visitor tries to navigate to a particular path. Everything belonging to one path is one row in a database table, so the memory footprint is significantly smaller. The inheritance rules for access, etc. are cleanly laid out in the documentation. The {menu_links} table contains the links that are displayed in the Navigation and other menu blocks. Some of these items are derived automatically from {menu_router}, but others may be added by the site administrator using the menu module or other modules.

Looking for support? Visit the forums, or join #drupal-support in IRC.