Problem/Motivation

EventPlatformHeaderCtaBlock renders content that varies based on the Event taxonomy term identified from the URL. To handle this, the block declares the url.path cache context, which is the standard best practice when content varies by URL.

However, url.path is far more granular than this block needs. Drupal stores one render-cache variation per unique full path, so every distinct URL the block appears on gets its own cached copy — including deep event paths, non-event pages, and invalid/junk paths. In practice the block's content only differs by the identified Event term, which is derived from a path shaped like /events/{event_name}.... All other paths could share a single variation.

The result is a large number of redundant, near-duplicate cache entries that waste storage and reduce cache efficiency, with no functional benefit.

Steps to reproduce

  1. Install Event Platform Helper and place the Event Platform Header CTA block.
  2. Enable a render cache debug header (e.g. set http.response.debug_cacheability_headers: true in services.yml).
  3. Visit several URLs where the block appears: multiple event pages (/events/event-a, /events/event-b), deep paths under one event (/events/event-a/schedule, /events/event-a/speakers), and several non-event pages.
  4. Observe that the block produces a separate render-cache entry for every unique path, even where the resolved Event term (and therefore the rendered CTA) is identical.

Proposed resolution

Introduce a custom cache context, event_name, that normalizes the request to a token rather than the raw path:

  • URLs resolving to the same Event term share one variation (token event:{tid}).
  • All non-event and invalid-event URLs collapse to a single shared none variation.

This reduces the variation count from "one per unique URL" to "one per valid Event term, plus one."

Components:

  • An EventResolver service (EventResolverInterface + implementation) that maps an event slug/path segment to its Event taxonomy_term, with per-request static caching and a persistent slug→tid map tagged taxonomy_term_list:event, so resolution is an in-memory lookup on a warm cache. This centralizes the term-resolution logic currently embedded in the block so both the rendered output and the cache token derive the event the same way.
  • An EventNameCacheContext service (tagged cache.context, service id cache_context.event_name) that returns event:{tid} or none, and exposes taxonomy_term_list:event as cacheable metadata so adding/removing Event terms invalidates dependent entries.
  • Block changes: replace url.path with event_name. Because BlockViewBuilder establishes the block's render-cache keys from getCacheContexts() before build() runs in a #pre_render callback, a context bubbled up from the build() render array triggers a cache "redirect" (two backend reads per render). The context is therefore declared in getCacheContexts() rather than in the render array returned by build(). The block should also bubble the resolved term's own cache tags (taxonomy_term:{tid}) so edits to an event's content invalidate the stored markup.

Because a cache context is evaluated on every request (including cache hits) to compute the cache key, getContext() is kept cheap via the resolver's static + persistent-map caching. Collapsing invalid slugs to none also prevents crawlers or malicious requests from inflating the variation count with garbage paths.

Remaining tasks

  • Confirm the Event vocabulary machine name and how the {event_name} path segment maps to a term (term name, dedicated slug field, or URL alias), and align the resolver's slug logic with the block's existing behavior.
  • Add EventResolverInterface, EventResolver, and EventNameCacheContext with service definitions.
  • Update EventPlatformHeaderCtaBlock to inject the resolver, declare event_name in getCacheContexts(), remove url.path, and bubble the resolved term's cache tags.
  • Add kernel test coverage (token collapse for non-event and invalid paths, stable token across deeper paths under one event, distinct tokens per event, and presence of the taxonomy_term_list:event invalidation tag).
  • Decide whether block content also varies by a second path segment (e.g. /schedule vs /speakers); if so, extend the token to include it.
  • Manually verify via cache debug headers that deep paths under one event reuse the same cached block.

User interface changes

None.

API changes

Additive only. Introduces a new event_platform_helper.event_resolver service (EventResolverInterface) and a new event_name cache context (cache_context.event_name). The block no longer declares the url.path cache context, replacing it with event_name; this is an internal cacheability change with no change to the block's rendered output.

Data model changes

None.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mandclu created an issue. See original summary.

  • mandclu committed 88b846a6 on 1.0.x
    feat: #3610368 Replace url.path cache context in...
mandclu’s picture

Status: Active » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.