- Drupal's url() function converts a system path (like 'node/1') into a relative or absolute URL. In doing this, it has logic to apply path aliasing, allow modules to alter the outbound URL (e.g., add a language prefix), prefix an explicit script path for web servers that don't support clean URLs, and generate an absolute URL based on various global variables and settings.php settings.
- Drupal's HttpKernel, which is a copy of Symfony FrameworkBundle's HttpKernel, also needs to be able to generate URLs to various Drupal routes, for purposes of HTTP-based partial caching such as ESI, SSI, or hInclude. It currently does this by invoking UrlGeneratorInterface::generate() on the router service. This interface is based on generating URLs from a route name, not from a Drupal system path. In , some of the details of this will change, but what will still remain is the need for some way of exposing Drupal's URL generation logic to the Symfony code that deals with HTTP caching strategies.
- New-router routes are defined not by path, but by machine name. That allows, among other things, the actual path to be decoupled from references to it, allowing for a more flexible and self-documenting way to generate links. However, prior to this issue such links do not go through the full set of link manipulations that url() does.
- Currently, Drupal's UrlGenerator::generate() method used by HttpKernel and the url() function used by the rest of Drupal diverge widely. For example, the former does not invoke the hook_url_outbound_alter() hooks that the latter does. And they follow completely different code paths for generating an absolute URL.
- Move the contents of url() into a new method of UrlGenerator:
generateFromPath(). That way, its logic is available via the router service used by HttpKernel, and all other code that works with dependency injected services.
- In the process, refactor the dependencies on global variables and settings into injected ones.
- Convert hook_url_outbound_alter() implementations into services tagged
path_processor_outbound. This complements a similar hook_url_inbound_alter() to
path_processor_inboundconversion that has already been done in HEAD. This avoids a low-level component such as UrlGenerator having a dependency on Drupal's module system, while still enabling modules to affect the URL generation process.
- Move the application of path aliases from being inlined in generate() and url() to being done by the path_processor_alias service that's already in HEAD. This puts outbound aliasing code in the same place as inbound de-aliasing code.
- With generate() and generateFromPath() being two methods in the same class, make all of their common functionality handled by a common helper method.
- Leave url() as a (non-deprecated) wrapper function for now. Punt the question of whether to deprecate it to a follow up.
- Fix generate() to invoke path processors prior to generating an absolute URL.
User interface changes
See "Proposed resolution" above.
Original report by Crell
As a follow-up from, we now have a generator (which works on routes) and url() (which works on arbitrary paths). Only the latter uses hook_url_outbound_alter(), but both hard-code and special-case path aliasing.
This needs to all fold down to one clean system. Quoting from the linked issue:
That includes merging the caching of path lookups, generator included, and unifying hook_url_outbound_alter() into an event that we can cache *after* lookup, not before. That in turn means that path aliases become just another hook_url_outbound_alter()-equivalent listener, which is fine because we're caching it. That would also parallel the inbound-alter logic, which has already been converted to the request listener.
That does lose us the ability to do uncached runtime outbound url manipulation, but I think that's a fairly niche case and an acceptable trade off to a unified outbound URL cache.
This will involve moving url() into the generator, removing its external dependencies, and then unifying the caching logic from path aliasing into a generator-aliasing strategy.
PASSED: [[SimpleTest]]: [MySQL] 55,305 pass(es).
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1888424.url_generator.180.patch. Unable to apply patch. See the log in the details link for more information.
PASSED: [[SimpleTest]]: [MySQL] 55,755 pass(es).