Elgg Blog: Elgg's New Menu System: Registering a menu item

By Cash

One of the bigger changes in Elgg 1.8 is its new menu system. Previously, Elgg had distinct functions and methodologies for its different menus. To add to the site menu, add_menu() was used. Adding to the sidebar menu required a called to add_submenu_item(). The user hover menu worked through view extensions.

There was discussion in the Elgg developers Google group about creating a consistent naming convention for the functions. That discussion quickly progressed to a redesign of the menu system with a single API for all menus. This is the first in a series of posts on this new menu API.

Registering during initialization

Most of the registration for Elgg's menus occurs during Elgg's boot process or early in a page handler (a page handler is a controller in MVC terminology). The site menu and page (sidebar) menu are two examples of this. In the bookmarks plugin, it registers its site menu item like this:

elgg_register_menu_item('site', array(
	'name' => 'bookmarks',
	'text' => elgg_echo('bookmarks'),
	'href' => 'bookmarks/all'

Alternatively, elgg_register_menu_item() also accepts an instance of the ElggMenuItem class as demonstrated by pages plugin:

$item = new ElggMenuItem('pages', elgg_echo('pages'), 'pages/all');
elgg_register_menu_item('site', $item);


Just-in-time registration

While registering early works for the site menu or the footer menu, it does not support something like a user's hover menu. This menu depends on access to the ElggUser object for its links and there will be many on an page. This is handled by a plugin hook that is triggered just before the menu is rendered. Consider the messages plugin. It registers a handler for the plugin hook:

elgg_register_plugin_hook_handler('register', 'menu:user_hover', 'messages_hover_menu');

It's handler function makes sure the viewer is logged in and then adds the appropriate link to the menu:

function messages_hover_menu($hook, $type, $return, $params) {
	$user = $params['entity'];
	if (elgg_is_logged_in() && elgg_get_logged_in_user_guid() != $user->guid) {
		$url = "messages/compose?send_to={$user->guid}";
		$item = new ElggMenuItem('send', elgg_echo('messages:send'), $url);
		$return[] = $item;

	return $return;

The handler is passed an array with all the currently registered menu items (in $return) and another array with the ElggUser object (in $params). The handler can add, remove, or modify menu items. What it returns is passed to additional handlers registered for that plugin hook.

What's next?

In the next post in this series, I'll cover the optional parameters available when registering a menu item. I'll show you how to create context-sensitive menus and multi-level menus along with demonstrating how to divide a menu into sections.

Latest comments