CiviCRM v2.1 Menu Redesign

2008-04-18 14:12
Written by
Drupal 6 introduced a new menu system. CiviCRM had modeled its menu system after drupal 4.x which meant we needed to upgrade the menu code significantly to upgrade CiviCRM to Drupal 6. We took the opportunity to learn and understand more from drupal's new system and also simplify the interface between CiviCRM and Drupal with regard to the menu hook. The CiviCRM menu system has been based on the Drupal menu system, so all credit for the below goes to chx and the Drupal folks (all blame should be assigned to us). We have simplified and extended it a bit to meet our needs. Similar to Drupal menu system, the CiviCRM menu data now resides in the database. civicrm_menu stores all the information for a menu item.
CREATE TABLE civicrm_menu (
     id int unsigned NOT NULL AUTO_INCREMENT  ,
     domain_id int unsigned NOT NULL   ,
     path varchar(255)    COMMENT 'Path Name',
     path_arguments text    COMMENT 'Arguments to pass to the url',
     title varchar(255)    COMMENT 'Menu Title',
     access_callback varchar(255)    COMMENT 'Function to call to check access permissions',
     access_arguments text    COMMENT 'Arguments to pass to access callback',
     page_callback varchar(255)    COMMENT 'function to call for this url',
     page_arguments text    COMMENT 'Arguments to pass to page callback',
     breadcrumb text    COMMENT 'Breadcrumb for the path.',
     component_id int unsigned    COMMENT 'Component that this menu item belongs to',
     is_active tinyint    COMMENT 'Is this menu item active?',
     is_public tinyint    COMMENT 'Is this menu accessible to the public?',
     is_exposed tinyint    COMMENT 'Is this menu exposed to the navigation system?',
     weight int NOT NULL  DEFAULT 1 COMMENT 'Ordering of the menu items in various blocks.',
     type int NOT NULL  DEFAULT 1 COMMENT 'Drupal menu type.',
     page_type int NOT NULL  DEFAULT 1 COMMENT 'CiviCRM menu type.'

We now interface with Drupal with only one menu item, i.e. the top level 'civicrm' item which does a callback into the civicrm code. This menu item is not permissioned, i.e. everyone has access. Permissioning is now handled within the CiviCRM menu system, which should make it a bit easier to transition to our ACL based permissioning system (currently being tested in the standalone release). Instead of storing the menu items as php arrays, we store it in a xml format. The menu xml files are in the civicrm templates directory. The xml files are read only during the menu rebuild process to populate the menu table. This process is run only at install / upgrade time. Hence there is no performance penalty for using xml based storage. This does enable folks to edit and change entries at the xml level if needed. We are also planning to implement "menu hooks" for use by other civicrm modules. This is a significant improvement over the current approach, where folks needed to write their own "invoke file" and hack some civicrm code to integrate other components. We do a fair amount of computation during menu rebuild. To make things more efficient in the rendering process, we ensure that all menu items have all the database fields. Thus we propagate values for access_callback et al down the path tree if not already specified. We also compute the values for the navigation and admin blocks for the system and also the breadcrumb for each path. This saves on processing and db lookups when we render a civicrm page. The above changes let us get rid of all the Invoke files in the system. It also makes things more consistent and easier to extend. I suspect there is also some performance impact for the better. Most of the changes described above are implemented and functional in trunk
Filed under


Is this going to be for the 2.1 version ?

As for the menu, are you going to take that opportunity to reorganise it (contentwise) as well ? I've read various comments on the forum about people not finding it intuitive (myself including) and some usability gurues offering to help, has it reached something ?


P.S. Certainly not the right place to ask, but is it possible to use it to create a shortcut block with your own links (eg using profiles) ?

forums post and the offers to help by usability folks

I'll have to take a look and see how the shortcuts block is created, but potentially it can be moved to the menuing system also



Can we expect civicrm menu hooks or api functions for easily & dynamically injecting options into menus?

we dont have it right now in the code base, but i do plan on adding it when we revisit and do some more cleanup / development on the menu system in the next few weeks