The new matcher/router system went in (yay!) but with only a stopgap API for defining routes, hook_route_info(). That is the one ugly part of that system, as it's the only part not testable and not object-oriented. Some have suggested that defining Route objects inline is less DX-friendly than route arrays, although that point has been debated. We Can Do Better(tm).
There are a couple of possible solutions on the table, with assorted pros and cons:
1) CMI files. Symfony uses YAML files to define routes, which is quite successful and nicely self documenting. This also allows routes to be treated as configuration, not code, which is more accurate and more flexible. The format of the file would be immediately familiar to any Symfony, ezPublish, or PHPBB developer. There would be no need for an alter hook, just config CRUD. It also means that, once we have a generator, we could allow the paths of routes to be changed very easily in config without obscenely complex gymnastics (aka, why Panels/Page Manager for Drupal 6 took 8 months to come out). See comment #6 for a patch. The downside of this option is dynamic routes (eg, those that right now would be defined with a foreach() loop in hook_menu()). Those would be very difficult to implement. The argument could be made that those are a code smell, though. See #57 for a discussion of dynamic routes.
2) Leave it as an info hook. I (Crell) personally don't like this approach as it's introducing a legacy Drupalism into an otherwise all new-fangled system. That's going to be very jarring. It would also be an info hook returning an object of objects, not an array of doom, which would be inconsistent with our other info hooks. However, we do know it handles dynamic routes reasonably well.
3) CMI files with "Decorators". Neclimdul suggested this to me earlier today. The idea would be to allow routes to declare some callback (which would have to be a class or service, not a function) that would take the CMI file and spawn multiple routes out of it, based on some rule. This is essentially the same as decorators in the Plugin system. Pros here are that it's similar to some other system, and still lets us use YAML files 95% of the time. Downside, it's an untested Drupalism so we don't know how viable or ugly it would be in practice.
4) A special method on bundles. Effectively the same idea as an info hook, but a specially named method on a module's bundle class rather than a specially named function. Pros: Still code definition, should be straightforward to do dynamic routes (although possibly that would break injection), lazy-loads cleanly. Cons: Still code definition. Drupalism. Not sure how we'd do the equivalent of an alter hook.
5) An event for collecting routes onto a RouteCollection. Basically the same idea as a hook, but done new-fancy style (and therefore easier to inject/test). Downsides: Still in code, unclear how we'd do an alter, and arguably a bastardization of events (Drupalism). Also, I don't know how this would support the very nice "rebuild one module at a time to avoid blowing up memory" capability that the new matcher dumper has.
It's also been noted that the above are not all mutually exclusive; that is, there are probably ways to offer both code-based and YAML-based route definitions, if we're willing to accept the potential for confusion (and two different ways to go about editing them).
Decide what to do, then do it.
User interface changes
None at this point.
That's what we're trying to decide! :-)
Original report by [username]
I want to change hook_route_info() before we ship. For now, though, I'm not sure what the better alternative is so I've provided minimal documentation and marked it as just a stopgap for now.
It feels, well, off to have this one legacy definition hook in a system that is otherwise 100% Symfony-based OO
From nielsvm's comment on the change notice:
I'm certainly not saying that adding Route objects to a RouteCollection object is a hard thing or that our developing audience can't adapt to that, what I do mean is that code readability drastically drops in a key area of every Drupal module that would declare paths. What about wrapping around this lower level API by providing a hook that still looks similar to hook_menu and does allow to pass everything down the chain so that Symfony's routing API is fully leveraged and that module organisation remains clean and readable?
This is an area of Drupal that is simultaneously low-level (in the sense of integrating into Symfony's basic HTTP handling) and that many contrib module developers will need to deal with. We need to come up with something that makes sense architecturally and that Drupal's broad community of developers finds appealing to work with.
PASSED: [[SimpleTest]]: [MySQL] 48,113 pass(es).
[ View ]
PASSED: [[SimpleTest]]: [MySQL] 48,152 pass(es).
[ View ]