3

We have got a node which contains a 3rd party clientside JS app. The node acts as a container page or base path, and the JS app acts like a SPA inside the node container. To allow deep-links into the JS app, I have created a inbound path procossor that resolves all sub-paths of that node back to the node's system path:

class MyInboundPathProcessor implements InboundPathProcessorInterface {
  public function processInbound($path, Request $request) {
    // assume '/container-node' is the URL alias of my special container node
    if (!str_starts_with($path, '/container-node/')) {
      return $path;
    }
    // the following line is required due "Redirect" contrib module
    $request->attributes->set('_disable_route_normalizer', TRUE);
    // assume '123' is the node ID of my special container node
    return '/node/123';
  }
}

Using the above code, the real node link
mydomain.com/container-node
and "fake" deep links like
mydomain.com/container-node/foo
mydomain.com/container-node/foo/bar
mydomain.com/container-node/foo/baz
will be served by my special Drupal node and the URL is preserved in the browser address bar, so the JS app can act on it.

The problem is, it only works on the very first visit of each deep link.

Even though my code is called on every sub-sequent request (breakpoint fires in debugger), only on the the very first visit the sub-path (like /container-node/foo/bar) is preserved. Every sub-sequent visit is rewritten to the "real" URL alias /container-node/, and the JS app can't do its thing. After clearing cache it works again for the first visit.

How can I tell the InboundPathProcessor not to discard the sub-paths on sub sequent requests?

1 Answer 1

3

In a path processor you can't set data in the request object, the request object is not preserved. The only exception are query parameters which are extracted from the request object when the rewritten path is cached.

Set the request attribute in an event subscriber with a priority higher than 30:

  public function onKernelRequest(RequestEvent $event) {
    $request = $event->getRequest();
    $path = $request->getPathInfo();
    if (!str_starts_with($path, '/container-node/')) {
      return;
    }
    $request->attributes->set('_disable_route_normalizer', TRUE);
  }

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