i want to match in a route a 'random' URL with a random sub path, fox example:

  • /example/1/a/b/c
  • /example/c3/s
  • ...

i implement this route in my .routing.yml file

  path: '/example/{path}'
    _controller: '\Drupal\modulo\Controller\Controller::check'
    _permission: 'TRUE'
    path: '.+'

I write it following Symfony2 standard but it doesn't works, seems Drupal override requirements in path.

Take look to system.routing.yml

  path: '/system/files/{filepath}'
    _controller: 'Drupal\system\FileDownloadController::download'
    # Permissive regex to allow slashes in filepath see
    # http://symfony.com/doc/current/cookbook/routing/slash_in_parameter.html
    filepath: .+
    _access: 'TRUE'

why this doesn't work for me?

Any suggestion?

  • Have a look at \Drupal\image\PathProcessor\PathProcessorImageStyles and image.services.yml and image.routing.yml
    – user21641
    Commented Jan 10, 2017 at 11:24
  • your example has _permission: 'TRUE' whereas it should be _access: 'TRUE'. if that is not a typo, it will explain why your route doesn't work. _permission takes an actual permission string
    – zerolab
    Commented Jan 10, 2017 at 11:51

3 Answers 3


The reason that the route in system.routing.yml works is that it gets help by an inbound path processor service, which stores the filepath to a query parameter in the request:



namespace Drupal\system\PathProcessor;

use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
use Symfony\Component\HttpFoundation\Request;

 * Defines a path processor to rewrite file URLs.
 * As the route system does not allow arbitrary amount of parameters convert
 * the file path to a query parameter on the request.
class PathProcessorFiles implements InboundPathProcessorInterface {

   * {@inheritdoc}
  public function processInbound($path, Request $request) {
    if (strpos($path, '/system/files/') === 0 && !$request->query->has('file')) {
      $file_path = preg_replace('|^\/system\/files\/|', '', $path);
      $request->query->set('file', $file_path);
      return '/system/files';
    return $path;


This service is registered in system.services.yml:



      class: Drupal\system\PathProcessor\PathProcessorFiles
        - { name: path_processor_inbound, priority: 200 }

And the controller gets the file path from the query parameter added by the processor:


  public function download(Request $request, $scheme = 'private') {
    $target = $request->query->get('file');

You can implement the same approach for your route to match everything after /example/.


The accepted answer may be appropriate for the intended use case of the OP, however, the title of this question is "Routing match everything".

As this is the closest question I've found from searching the interwebs, I'll just share my discovery here on how to accomplish this for SPAs where all paths that start with "/app" need to be redirected to a single route.

In ./my_module/my_module.routing.yml:

  path: '/app'
    _controller: '\Drupal\my_module\Controller\App::content'
    _access: 'TRUE' # Access is handled by app.

In ./my_module/my_module.services.yml:

    class: Drupal\my_module\EventSubscriber\RequestSubscriber
    arguments: ['@router.route_provider', '@controller_resolver', '@http_kernel.controller.argument_resolver']
      - { name: event_subscriber }

In ./my_module/src/EventSubscriber/RequestSubscriber.php:


namespace Drupal\my_module\EventSubscriber;

use Drupal\Core\Controller\ControllerResolverInterface;
use Drupal\Core\Routing\RouteProviderInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

 * Class RequestSubscriber.
class RequestSubscriber implements EventSubscriberInterface  {

   * The Argument Resolver service.
   * @var \Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface
  protected $argumentResolver;

   * The Controller Resolver service.
   * @var \Drupal\Core\Controller\ControllerResolverInterface
  protected $controllerResolver;

   * The Route Provider service.
   * @var \Drupal\Core\Routing\RouteProviderInterface
  protected $routeProvider;

   * RequestSubscriber constructor.
   * @param \Drupal\Core\Routing\RouteProviderInterface $routeProvider
   * @param \Drupal\Core\Controller\ControllerResolverInterface $controllerResolver
   * @param \Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface $argumentResolver
  public function __construct(RouteProviderInterface $routeProvider, ControllerResolverInterface $controllerResolver, ArgumentResolverInterface $argumentResolver) {
    $this->routeProvider = $routeProvider;
    $this->controllerResolver = $controllerResolver;
    $this->argumentResolver = $argumentResolver;

   * The request event handler.
   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
   *   The event.
  public function checkAppRequest(GetResponseEvent $event) {
    $request = $event->getRequest();
    $path = $request->getPathInfo();

    // Redirect all requests that start with "/app" requests to a single
    // route. Note: this is necessary because core doesn't have any other
    // way to really handle "wildcard/catch all" routes.
    if (strpos($path, '/app') === 0
      // Ignore CSS/JS (if it reaches here, it means the file doesn't exist).
      && !in_array(substr($path, -3), ['.css', '.js'])
      && !in_array(substr($path, -4), ['.map'])
    ) {
      $route = $this->routeProvider->getRouteByName('my_module.app');
      $definition = $route->getDefault('_controller');
      $controller = $this->controllerResolver->getControllerFromDefinition($definition, $path);
      $arguments = $this->argumentResolver->getArguments($request, $controller);
      $response = \call_user_func_array($controller, $arguments);
      if ($response instanceof Response) {
        // Set the response, necessary so the kernel knows it got something
        // which will also prevent any other event handler from running.

   * {@inheritdoc}
  public static function getSubscribedEvents() {
    // Check for /app requests.
    $events[KernelEvents::REQUEST][] = ['checkAppRequest', 1000];
    return $events;

  • Since Drupal 9 (drupal.org/project/drupal/issues/3094398), GetResponseEvent has been replaced by RequestEvent. Simply changing the class name in checkAppRequest will fix issues with newer versions.
    – david8
    Commented Mar 14 at 7:27

The Drupal 8 example modules has a few examples of this functionality.

For example in the page_example module you'll see a page_example.routing.yml file with the following

   path: 'examples/page-example/arguments/{first}/{second}'
       _controller: '\Drupal\page_example\Controller\PageExampleController::arguments'
       _permission: 'access arguments page'

And in the controller you have the arguments function that is called:

public function arguments($first, $second) {
    // Make sure you don't trust the URL to be safe! Always check for exploits.
    if (!is_numeric($first) || !is_numeric($second)) {
       // We will just show a standard "access denied" page in this case.
       throw new AccessDeniedHttpException();

    $list[] = $this->t("First number was @number.", array('@number' => $first));
    $list[] = $this->t("Second number was @number.", array('@number' => $second));
    $list[] = $this->t('The total was @number.', array('@number' => $first + $second));

    $render_array['page_example_arguments'] = array(
       // The theme function to apply to the #items.
       '#theme' => 'item_list',
       // The list itself.
       '#items' => $list,
       '#title' => $this->t('Argument Information'),

     return $render_array;
  • 2
    this is not a response, i know how routing work but i have to match everythings the / character too. Commented Jan 10, 2017 at 11:31
  • Oké, it's not 100% clear what you want to achieve here then. I thought you had to troubles with the routing and then reading out the parameters to do something with them. Commented Jan 10, 2017 at 11:33
  • 1
    If you want to alter an existing route you may want to check this page: drupal.org/docs/8/api/routing-system/… Commented Jan 10, 2017 at 11:34

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.