hook_link_alter doesn't support passing any cache metadata

Created on 20 September 2019, almost 5 years ago
Updated 2 January 2024, 6 months ago

Problem/Motivation

The hook_link_alter allows developers to alter properties of a link before it's generated by LinkGenerator service. This is great, but it provides no way to pass along cache metadata, limiting its usefulness. This means that any alterations made to links must not vary based on anything other than what's already passed into the alter hook.

From some google searches, this seems to be a common issue in the community:

My specific use case is that I want to add a data attribute to the link depending on if the user has access to the page being linked to. I cannot do this without passing along cache contexts for the user permissions and roles.

Proposed resolution

  • Just before link_alter hook is invoked, set a cache key in $variables with an new instantiated CacheableMetadata() object.
  • Implementations of link_alter hook are able to add metadata to $variables['cache'] object.
  • Add $variables['cache'] instance as cacheable dependency to generated link.

Remaining tasks

None.

User interface changes

None.

API changes

Third-party code is able to add cacheable metadata to a link by enriching the $variables['cache'] instance, in a hook_link_alter() implementation.

Data model changes

None.

Release notes snippet

In order to add cacheable metadata to a link, third-party modules should implement hook_link_alter() and add cache tags, cache contexts or alter cache max age to $variables['cache'] instance.

✨ Feature request
Status

Needs work

Version

11.0 πŸ”₯

Component
BaseΒ  β†’

Last updated about 4 hours ago

Created by

πŸ‡ΊπŸ‡ΈUnited States bkosborne New Jersey, USA

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.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request β†’ as a guide.

    Appears there was 1 open thread. @alexpott could that be closed?

  • πŸ‡­πŸ‡ΊHungary mxr576 Hungary

    This means that any alterations made to links must not vary based on anything other than what's already passed into the alter hook.

    ...and maybe this should be a valid limitation of the scope of the hook that shall not be bypassed. For every other use case, use a different approach and not this hook.

    I had this issue open for months for sharing my 2 cents after I realized that some devs were using this hook to conditionally replace URLs of links generated by Drupal... like (conditionally) replacing the built-in login/log-out link in the menu with one that points to SSO. The issues were the same, cachebility information related to the new/altered link or the condition based on a link replaced/modified by our code could not be bubbled up.

    The proper solution was in our case for this particular problem instead of using this hook, we defined a custom menu link and leveraged hook_menu_links_discovered_alter() to replace the original one. This approach supports cacheability bubble-up, even from access results (when the destination internal url is not available for the current user.) This also caused performance gain because a menu link was only calculated two times (for authenticated and anonymous) in contradiction with the hook_link_alter() that ran on all page requests (IIRC).

    So I tend to believe that instead of enhancing the capabilities of this hook rather the hook's documentation should be improved and be more explicit about that, as this is a front-end related alter hook, it should be only used for small "cosmetical" changes and for everything else a different approach should be used. (Like changing links at the source instead of trying to alter them close to the end of the rendering process.)

Production build 0.69.0 2024