The drop is always movingYou know that saying about standing on the shoulders of giants? Drupal is standing on a huge pile of midgetsAll content management systems suck, Drupal just happens to suck less.Popular open source software is more secure than unpopular open source software, because insecure software becomes unpopular fast. [That doesn't happen for proprietary software.]Drupal makes sandwiches happen.There is a module for that

New menu system

Submitted by nk on Sat, 2006-09-30 23:09

There are lengthy posts of this on the development list, but I will try to describe it again, and there are some news which are not yet covered on devel.

So, instead of caching a huge serialized array per user we store each menu item in a normalized table. The primary key is the path. However, it's not always a real path as it can have a wildcard instead of a part. So, to define the node edit URL, we now have node/%/edit. To stay with this example, instead of 'access' => node_access('update', arg(1)) now we have 'access' => 'node_access', 'access arguments' => array('update', 1). This way we can run the access callback when the user visits the page.

So the user visits node/12/edit. How we find out the relevant menu item? Easy, the possibilites are the following:

node/12/edit
node/12/%
node/%/edit
node/%/%
node/12
node/%
node

Now, if we write a 1 where we see an actual path and 0 where we see the wildcard:

111
110
101
100
11
10
1

Oh. Binary numbers. These are used twice: first, we generate the possible paths using them and also, they serve as the sorting order when hunting for the menu item.

Actually we do not hunt for one menu item but three: one that defines the title, one that defines the access and one that defines the callback. However, this inheritance can be calculated on build time, so by the time a menu gets stored it does have a title, an access and a callback. And this way, we are now back to one path -- one menu item.

The navigation block will work like this: we store into the database the parent, the grandparent, the whole lineage for the item. While we scan for parents we can calculate the inheritance mentioned above. So, when we have our menu item we have all its parents, so we take the direct children of these parents and that's the navigation block. (Some caching here might be in order, but we shall see.)

Also it should be mentioned that the ordering of the menu items in the navigational block is a bit of a problem, but the comment module already contains the solution, so I reused it. Now, the whole navigation block can be retrieved by running db_query('SELECT path, title FROM {menu_new} WHERE pid IN (%s) ORDER BY vancode', $item->parents);.

Commenting on this Story is closed.