There is already a menu defined in core module. I need to alter the page callback of this menu in another module. Similar to using hook_menu_alter()
in Drupal 7, but since there is no hook_menu_alter()
in Drupal 8, how do I define another page callback?
-
Did you read drupal.stackexchange.com/questions/187585/… ?– mppJul 3, 2016 at 11:52
-
In Drupal 8 there aren't anymore page callbacks.– apaderno ♦Jul 3, 2016 at 12:12
-
@kiamlaluno I need to change the permission callback for a menu. I have created a custom permission. Now i need to call this custom permission for this menu. My custom permission is properly visible on permission list page.– nehaJul 4, 2016 at 8:36
2 Answers
In Drupal 8 You don't have hook_menu and the are changed to "Routers" now.
Drupal 8 has a new menu system, there is no hook_menu and no hook_menu_alter anymore.
If you want to alter an existing route, it is a little bit more complicated in comparison to Drupal 7.
In your module you have to create a class file at YOURMODULE/src/Routing/CLASSNAME.php that extends RouteSubscriberBase:
/**
* @file
* Contains \Drupal\YOURMODULE\Routing\RouteSubscriber.
*/
namespace Drupal\YOURMODULE\Routing;
use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;
/**
* Listens to the dynamic route events.
*/
class RouteSubscriber extends RouteSubscriberBase {
/**
* {@inheritdoc}
*/
protected function alterRoutes(RouteCollection $collection) {
// Get the route you want to alter
$route = $collection->get('system.admin_content');
// alter the route...
}
}
You can take the RouteSubsciber class of the node module as an example.
To let your RouteSubscriber be recognized you also have to create a YOURMODULE.services.yml file in the root of your modules directory:
services:
node.route_subscriber:
class: Drupal\YOURMODULE\Routing\RouteSubscriber
tags:
- { name: event_subscriber }
To get a better insight to the new menu system I would recommend the following articles:
D7 to D8 upgrade tutorial: Convert hook_menu() and hook_menu_alter() to Drupal 8 APIs What Happened to Hook_Menu in Drupal 8? Edit: the menu system has a different structure now, which has nothing to do with D7's menu system, so there is no such thing as a menu type anymore.
Thanks to the above answers for pointing me in the right direction, but I think the key part is missing - How to change the page callback! Though D8 might not use the phrase page callback
we still have page callbacks - the controller::method
which responds to a request.
Step 1: Create a route subscriber
Follow the official Drupal 8 documentation on and create a Drupal 8 Route Subscriber - Paritoshik Paul's answer might help you in this step. Make sure you implement the alterRoutes()
method and that it is working (you might have to clear cache).
At the end of this step, if you do a die();
in the alterRoutes()
method, the code execution should stop at the die when rebuilding cache.
Step 2: Change the page callback
Once the RouteSubscriber::alterRoutes()
is confirmed to be working, you can change the page callback to your custom controller::method like this:
protected function alterRoutes(RouteCollection $collection) {
// Change the page callback for Taxonomy Term pages.
$route = $collection->get('entity.taxonomy_term.canonical');
$route->setDefault('_controller', '\\Drupal\\YOURMODULE\\Controller\\YourController::yourMethod');
}
In the above example, I change the callback for a taxonomy term page. Of course, we will have to ensure that YourController::yourMethod
actually exist. Refer official docs for how to create a basic controller.
Rebuild your cache and your page callback is changed!