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
- Install Event Platform Helper and place the Event Platform Header CTA block.
- Enable a render cache debug header (e.g. set
http.response.debug_cacheability_headers: trueinservices.yml). - 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. - 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
nonevariation.
This reduces the variation count from "one per unique URL" to "one per valid Event term, plus one."
Components:
- An
EventResolverservice (EventResolverInterface+ implementation) that maps an event slug/path segment to its Eventtaxonomy_term, with per-request static caching and a persistent slug→tid map taggedtaxonomy_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
EventNameCacheContextservice (taggedcache.context, service idcache_context.event_name) that returnsevent:{tid}ornone, and exposestaxonomy_term_list:eventas cacheable metadata so adding/removing Event terms invalidates dependent entries. - Block changes: replace
url.pathwithevent_name. BecauseBlockViewBuilderestablishes the block's render-cache keys fromgetCacheContexts()beforebuild()runs in a#pre_rendercallback, a context bubbled up from thebuild()render array triggers a cache "redirect" (two backend reads per render). The context is therefore declared ingetCacheContexts()rather than in the render array returned bybuild(). 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, andEventNameCacheContextwith service definitions. - Update
EventPlatformHeaderCtaBlockto inject the resolver, declareevent_nameingetCacheContexts(), removeurl.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:eventinvalidation tag). - Decide whether block content also varies by a second path segment (e.g.
/schedulevs/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.
Issue fork event_platform_helper-3610368
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
Comment #4
mandclu commented