Automatically generate URL alias for new/updated external entities

Created on 10 October 2018, about 6 years ago
Updated 7 February 2023, almost 2 years ago

In #2538684: Add support for path auto we added basic support for the pathauto module. This fix made it possible to bulk generate/update URL aliases for external entities.

New or updated external entities do not receive an alias automatically however, since pathauto relies on hook_entity_insert(), hook_entity_update() and hook_entity_delete(). These hooks are not triggered for external entities (since there is currently no generic way to identify changes in external data).

A first approach: subscribing to Kernel events

A KernelEvents::RESPONSE subscriber checks on every request to "//" if an URL alias can/must be generated. This would only happen for responses on requests to the canonical route of the external entity. Thereafter we can perform a 302 redirect (as the https://www.drupal.org/project/redirect module does) even before the response is sent. This means only the first visitor has a less performant experience (URL alias needs to be calculated & redirected to) - similar to how the first visitor Varnish/Page Cache primes.

For when external entities are updated, we can introduce a KernelEvents::TERMINATE subscriber which is execute after the response has been sent to the end-user (see index.php: first there's a $response->send() and only then there's a $kernel->terminate()). The end-user won't notice any difference at all. We could use the same technique for the the above (KernelEvents::RESPONSE), but that would mean that the first user stays on the unaliased URL. The KernelEvents::TERMINATE subscriber would execute a $pathautoGenerator->updateEntityAlias($external_entity, 'update'), which generates an URL alias based on the values in the external entity. Most of the time the URL alias will stay unchanged. The next visitor then gets the correct URL alias. This is an "eventual consistency" approach (https://en.wikipedia.org/wiki/Eventual_consistency).

This would mean that every time the HTML response for a specific external entity is generated (thus after the TTL/max-age is reached & the page is requested again), the URL alias will be re-calculated, and if changed, be used in the future.

A second approach: hook_entity_storage_load()

Another approach would be generating URL aliases in hook_entity_storage_load(). The first approach spreads the performance cost across a lot of requests, this would have a performance penalty when loading a non-cached external entity. That performance cost can be relative however, see comment_entity_storage_load() which performs a lot of logic as well.

Regardless of the approach, this should be configurable on the external entity type. There's always the possibility one can listen to CREATE/UPDATE/DELETE events from external source. In that case you could trigger the URL generation when those events occur, making it far more efficient.

Credits to Wim Leers for investigating this.

Feature request
Status

Fixed

Version

2.0

Component

Code

Created by

🇧🇪Belgium rp7

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024