SlideShare a Scribd company logo
Drupal  Menu System By: Anirudha Prabhune Mail: [email_address]
Menu  System The Menu System has three primary responsibilities:  callback mapping   access control menu customization
Callback  Mapping When a request is made to Drupal by a browser, a URL is given to Drupal.  From this information, Drupal must figure out what code to run and how to handle the request. This is commonly known as  dispatching .
Mapping URLs  to Functions The general approach taken is as follows: Drupal asks all its modules to provide an array of  menu items —that is, a path and some information about that path. One of the pieces of information   a module must provide is a  callback . A  callback   in this context is simply the name of a PHP function that will be run when the browser requests a certain path.
Mapping URLs  to Functions Drupal goes through the following steps when a request comes in: 1. If the path is an alias to a real path, Drupal finds the real path and uses it instead.  2. Executes hook_menu() so that all modules can provide their callbacks. 3. Creates a map from paths (such as node/add) to callbacks (PHP functions such as node_page()). Cont..
Mapping URLs  to Functions 4. If menu.module is enabled, applies any changes or additions the site administrator has made to the map (such as overriding a menu item’s title). 5. Uses the map to look up the callback function for the requested URL, and calls it. If any callback arguments were specified, Drupal sends those along. 6. Returns the function’s result or an “Access denied” message if the user may not access the URL, or a 404 response if the path did not map to any function.
Process  Representation Menu   Array
A Sample   Module A module named new_menu.module that places a menu item in Drupal’s navigation menu is coded here. The Drupal path new_menu is mapped to the PHP function new_menu_hello().
A Demo  Menu function new_menu_menu($may_cache)  { $items = array(); if ($may_cache)   { $items[] = array( 'title' => t('My Menu'), 'path' => 'admin/settings/new_menu', 'callback' => 'new_menu_hello', 'callback arguments' => array(t('Menu!'), t('Nested Menu!')), 'access' => TRUE );
A Demo  Menu $items[] = array( 'title' => t('Done'), 'path' => 'admin/settings/new_menu/MyMenu', 'callback' => 'new_menu_hello', 'callback arguments' => array(t('Menu!'), t('Nested Menu!')), 'access' => TRUE ); } return $items; }
A Demo  Menu function new_menu_hello($first,$second,$name = NULL) { drupal_set_message(t('First comes %first', array('%first' => $first))); drupal_set_message(t('Second comes %second', array('%second' =>  $second))); if (!isset($name))  { $name = t('good looking!'); } return t('Hello @name!', array('@name' => $name)); }
Visual  Demo Nested Menu
Access   Control Previously we’ve simply set the access key of the menu item to  TRUE , meaning that anyone can access our menu. Usually menu access is controlled by defining permissions inside the module using hook_perm() and testing those permissions using user_access().  Let’s define a permission called  Door Opened!! ;  if a user does not have a role that has been granted this permission ,  the user will receive an “Access denied” message if he or she tries to access that particular menu.
Access   Control function new_menu_perm()  { return array('Door Opened!!'); } Replace  ‘ access’ => TRUE   WITH ‘ access’ => user_access(‘Door Opened!!’) In this way, the menu system serves as a gatekeeper determining which paths may be accessed and which will be denied based on the user’s role. Note: Do not forget to apply the Access Control from Administer Panel  Manually .
Access   Control When determining access to a menu item, Drupal will look at the access key of the menu item’s full path and use that. If the access key is TRUE, access will be granted  even if the parent’s access   key is  FALSE. If there is no access key assigned to a menu item, its parent’s access key will be used. If the parent does not have an access key, Drupal will recurse all the way up the tree until it finds an access key (the access key for the root of the tree is TRUE). Local tasks are common nested menu items.
Access   Control Access Settings and Resulting User Access Table Parent  Child  User Access FALSE  FALSE Denied TRUE  FALSE  Denied FALSE  TRUE  Allowed TRUE  TRUE  Allowed FALSE  Undefined  Denied TRUE  Undefined  Allowed
Kinds of  Menu When you are adding a menu item in the menu hook, one of the possible keys you can use is the  type.  If you do not define a type, the default type MENU_NORMAL_ITEM will be used. Drupal will treat your menu item differently according to the type you assign. Each menu item type is composed of a series of flags, or attributes. The Following Table lists the menu item type FLAGS :
Kinds of  Menu Binary  Hexadecimal    Decimal     Constant 000000000001   0x0001  1  MENU_IS_ROOT 000000000010    0x0002    2   MENU_VISIBLE_IN_TREE 000000000100   0x0004  4  MENU_VISIBLE_IN_BREADCRUMB 000000001000    0x0008 8  MENU_VISIBLE_IF_HAS_CHILDREN 000000010000    0x0010  16  MENU_MODIFIABLE_BY_ADMIN 000000100000   0x0020  32  MENU_MODIFIED_BY_ADMIN 000001000000    0x0040  64  MENU_CREATED_BY_ADMIN 000010000000    0x0080  128  MENU_IS_LOCAL_TASK 000100000000    0x0100  256  MENU_EXPANDED 001000000000   0x0200  512  MENU_LINKS_TO_PARENT
Kinds of  Menu For example, the constant MENU_NORMAL_ITEM has the flags MENU_VISIBLE_IN_TREE, MENU_VISIBLE_IN_BREADCRUMB, and MENU_MODIFIABLE_BY_ADMIN, as shown in Table . See how the separate flags can be expressed in a single constant?   Binary    Constant 000000000010  MENU_VISIBLE_IN_TREE 000000000100  MENU_VISIBLE_IN_BREADCRUMB 000000010000  MENU_MODIFIABLE_BY_ADMIN 000000010110  MENU_NORMAL_ITEM
Common   Tasks Assigning Callbacks Without Adding a Link to the Menu Often we want to map a URL to a function without creating a visible menu item. We can do this by assigning the MENU_CALLBACK type to your menu item, as in this example from  node.module : $items[] = array( ‘ path' => 'rss.xml', 'title' => t('RSS feed'), 'callback' => 'node_feed', 'access' => user_access('access content'), 'type' => MENU_CALLBACK );
Common   Tasks Programmatically Modifying Existing Menus: When we implement the menu hook in our module, there’s nothing to prevent us from adding entries to other modules’ paths, or even from overriding them. Typically this is done using the handy web interface provided by menu.module, which ships as part of Drupal, but we have reasons to do this programmatically.
Common   Tasks Wrapping Calls to Menu Items: For example,  devel.module  has a menu item that clears Drupal’s cache tables. Let’s wrap that function so our function gets called first. First, we override devel.module’s menu item by specifying one of our own with the same path inside our menu hook
Common   Tasks function mymodule_menu($may_cache) { $items = array(); if (!$may_cache && module_exist('devel')) { // Make sure devel.module is enabled. $items[] = array( 'path' => 'devel/cache/clear', // Same path that devel.module uses. 'title' => t('Wrap cache clear'), 'callback' => 'mymodule_clear_cache', 'type' => MENU_CALLBACK, 'access' => user_access('access devel information') // Same as devel.module. ); } } function mymodule_clear_cache() { drupal_set_message('We got called first!'); // Wrap the devel function normally called. devel_cache_clear(); }
Common   Tasks Now when we go to the menu  ../?q=devel/cache/clear , our module will be called first, and it will call the function that would have originally been called. Here’s the result: We got called first! Cache cleared. Note :  This is a useful technique for when you want to modify Drupal’s default behavior without modifying any underlying code.
Common   Tasks Deleting Existing Menus: Using the same approach presented in the section “Wrapping Calls to Menu Items,” we can delete existing menu items by overriding their paths. Suppose you want to remove the “create content” menu item and the ability to add content, for some reason: $items[] = array( 'path' => 'node/add', 'title' => t('This should not show up'), 'callback' => 'drupal_not_found', ‘ type' => MENU_CALLBACK );
Common   Tasks Adding to Existing Menus: We can add to existing menus by inserting our menu item with a clever path. For example, suppose we want to add a tab to the user administration interface to delete all users. By examining the menu hook in user.module, we determine that admin/user is the path we want to use as our base path. Here’s the menu item we return from eradicateusers.module:
Common   Tasks $items[] = array( 'path' => 'admin/user/eradicate', 'title' => t('Eradicate all users'), 'callback' => 'mymodule_eradicate_users', 'type' => MENU_LOCAL_TASK, 'access' => user_access('eradicate users') ); This adds the menu item as a local task. If we want the menu item to show up in the administrative menu block, we have to make the type a MENU_NORMAL_ITEM instead of a MENU_LOCAL_TASK. And if we want it to show up in both places, use the following: 'type' => MENU_NORMAL_ITEM | MENU_LOCAL_TASK and the menu item will have the attributes of both menu item types.
THANK   YOU

More Related Content

PDF
How to Create A Magento Adminhtml Controller in Magento Extension
PDF
How to create a magento controller in magento extension
PDF
How to Develop a Basic Magento Extension Tutorial
PDF
The Flexibility of Drupal
PDF
The Flexibility of Drupal 8
PPTX
Java me lab2-slides (gui programming)
PPTX
Cordova training : Day 6 - UI development using Framework7
PDF
Mason - A Template system for us Perl programmers
How to Create A Magento Adminhtml Controller in Magento Extension
How to create a magento controller in magento extension
How to Develop a Basic Magento Extension Tutorial
The Flexibility of Drupal
The Flexibility of Drupal 8
Java me lab2-slides (gui programming)
Cordova training : Day 6 - UI development using Framework7
Mason - A Template system for us Perl programmers

What's hot (14)

PDF
Php tour 2018 un autre regard sur la validation (1)
PDF
13th Sep, Drupal 7 advanced training by TCS
PPTX
Drupal 7 — Circle theme
PDF
Curso Symfony - Clase 3
PPTX
Magento 2.0: Prepare yourself for a new way of module development
PDF
Empowering users: modifying the admin experience
KEY
Rails Routing and URL design
PDF
Jinja2 Templates - San Francisco Flask Meetup
PDF
Ruby on Rails : RESTful 和 Ajax
ODT
Eclipse Tricks
PPTX
Editing the Visual Editor (WordPress)
PDF
Whmcs addon module docs
PDF
There's a Filter For That
Php tour 2018 un autre regard sur la validation (1)
13th Sep, Drupal 7 advanced training by TCS
Drupal 7 — Circle theme
Curso Symfony - Clase 3
Magento 2.0: Prepare yourself for a new way of module development
Empowering users: modifying the admin experience
Rails Routing and URL design
Jinja2 Templates - San Francisco Flask Meetup
Ruby on Rails : RESTful 和 Ajax
Eclipse Tricks
Editing the Visual Editor (WordPress)
Whmcs addon module docs
There's a Filter For That
Ad

Similar to DRUPAL Menu System (20)

PPT
WordPress as a Content Management System
DOCX
Android menus in android-chapter15
PDF
WordCamp Geneva Presentation - Customising WordPress' Admin Panel - 19 Nov. 2016
PDF
Using and reusing CakePHP plugins
PPT
Smarter Interfaces with jQuery (and Drupal)
PPT
Menu bars and menus
PDF
Model View Controller
PPTX
Theming Drupal Menus
PPTX
Fixing Magento Core for Better Performance - Ivan Chepurnyi
PPTX
Routing in Drupal 8
PPT
Creating Custom Drupal Modules
PPTX
WordPress plugin #3
PPTX
DJango admin interface
PDF
Alfredo-PUMEX
PDF
Alfredo-PUMEX
PDF
Alfredo-PUMEX
PDF
Alfredo-PUMEX
PPTX
WordPress plugin #2
PPTX
Routing in Drupal 8
PDF
Views Unlimited: Unleashing the Power of Drupal's Views Module
WordPress as a Content Management System
Android menus in android-chapter15
WordCamp Geneva Presentation - Customising WordPress' Admin Panel - 19 Nov. 2016
Using and reusing CakePHP plugins
Smarter Interfaces with jQuery (and Drupal)
Menu bars and menus
Model View Controller
Theming Drupal Menus
Fixing Magento Core for Better Performance - Ivan Chepurnyi
Routing in Drupal 8
Creating Custom Drupal Modules
WordPress plugin #3
DJango admin interface
Alfredo-PUMEX
Alfredo-PUMEX
Alfredo-PUMEX
Alfredo-PUMEX
WordPress plugin #2
Routing in Drupal 8
Views Unlimited: Unleashing the Power of Drupal's Views Module
Ad

More from Amit Kumar Singh (20)

PPTX
Improving Core Web Vitals for WordPress
PPTX
Getting started with WordPress Development
PPTX
Alternate Development Techniques on WordPress
PPTX
Building Minimal Viable Product (MVP) with WordPress
PPTX
Rapid Prototyping With WordPress
PPTX
Stop Coding; Start Assembling Your Websites
PPTX
WordPress as Rapid Prototyping Tool
PPTX
WordPress Use Cases
PPTX
Leveraging your business with WordPress
PPT
Maharashtra at a glance
PDF
Custom Post Type and Taxonomies in WordPress 3.x
PPTX
WPoid : You Blog, We Take Care Of The Rest
ODP
Joomla Day India 2009 Business Logic With The Mvc
PPT
Joomla Request To Response
PPT
Introduction to web services and how to in php
PPT
Getting Started With Php Frameworks @BCP5
PPT
Php Security
PPT
Open Social Phpcamp
PPT
Overview Of Drupal
PPT
PHP tips by a MYSQL DBA
Improving Core Web Vitals for WordPress
Getting started with WordPress Development
Alternate Development Techniques on WordPress
Building Minimal Viable Product (MVP) with WordPress
Rapid Prototyping With WordPress
Stop Coding; Start Assembling Your Websites
WordPress as Rapid Prototyping Tool
WordPress Use Cases
Leveraging your business with WordPress
Maharashtra at a glance
Custom Post Type and Taxonomies in WordPress 3.x
WPoid : You Blog, We Take Care Of The Rest
Joomla Day India 2009 Business Logic With The Mvc
Joomla Request To Response
Introduction to web services and how to in php
Getting Started With Php Frameworks @BCP5
Php Security
Open Social Phpcamp
Overview Of Drupal
PHP tips by a MYSQL DBA

Recently uploaded (20)

PPT
Teaching material agriculture food technology
PDF
Machine learning based COVID-19 study performance prediction
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPTX
Programs and apps: productivity, graphics, security and other tools
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Encapsulation theory and applications.pdf
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PPTX
sap open course for s4hana steps from ECC to s4
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PPTX
Spectroscopy.pptx food analysis technology
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
Big Data Technologies - Introduction.pptx
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Network Security Unit 5.pdf for BCA BBA.
Teaching material agriculture food technology
Machine learning based COVID-19 study performance prediction
Building Integrated photovoltaic BIPV_UPV.pdf
Programs and apps: productivity, graphics, security and other tools
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Spectral efficient network and resource selection model in 5G networks
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Encapsulation theory and applications.pdf
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
sap open course for s4hana steps from ECC to s4
Reach Out and Touch Someone: Haptics and Empathic Computing
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Spectroscopy.pptx food analysis technology
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Big Data Technologies - Introduction.pptx
Mobile App Security Testing_ A Comprehensive Guide.pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Diabetes mellitus diagnosis method based random forest with bat algorithm
Network Security Unit 5.pdf for BCA BBA.

DRUPAL Menu System

  • 1. Drupal Menu System By: Anirudha Prabhune Mail: [email_address]
  • 2. Menu System The Menu System has three primary responsibilities: callback mapping access control menu customization
  • 3. Callback Mapping When a request is made to Drupal by a browser, a URL is given to Drupal. From this information, Drupal must figure out what code to run and how to handle the request. This is commonly known as dispatching .
  • 4. Mapping URLs to Functions The general approach taken is as follows: Drupal asks all its modules to provide an array of menu items —that is, a path and some information about that path. One of the pieces of information a module must provide is a callback . A callback in this context is simply the name of a PHP function that will be run when the browser requests a certain path.
  • 5. Mapping URLs to Functions Drupal goes through the following steps when a request comes in: 1. If the path is an alias to a real path, Drupal finds the real path and uses it instead. 2. Executes hook_menu() so that all modules can provide their callbacks. 3. Creates a map from paths (such as node/add) to callbacks (PHP functions such as node_page()). Cont..
  • 6. Mapping URLs to Functions 4. If menu.module is enabled, applies any changes or additions the site administrator has made to the map (such as overriding a menu item’s title). 5. Uses the map to look up the callback function for the requested URL, and calls it. If any callback arguments were specified, Drupal sends those along. 6. Returns the function’s result or an “Access denied” message if the user may not access the URL, or a 404 response if the path did not map to any function.
  • 8. A Sample Module A module named new_menu.module that places a menu item in Drupal’s navigation menu is coded here. The Drupal path new_menu is mapped to the PHP function new_menu_hello().
  • 9. A Demo Menu function new_menu_menu($may_cache) { $items = array(); if ($may_cache) { $items[] = array( 'title' => t('My Menu'), 'path' => 'admin/settings/new_menu', 'callback' => 'new_menu_hello', 'callback arguments' => array(t('Menu!'), t('Nested Menu!')), 'access' => TRUE );
  • 10. A Demo Menu $items[] = array( 'title' => t('Done'), 'path' => 'admin/settings/new_menu/MyMenu', 'callback' => 'new_menu_hello', 'callback arguments' => array(t('Menu!'), t('Nested Menu!')), 'access' => TRUE ); } return $items; }
  • 11. A Demo Menu function new_menu_hello($first,$second,$name = NULL) { drupal_set_message(t('First comes %first', array('%first' => $first))); drupal_set_message(t('Second comes %second', array('%second' => $second))); if (!isset($name)) { $name = t('good looking!'); } return t('Hello @name!', array('@name' => $name)); }
  • 12. Visual Demo Nested Menu
  • 13. Access Control Previously we’ve simply set the access key of the menu item to TRUE , meaning that anyone can access our menu. Usually menu access is controlled by defining permissions inside the module using hook_perm() and testing those permissions using user_access(). Let’s define a permission called Door Opened!! ; if a user does not have a role that has been granted this permission , the user will receive an “Access denied” message if he or she tries to access that particular menu.
  • 14. Access Control function new_menu_perm() { return array('Door Opened!!'); } Replace ‘ access’ => TRUE WITH ‘ access’ => user_access(‘Door Opened!!’) In this way, the menu system serves as a gatekeeper determining which paths may be accessed and which will be denied based on the user’s role. Note: Do not forget to apply the Access Control from Administer Panel Manually .
  • 15. Access Control When determining access to a menu item, Drupal will look at the access key of the menu item’s full path and use that. If the access key is TRUE, access will be granted even if the parent’s access key is FALSE. If there is no access key assigned to a menu item, its parent’s access key will be used. If the parent does not have an access key, Drupal will recurse all the way up the tree until it finds an access key (the access key for the root of the tree is TRUE). Local tasks are common nested menu items.
  • 16. Access Control Access Settings and Resulting User Access Table Parent Child User Access FALSE FALSE Denied TRUE FALSE Denied FALSE TRUE Allowed TRUE TRUE Allowed FALSE Undefined Denied TRUE Undefined Allowed
  • 17. Kinds of Menu When you are adding a menu item in the menu hook, one of the possible keys you can use is the type. If you do not define a type, the default type MENU_NORMAL_ITEM will be used. Drupal will treat your menu item differently according to the type you assign. Each menu item type is composed of a series of flags, or attributes. The Following Table lists the menu item type FLAGS :
  • 18. Kinds of Menu Binary Hexadecimal Decimal Constant 000000000001 0x0001 1 MENU_IS_ROOT 000000000010 0x0002 2 MENU_VISIBLE_IN_TREE 000000000100 0x0004 4 MENU_VISIBLE_IN_BREADCRUMB 000000001000 0x0008 8 MENU_VISIBLE_IF_HAS_CHILDREN 000000010000 0x0010 16 MENU_MODIFIABLE_BY_ADMIN 000000100000 0x0020 32 MENU_MODIFIED_BY_ADMIN 000001000000 0x0040 64 MENU_CREATED_BY_ADMIN 000010000000 0x0080 128 MENU_IS_LOCAL_TASK 000100000000 0x0100 256 MENU_EXPANDED 001000000000 0x0200 512 MENU_LINKS_TO_PARENT
  • 19. Kinds of Menu For example, the constant MENU_NORMAL_ITEM has the flags MENU_VISIBLE_IN_TREE, MENU_VISIBLE_IN_BREADCRUMB, and MENU_MODIFIABLE_BY_ADMIN, as shown in Table . See how the separate flags can be expressed in a single constant? Binary Constant 000000000010 MENU_VISIBLE_IN_TREE 000000000100 MENU_VISIBLE_IN_BREADCRUMB 000000010000 MENU_MODIFIABLE_BY_ADMIN 000000010110 MENU_NORMAL_ITEM
  • 20. Common Tasks Assigning Callbacks Without Adding a Link to the Menu Often we want to map a URL to a function without creating a visible menu item. We can do this by assigning the MENU_CALLBACK type to your menu item, as in this example from node.module : $items[] = array( ‘ path' => 'rss.xml', 'title' => t('RSS feed'), 'callback' => 'node_feed', 'access' => user_access('access content'), 'type' => MENU_CALLBACK );
  • 21. Common Tasks Programmatically Modifying Existing Menus: When we implement the menu hook in our module, there’s nothing to prevent us from adding entries to other modules’ paths, or even from overriding them. Typically this is done using the handy web interface provided by menu.module, which ships as part of Drupal, but we have reasons to do this programmatically.
  • 22. Common Tasks Wrapping Calls to Menu Items: For example, devel.module has a menu item that clears Drupal’s cache tables. Let’s wrap that function so our function gets called first. First, we override devel.module’s menu item by specifying one of our own with the same path inside our menu hook
  • 23. Common Tasks function mymodule_menu($may_cache) { $items = array(); if (!$may_cache && module_exist('devel')) { // Make sure devel.module is enabled. $items[] = array( 'path' => 'devel/cache/clear', // Same path that devel.module uses. 'title' => t('Wrap cache clear'), 'callback' => 'mymodule_clear_cache', 'type' => MENU_CALLBACK, 'access' => user_access('access devel information') // Same as devel.module. ); } } function mymodule_clear_cache() { drupal_set_message('We got called first!'); // Wrap the devel function normally called. devel_cache_clear(); }
  • 24. Common Tasks Now when we go to the menu ../?q=devel/cache/clear , our module will be called first, and it will call the function that would have originally been called. Here’s the result: We got called first! Cache cleared. Note : This is a useful technique for when you want to modify Drupal’s default behavior without modifying any underlying code.
  • 25. Common Tasks Deleting Existing Menus: Using the same approach presented in the section “Wrapping Calls to Menu Items,” we can delete existing menu items by overriding their paths. Suppose you want to remove the “create content” menu item and the ability to add content, for some reason: $items[] = array( 'path' => 'node/add', 'title' => t('This should not show up'), 'callback' => 'drupal_not_found', ‘ type' => MENU_CALLBACK );
  • 26. Common Tasks Adding to Existing Menus: We can add to existing menus by inserting our menu item with a clever path. For example, suppose we want to add a tab to the user administration interface to delete all users. By examining the menu hook in user.module, we determine that admin/user is the path we want to use as our base path. Here’s the menu item we return from eradicateusers.module:
  • 27. Common Tasks $items[] = array( 'path' => 'admin/user/eradicate', 'title' => t('Eradicate all users'), 'callback' => 'mymodule_eradicate_users', 'type' => MENU_LOCAL_TASK, 'access' => user_access('eradicate users') ); This adds the menu item as a local task. If we want the menu item to show up in the administrative menu block, we have to make the type a MENU_NORMAL_ITEM instead of a MENU_LOCAL_TASK. And if we want it to show up in both places, use the following: 'type' => MENU_NORMAL_ITEM | MENU_LOCAL_TASK and the menu item will have the attributes of both menu item types.
  • 28. THANK YOU