Both Drupal and Symfony have a router which defines paths, controllers, default arguments, and validity requirements. It is simple to achieve a very basic representation of Drupal's menu_router table as a Symfony route collection. In the DrupalLoader class, each Drupal route (such as node/%/edit) is rewritten to use Symfony's route patterns (becomes node/{p0}/edit).

All of the data attached to the route objects in the loader can be retrieved from the request object when that route is matched. My custom Drupal route loader only registers these routes and flags them as Drupal routes.

Drupal has two representations of routes: a generic one that can be loaded from the menu_router table and one retrieved from menu_get_item() that is specific for the user and session. The latter is more complete, but it's also going to be different from user to user. Symfony wants to cache its routes, so I have to use the generic route.

Supporting optional URL parameters

Drupal supports optional trailing arguments on its URLs, while Symfony is more strict.

For example, in Drupal, taxonomy/autocomplete is a valid path for a route, but it requires two additional arguments: a field name and a string of text representing the user's input into the aforementioned field. For Symfony to pick up those arguments from the request path, they need to be defined explicitly.

To achieve this, I created a custom Symfony route compiler which overrides the regular expression that Symfony uses to match Drupal routes. Since I am not using the router to actually parse the page arguments from the path (that is still left to Drupal's menu_get_item() function), I can force Symfony to match if the first part of the path matches.

See the RouteCompiler in the Drupal Bundle.

This probably could be better, but it might not need to be.

This was the trickiest gap to bridge between Drupal and Symfony, and there is at least one significant shortcoming.

Symfony supports attaching route collections to a specific prefix, which means that it should be possible to map all Drupal routes to a path within Symfony (e.g. using a route collection prefix of /drupal so that /node/1 is accessed at /drupal/node/1). Unfortunately, when you do this, Drupal's menu_get_item() can no longer match the request path with a route.

To fix this would require educating the DrupalLoader class with the route prefix. However, this probably goes against the grain of the Symfony framework's design.