3

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 ?

  • 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. – 4k4 Mar 1 '18 at 17:10
  • 1
    @4k4 Can u explain with an example of pointing the default route (entity.node.edit_form) to custom controller ? – Crazyrubixfan Mar 1 '18 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. – 4k4 Mar 1 '18 at 19:52
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.

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

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);
        }           
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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