Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Reported by Berdir:
/**
* Implements hook_entity_build_defaults_alter().
*/
function comment_entity_build_defaults_alter(array &$build, EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
// Get the corresponding display settings.
$display = EntityViewDisplay::collectRenderDisplay($entity, $view_mode);
// Add the comment page number to the cache key if render caching is enabled.
if (isset($build['#cache']) && isset($build['#cache']['keys']) && \Drupal::request()->query->has('page')) {
foreach ($entity->getFieldDefinitions() as $field_name => $definition) {
if ($definition->getType() === 'comment' && ($display_options = $display->getComponent($field_name))) {
$pager_id = $display_options['settings']['pager_id'];
$page = pager_find_page($pager_id);
$build['#cache']['keys'][] = $field_name . '-pager-' . $page;
}
}
}
return $build;
}
Comment | File | Size | Author |
---|---|---|---|
#22 | pager_cache_context-2428563-22.patch | 6.81 KB | Wim Leers |
Comments
Comment #1
Wim LeersBlocked on #2428563: Introduce parameter-dependent cache contexts.
Comment #2
Wim Leers#2428563: Introduce parameter-dependent cache contexts landed, now unblocked. Taking a first stab at this.
Comment #3
andypostSuppose better to apply
CommentPagerCacheContext
from comment field formater somehowis it possible if:
1) bubbling is not supported yet #2429257: Bubble cache contexts
2) comment formatter could be changed to contrib provided one
Comment #4
Wim LeersBriefly discussed this with catch yesterday. We saw 2 general approaches:
QueryStringCacheContext
: hashes the entire query string, and hence varies cache items using this context whenever a single detail about it is different.QueryParameterCacheContext
: varies cache items using a query parameter that a render array varies by.I'm not a fan of approach 1 because it would cause even the typical Google Analytics query parameters that appear when used from feed readers to cause caches not to be used, even though Drupal never ever reacts to either of those query parameters.
I implemented approach 2.
But then I noticed that this doesn't actually work very well for pagers, because Drupal's pagers (see
pager.inc
) actually don't use separate query parameters… but the same query parameter:page
, with the values for the different pagers encoded as an integer at a different location in a list of comma-separated page numbers (seepager_find_page()
).So I added a
PagerCacheContext
as well.In doing so, I found a small bug in #2428563: Introduce parameter-dependent cache contexts: the
CacheContexts
service, when converting cache context tokens to keys, if given the same cache parameter-dependent cache context multiple times, with different parameters, it only keeps one of them. Very simple fix (with expanded test coverage) included.Comment #5
Wim LeersAlso note this bit in the patch:
i.e. once we have bubbling, we can automatically make sure that anything using a pager automatically sets the appropriate cache context, and hence it automatically bubbles up everywhere!
Comment #6
Wim LeersFiled #2433591: Views using pagers should specify a cache context as a sister issue.
Comment #8
Wim LeersFiled an issue for that @todo cited in #5: #2433599: Ensure every (non-views) pager automatically associates a matching cache context.
Comment #9
Wim LeersFixed test failures.
Comment #10
Wim LeersOops. Chrome--
Comment #11
Fabianx CreditAttribution: Fabianx commentedThis is off-topic, but this .missing is interested.
We should just still execute fields that have #access => FALSE so that we always have the same cache contexts and no variations :-p.
The PR looks good, gonna hopefully review later for RTBC.
Comment #12
andypostI still think that this context should apply within formatter, also this is a way to solve #11 about #access
Comment #13
Fabianx CreditAttribution: Fabianx commentedDo we need to sanitize this in any way?
Overall like a query parameter cache context, but perhaps we should have a cache_context.request.query
instead?
So we could also have cache_context.request.cookie, which is another important use case?
Comment #14
Wim LeersPerhaps it's better to just omit
UrlQueryParameterCacheContext
, because it's not actually necessary to fix this issue? We can easily add it later.Comment #15
Fabianx CreditAttribution: Fabianx commentedSounds good, lets get this in first.
Comment #16
Wim LeersAlright, done.
Comment #17
Fabianx CreditAttribution: Fabianx commentedThis is technically an API change (though it was just introduced, so disruption is zero.
--
RTBC!
Comment #18
BerdirI still need to read all the issues around that, but why is removing that only possible there?
Shouldn't the bubble issue allow us to remove it already, assuming the pager actually adds this context as well?
Comment #19
Wim LeersIndeed, plus: this is an API function that is very, very, very rarely used. Only code that provides a UI that shows cache contexts is affected. In core, that's only
BlockBase
. In D8 contrib, likely nothing yet.Because pager uses
#theme => pager
, not#type => pager
. Preprocess functions cannot add cache tags. But#type => pager
means we can have a#pre_render
callback which adds it.Correct. But bubbling isn't in yet.
Comment #20
BerdirOk, I'm not sure to which issue that @todo should actually point to. It currently points to #2429617: Make D8 2x as fast: Dynamic Page Cache: context-dependent page caching (for *all* users!), but I think it should point to #2433599: Ensure every (non-views) pager automatically associates a matching cache context?
That would make sense to me, but pointing it to the first seems strange, because I'd expect need to solve those kind of issues before being able to use that kind of caching?
Comment #21
Fabianx CreditAttribution: Fabianx commentedYes, lets put the @todo to this issue: #2433599: Ensure every (non-views) pager automatically associates a matching cache context
CNW, sadly on that ...
Comment #22
Wim Leers#20: LOL! Oops!
Fixed.
Comment #23
catchCommitted/pushed to 8.0.x, thanks!