summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2004-07-10 18:10:36 +0000
committerDries Buytaert <dries@buytaert.net>2004-07-10 18:10:36 +0000
commitf163fa99569885de43a65e3e411637d0bf806c81 (patch)
treee1fb344a26d69401aa28b2f4a270ad51647915a8 /includes
parent1f288c11c43f647020a928d6e2f3fabccac191fe (diff)
downloadbrdo-f163fa99569885de43a65e3e411637d0bf806c81.tar.gz
brdo-f163fa99569885de43a65e3e411637d0bf806c81.tar.bz2
- Patch by JonBob: a significant documentation update for the menu system!
Diffstat (limited to 'includes')
-rw-r--r--includes/menu.inc91
1 files changed, 71 insertions, 20 deletions
diff --git a/includes/menu.inc b/includes/menu.inc
index 9e9e2b5f9..95d47ed9b 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -4,6 +4,60 @@
/**
* @defgroup menu Menu system
* @{
+ *
+ * The Drupal menu system drives both the navigation system from a user
+ * perspective and the callback system that Drupal uses to respond to URLs
+ * passed from the browser. For this reason, a good understanding of the
+ * menu system is fundamental to the creation of complex modules.
+ *
+ * Drupal's menu system follows a simple hierarchy defined by paths.
+ * Implementations of hook_menu() define menu items and assign them to
+ * paths (which should be unique). The menu system aggregates these items
+ * and determines the menu hierarchy from the paths. For example, if the
+ * paths defined were a, a/b, e, a/b/c/d, f/g, and a/b/h, the menu system
+ * would form the structure:
+ * - a
+ * - a/b
+ * - a/b/c/d
+ * - a/b/h
+ * - e
+ * - f/g
+ * Note that the number of elements in the path does not necessarily
+ * determine the depth of the menu item in the tree.
+ *
+ * When responding to a page request, the menu system looks to see if the
+ * path requested by the browser is registered as a menu item with a
+ * callback. If not, the system searches up the menu tree for the most
+ * complete match with a callback it can find. If the path a/b/i is
+ * requested in the tree above, the callback for a/b would be used.
+ *
+ * The found callback function is called with any arguments specified in
+ * the "callback arguments" attribute of its menu item. After these
+ * arguments, any remaining components of the path are appended as further
+ * arguments. In this way, the callback for a/b above could respond to a
+ * request for a/b/i differently than a request for a/b/j.
+ *
+ * For an illustration of this process, see page_example.module.
+ *
+ * Access to the callback functions is also protected by the menu system.
+ * The "access" attribute of each menu item is checked as the search for a
+ * callback proceeds. If this attribute is TRUE, then access is granted; if
+ * FALSE, then access is denied. The first found "access" attribute
+ * determines the accessibility of the target. Menu items may omit this
+ * attribute to use the value provided by an ancestor item.
+ *
+ * In the default Drupal interface, you will notice many links rendered as
+ * tabs. These are known in the menu system as "local tasks", and they are
+ * rendered as tabs by default, though other presentations are possible.
+ * Local tasks function just as other menu items in most respects. It is
+ * convention that the names of these tasks should be short verbs if
+ * possible. In addition, a "default" local task should be provided for
+ * each set. When visiting a local task's parent menu item, the default
+ * local task will be rendered as if it is selected; this provides for a
+ * normal tab user experience. This default task is special in that it
+ * links not to its provided path, but to its parent item's path instead.
+ * The default task's path is only used to place it appropriately in the
+ * menu hierarchy.
*/
/**
@@ -34,19 +88,21 @@ define('MENU_LINKS_TO_PARENT', 0x0200);
/**
* Normal menu items show up in the menu tree and can be moved/hidden by
- * the administrator.
+ * the administrator. Use this for most menu items. It is the default value if
+ * no menu item type is specified.
*/
define('MENU_NORMAL_ITEM', MENU_VISIBLE_IN_TREE | MENU_VISIBLE_IN_BREADCRUMB | MENU_MODIFIABLE_BY_ADMIN);
/**
* Item groupings are used for pages like "node/add" that simply list
- * subpages to visit.
+ * subpages to visit. They are distinguished from other pages in that they will
+ * disappear from the menu if no subpages exist.
*/
define('MENU_ITEM_GROUPING', MENU_VISIBLE_IF_HAS_CHILDREN | MENU_VISIBLE_IN_BREADCRUMB | MENU_MODIFIABLE_BY_ADMIN);
/**
* Callbacks simply register a path so that the correct function is fired
- * when the URL is accessed.
+ * when the URL is accessed. They are not shown in the menu.
*/
define('MENU_CALLBACK', MENU_VISIBLE_IN_BREADCRUMB);
@@ -57,33 +113,33 @@ define('MENU_CALLBACK', MENU_VISIBLE_IN_BREADCRUMB);
define('MENU_DYNAMIC_ITEM', MENU_VISIBLE_IN_TREE | MENU_VISIBLE_IN_BREADCRUMB);
/**
- * Modules may "suggest" menu items that the administrator may enable.
+ * Modules may "suggest" menu items that the administrator may enable. They act
+ * just as callbacks do until enabled, at which time they act like normal items.
*/
define('MENU_SUGGESTED_ITEM', MENU_MODIFIABLE_BY_ADMIN);
/**
- * Local tasks are rendered as tabs by default.
+ * Local tasks are rendered as tabs by default. Use this for menu items that
+ * describe actions to be performed on their parent item. An example is the path
+ * "node/52/edit", which performs the "edit" task on "node/52".
*/
define('MENU_LOCAL_TASK', MENU_IS_LOCAL_TASK);
/**
- * Local subtasks are rendered as a horizontal listing below the tabs by default.
- */
-define('MENU_LOCAL_SUBTASK', MENU_IS_LOCAL_SUBTASK);
-
-/**
* Every set of local tasks should provide one "default" task, that links to the
* same path as its parent when clicked.
*/
define('MENU_DEFAULT_LOCAL_TASK', MENU_IS_LOCAL_TASK | MENU_LINKS_TO_PARENT);
/**
- * Custom items are those defined by the administrator.
+ * Custom items are those defined by the administrator. Reserved for internal
+ * use; do not return from hook_menu() implementations.
*/
define('MENU_CUSTOM_ITEM', MENU_VISIBLE_IN_TREE | MENU_VISIBLE_IN_BREADCRUMB | MENU_CREATED_BY_ADMIN | MENU_MODIFIABLE_BY_ADMIN);
/**
- * Custom menus are those defined by the administrator.
+ * Custom menus are those defined by the administrator. Reserved for internal
+ * use; do not return from hook_menu() implementations.
*/
define('MENU_CUSTOM_MENU', MENU_IS_ROOT | MENU_VISIBLE_IN_TREE | MENU_CREATED_BY_ADMIN | MENU_MODIFIABLE_BY_ADMIN);
@@ -688,20 +744,15 @@ function _menu_build() {
function _menu_item_is_accessible($mid) {
$menu = menu_get_menu();
- if (array_key_exists('access', $menu['items'][$mid])) {
- return $menu['items'][$mid]['access'];
- }
-
- // Follow the path up to find the actual callback.
+ // Follow the path up to find the first "access" attribute.
$path = $menu['items'][$mid]['path'];
- while ($path && (!array_key_exists($path, $menu['path index']) || !array_key_exists('callback', $menu['items'][$menu['path index'][$path]]))) {
+ while ($path && (!array_key_exists($path, $menu['path index']) || !array_key_exists('access', $menu['items'][$menu['path index'][$path]]))) {
$path = substr($path, 0, strrpos($path, '/'));
}
if (empty($path)) {
return FALSE;
}
- $callback_mid = $menu['path index'][$path];
- return $menu['items'][$callback_mid]['access'];
+ return $menu['items'][$menu['path index'][$path]]['access'];
}
/**