0

I have been trying to create dynamic routes by using RouteSubscriberBase class.

I know we can create dynamic routes by using slug parameter in the URL. Similar to this method ( https://befused.com/drupal/dynamic-route ).

But I want is dynamic Routes not URLs.Similar to this method ( https://www.previousnext.com.au/blog/dynamic-routes-drupal-8-routesubscriber )

Here is the code I have written so far but I cant get whats missing in the code.

When I try to access http://example.com/custom-module/dynamic-routes/ it is available but when I try to access http://example.com/custom-module/dynamic-routes/tents I am getting Page not found Error.

I have Cleared cache before accessing the new URL.

DynamicRoutesAlter.php

<?php

namespace Drupal\custom_module\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

/**
 * DynamicRoutesAlter Class.
 */
class DynamicRoutesAlter extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  public function alterRoutes(RouteCollection $collection) {

   $products = ['cooking_gear' => 'Cooking Gear', 'tents' => 'Tents' , 'sleeping_bags' => 'Sleeping Bags','rope' => 'Rope', 'safety' => 'Safety','packs' => 'Packs'];


    foreach ($products as $key => $value) {

      $url = preg_replace('/_/', '-', $key);

      $route = new Route(
        // The url path to match.
        '/custom-module/dynamic-routes/' . $url,
        // The defaults (see the custom_module.dynamic_routes for structure)
        [
          '_title' => $value,
          '_controller' => '\Drupal\custom_module\Controller\DynamicRoutesController::productType',
          'type' => $key, //Not sure what type does ? Is it required? I have seen it as the syntax in the book Mastering Drupal 8 By Chaz Chumley, William Hurley
        ],
        // The requirements.
        [
          '_permission' => 'create ' . $value,
        ]
      );

      // Add our route to the collection with a unique key.
      $collection->add('custom_module.dynamic_routes'. $key, $route);

    }
  }

}

custom_module.services.yml

services:
  custom_module.dynamic_routes:
    class: Drupal\custom_module\Routing\DynamicRoutesAlter
    tags:
      - { name: event_subscriber }    

custom_module.routing.yml

custom_module.dynamic_routes:
  path: '/custom-module/dynamic-routes'
  defaults:
    _title: 'Dynamic Routes'
    _controller: '\Drupal\custom_module\Controller\DynamicRoutesController::productType'
  requirements:
    _permission: 'access content'      

DynamicRoutesController.php

  /**
   * {@inheritdoc}
   */
  public function productType() {

    $build['results'] = [
      '#markup' => $this->t('Controller to get Products List.'),
    ];

    return $build;
  }  
1

DynamicRoutesAlter.php

Problem #1 - preg_replace() without pattern

$url = preg_replace('_', '-', $key);

The $url will be always NULL, because you are using preg_replace() without regexp, use instead str_replace() or write appropriate regexp pattern: '/_/'.

Solution #1

$url = preg_replace('/_/', '-', $key);

Solution #2

$url = str_replace('_', '-', $key);

Problem #2 - wrong variable mixing

$collection->add('custom_module.dynamic_routes'.{$key}, $route);

You are wrong with mixing variable and string. You want to concatenate it with the curly syntax. This is also incorrect.

Solution #1

$collection->add("custom_module.dynamic_routes.{$key}", $route);

Solution #2

$collection->add('custom_module.dynamic_routes' . $key, $route);

After you fix those problems, your code will work.

I'm also not sure about 'type' => $key,, why is that here? There is nothing about type route param.

P.s. as you mentioned itself, better use slugs.

UPD - all files

Check your files for mistakes.

custom_module.info.yml

name: Custom module
type: module
description: For https://drupal.stackexchange.com/questions/281728
package: Custom
core: 8.x

custom_module.routing.yml

custom_module.dynamic_routes:
  path: '/custom-module/dynamic-routes'
  defaults:
    _title: 'Dynamic Routes'
    _controller: '\Drupal\custom_module\Controller\DynamicRoutesController::productType'
  requirements:
    _permission: 'access content'

custom_module.services.yml

services:
  custom_module.dynamic_routes:
    class: Drupal\custom_module\Routing\DynamicRoutesAlter
    tags:
      - { name: event_subscriber }

src/Controller/DynamicRoutesController.php

<?php

namespace Drupal\custom_module\Controller;

use Drupal\Core\Controller\ControllerBase;

/**
 * Returns responses for Custom module routes.
 */
class DynamicRoutesController extends ControllerBase {

  /**
   * Builds response for dynamic routes.
   */
  public function productType() {

    $build['results'] = [
      '#markup' => $this->t('Controller to get Products List.'),
    ];

    return $build;
  }

}

src/Routing/DynamicRoutesAlter.php

<?php

namespace Drupal\custom_module\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

/**
 * DynamicRoutesAlter Class.
 */
class DynamicRoutesAlter extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  public function alterRoutes(RouteCollection $collection) {

    $products = ['cooking_gear' => 'Cooking Gear', 'tents' => 'Tents' , 'sleeping_bags' => 'Sleeping Bags','rope' => 'Rope', 'safety' => 'Safety','packs' => 'Packs'];


    foreach ($products as $key => $value) {

      $url = preg_replace('/_/', '-', $key);

      $route = new Route(
      // The url path to match.
        '/custom-module/dynamic-routes/' . $url,
        // The defaults (see the custom_module.dynamic_routes for structure)
        [
          '_title' => $value,
          '_controller' => '\Drupal\custom_module\Controller\DynamicRoutesController::productType',
          'type' => $key,
        ],
        // The requirements.
        [
          '_permission' => 'create ' . $value,
        ]
      );

      // Add our route to the collection with a unique key.
      $collection->add('custom_module.dynamic_routes' . $key, $route);

    }
  }

}

Dynamic route

  • Thanks for the detailed answer , but I need dynamic route Ids, so I can create dynamic menu items and tabs. So I need to proceed in this way. Those things you mentioned in the answer were my typos and I have corrected them. But I still cant get it working. – miststudent2011 May 29 at 12:46
  • In the code, you provide there is no more place to mistake. I recreate your module and works as you expect it. Do you place files in the correct folders? Wait a min I think how to share code for you. – Niklan May 29 at 13:36
  • Check out the updated answer. I provide all my files used for testing. – Niklan May 29 at 13:43
  • Thank you for taking your time and helping me. I did a silly mistake, In services.yml file I had used custom_module.dynamic_routes earlier for other service after renaming it all worked well. – miststudent2011 May 29 at 13:50

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.