6

I want to modify node edit of a specific content type node to a different route .

Eg : suppose i have a node edit page route as entity.node.edit_form (core feature) . And now i want to change this route to custom_module.edit_form when taking the node to edit .

I refered This which explains altering the existing route to a different route . It only says to route to a different url . It may not work in my case as node edit form will contain node id as parameter . Its not mentioning how routes can be placed in $route->setPath() though .

For eg: In custom_module/src/Routing/RouteSubscriber.php

/**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    // Change path '/user/login' to '/login'.
    if ($route = $collection->get('user.login')) {
      $route->setPath('/login');
    }
    // Always deny access to '/user/logout'.
    // Note that the second parameter of setRequirement() is a string.
    if ($route = $collection->get('user.logout')) {
      $route->setRequirement('_access', 'FALSE');
    }
  }

How can i do this ?

3
  • 1
    RouteSubscribers alter routes, not where they are used. This is defined in the entity type build, globally for all bundles. If you want to do this content type specific, one possible approach could be to point the route to a custom controller and put the logic there what entity form you want to return.
    – 4uk4
    Commented Mar 1, 2018 at 17:10
  • 1
    @4k4 Can u explain with an example of pointing the default route (entity.node.edit_form) to custom controller ?
    – KTM
    Commented Mar 1, 2018 at 19:36
  • 1
    I think you need $route->getDefaults() and $route->setDefaults() to get and set the defaults array, where you remove the _entity_form and add a _controller key. You might need to adjust other route settings.
    – 4uk4
    Commented Mar 1, 2018 at 19:52

2 Answers 2

3

Hi i done this as follows : in RouteSubscriber.php :

<?php

namespace Drupal\module_name\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) {
    // Change path '/node/edit' to custom controller action.
    if ($route = $collection->get('entity.node.edit_form')) {
        $route->setDefault('_controller', '\Drupal\module_name\Controller\MyController::alter_edit_route');
    }
  }
}    

and in MyController.php :

/**
 * Function to redirect the edit route to custom route
 */
public function alter_edit_route(){
    $node_id = \Drupal::routeMatch()->getRawParameter('node');
    //get the content type using node id 
    $entityObj  = entity_load('node',$node_id);
    $bundle = $entityObj->bundle();
    if($bundle=="custom_service_name"){
        //redirect to custom service list page
        $response = new RedirectResponse('/module_name/custom_service/'.$node_id);
        $response->send();
       return;
    }
    else return $this->redirect('entity.node.edit_form', ['node' => $node_id]);
}

NB:- A problem here is that its redirecting to the custom url for the specific content type . But when taking other content type nodes its hanging with the too many redirections.

Welcoming your insights on this . thanks .

UPDATE

Okay , here its how i resolved the problem . For the custom content type node its using the redirectResponse to redirect to custom page . For other content type nodes its creating the specific content type form and load the values to it for the specific node id . So in MyController.php

  /**
     * Function to redirect the edit route to custom route
     */
    public function alter_edit_route(){
        $node_id = \Drupal::routeMatch()->getRawParameter('node');
        //get the content type using node id 
        $entityObj  = entity_load('node',$node_id);
        $bundle = $entityObj->bundle();
        if($bundle=="custom_service_name"){
            //redirect to custom service list page
            $response = new RedirectResponse('/module_name/custom_service/'.$node_id);
            $response->send();
        }
        else {
            //programmatically load the node edit page with value
            $node = \Drupal::entityTypeManager()->getStorage('node')->load($node_id);
            $form = \Drupal::entityTypeManager()
              ->getFormObject('node', 'default')
              ->setEntity($node);
            return \Drupal::formBuilder()->getForm($form);
        }           
    }
1
  • Thank you for you for posting an answer. I found the same thing: Redirecting to the same route will result in an endless loop. So the only way is to return the built form or view or whatever it may be from the controller. Commented Dec 2, 2021 at 16:46
1

You need to change the _controller for the route, check this code:

<?php

namespace Drupal\drush_help\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) {
    // Change the controller for the help page.
    if ($route = $collection->get('help.page')) {
      $route->setDefault('_controller', '\Drupal\drush_help\Controller\HelpController::helpPage');
    }
  }

}

In this case the route is altered to replace the Drupal help page for a custom controller.

If you want to see this in action go to check the code of the Drush Help module.

Disclosure: I'm the maintainer of the module Drush Help.

2
  • How could I pass the node ID to the controller action ?
    – KTM
    Commented Mar 1, 2018 at 19:57
  • @RubberDuckIsKing yes, you can add all the params that you need with $route->setDefault() Commented Mar 1, 2018 at 20:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.