0

I have a view that shows the title of a single content type as an unformatted list. I have an argument for a nid-contextual filter that I pass to the view in

function modulename_views_pre_view($view, $display_id, array &$args) {
 ....
 $args[0] = $filter_value;
 }

The value for the contextual filter is a value the user can select and is set in \Drupal::service('user.private_tempstore'). Every time the user selects a different value from a select form element, the view should show different results. However, it caches the output and only if I clear all caches it shows the correct output. But if I format the view output as a table, then everything works totally fine and the new results are shown immediately.

The cache tags for this view are given as follows:

print_r($view->getCacheTags());
Array ( [0] => config:views.view.users_in_class [1] => node_list ) 

Do I have to specifically invalidate something here or am I missing something else ? I thought that the cache tag node_list would already be enough. And why are results being cached when having the format as an unformatted list?

0

1 Answer 1

1

The cache tag node_list only works for database changes in the node table, but this is not happening when the user selects a filter value.

This is from the point of the View a cache context. So if you don't find a way to configure the View to handle this correctly, you could assign a custom cache context for the filter value.

The whole picture, which the View can't know because you provide only the filter value to it, is a mix of tag and context. You would need a cache tag for the private tempstore and a context for the current user to get the caching right:

function modulename_views_pre_view($view, $display_id, array &$args) {
  ...
  $uid = \Drupal::currentUser()->id();
  $view->element['#cache']['tags'][] = 'users_in_class.' . $uid;
  $view->element['#cache']['contexts'][] = 'user';
}

and then invalidate the tag when changing the private tempstore of a user $uid:

Cache::invalidateTags(['users_in_class.' . $uid']);
2
  • Thanks, that makes sense. I got it working as you described it. Just so I fully understand this: when you add the new cache tag 'users_in_class' . $uid how does this specifically point to the $tempstore object in the $_SESSION. Does it invalidate the cache as soon as any of the values in the user's $_SESSION array changes ?
    – theuni
    May 15, 2017 at 19:01
  • no, this is a custom cache tag and you have to invalidate the tag at the same time when you modify the value in the private tempstore, see the last code example in the answer
    – 4uk4
    May 15, 2017 at 19:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.