I am trying to find the correct views hook to alter/add a contextual filter to a views block that's being rendered in a template. (Using drupal_view and the twig tweaks module).

The view is setup to accept a contextual filter that is provided in the URL by default. It works great on that page, however it's been requested that the view also display on a sub-page of this main page, in where the URL does not contain the contextual filter. Therefore, I am trying to find a views hook that I can reliably attach the contextual filter to and have it work every page load.

I have tried using hook_views_pre_view(), however this appears to only work once between cache clears, as if I clear cache it works, then as soon as I refresh the page it stops working again until another cache clear.

Is there a way I can do this from a hook? The way the child-page is structured, I can't easily get it from the template to pass it into drupal_view() as an argument.

The current code I am using is:

function item_types_views_pre_view(&$view, &$display_id, &$args) {
    if ($view->id() == 'existing_copies') {

        $parameters = \Drupal::routeMatch()->getParameters();
        $imcid = \Drupal::routeMatch()->getParameter('imcid');

        $entity = \Drupal::entityTypeManager()->getStorage('item_type')->load($imcid);

        if ($entity->bundle() == 'book_copy') {
            $main_record = $entity->field_book_main_record->getString();
        elseif ($entity->bundle() == 'book_master_copy') {
            $main_record = $entity->field_master_copy_book_mr->getString();

        $args = [$main_record];

Which like I said, works great immediately after a cache clear, but no longer works after the page is refreshed.

  • There's another approach too: you can add a custom default argument plugin (the things which power Content ID from URL, Raw value from URL, etc). See api.drupal.org/api/drupal/… and api.drupal.org/api/drupal/… for examples
    – Clive
    Mar 18, 2021 at 21:35
  • Hmm, can I make this only available on a specific view? Id hate to implement thials globally and somebody not familiar with views using it and breaking stuff on existing views.
    – Ex0r
    Mar 18, 2021 at 21:38
  • Well there goes my argument about reusability anyway ;) There probably will be a way to make it work for just one view, but that would probably involve another hook and the reason for using a plugin would kind of been lost. For your current code would you not just need to add $view->setArguments($args);?
    – Clive
    Mar 18, 2021 at 21:45
  • Ignore that, stupid question, I read the post properly. Sounds like you just need to add a cache context somewhere
    – Clive
    Mar 18, 2021 at 21:47
  • I don't have anywhere to attach that. The pre_view hook appears to be cached, so it doesn't update changes, at least if it's supposed to its not.
    – Ex0r
    Mar 18, 2021 at 21:47

1 Answer 1


I was able to use achieved what I wanted by using hook_views_pre_build() as below

hook_views_pre_build(ViewExecutable $view) {
  $args[0] = '1234';


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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