programmatically add filter to view using hook_views_pre_view() in Drupal 9

Created on 25 November 2021, almost 3 years ago
Updated 14 March 2023, over 1 year ago

Problem/Motivation

I wish to programmatically add a filter to a view using hook_views_pre_view() in Drupal 9.

Steps to reproduce

In previous Drupal versions, it was done like this (using $view->add_item):

      $view->add_item(
        $view->current_display,
        'filter',
        'node',
        'nid',
        array(
          'operator' => '=',
          'value' => '59',
          'group' => 1
        )
      );

In Drupal 9, the above code now generates this error:

Call to undefined method Drupal\views\ViewExecutable::add_item()

Proposed resolution

Can someone provide an example of how to programmatically add a filter to a view using hook_views_pre_view() in Drupal 9?

πŸ’¬ Support request
Status

Closed: works as designed

Version

9.2

Component
ViewsΒ  β†’

Last updated about 11 hours ago

Created by

πŸ‡ΊπŸ‡ΈUnited States SomebodySysop

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡©πŸ‡°Denmark Steven Snedker

    Well, SomebodySysop. I'm sorry that noone gave you a good answer in time and that the documentation for Drupal 9 is so awful. I try do document my own modules well, at least.

    Anyway, here how I solved programmatically adding a filter to a view in Drupal 9.5. It may solve a problem for you in the future or bring some help to all the other lost developers looking for useful documentation and working examples.


    I made a view β†’ (the format is Full Calender Display, but that doesn't matter) showing the jobs assigned to a specific car on a specific day.

    My wish was to programmatically load and show a view block 10 times - once for each car on that day.

    So in the views UI I added a filter for field_car_term set to 11.

    Then I made this code:

    function home() {
        $terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree('cars'); // Get all terms from vocabulary
        foreach ($terms as $term) { // Loop through them
          $view = Views::getView('job_calendar');
          $view->setDisplay('block_1');
    
          unset($view->display_handler->options['filters']['field_car_term_target_id']['value']['11']); // Unset the hardcoded value
          $view->display_handler->options['filters']['field_car_term_target_id']['value'][$term->tid] = $term->tid; // Set the dynamic value
    
          $ret[$term->tid]['cal'] = $view->buildRenderable(); // Add the render array of the view to an array
        }
    
        return $ret;     // Return render array
    }
    

    The filter has to exist in the view. Otherwise the above code will not work.

    The filter should be hardcoded to something that you later unset. Here it's term id 11.

    Setting the filter, you have a surprising amount of freedom

    $view->display_handler->options['filters']['field_car_term_target_id']['value'][$term->tid] = $term->tid;
    $view->display_handler->options['filters']['field_car_term_target_id']['value'][3] = $term->tid;
    $view->display_handler->options['filters']['field_car_term_target_id']['value']['drupalisawfullydocmented'] = $term->tid;
    

    all work well.

    The saner looking

    $view->display_handler->options['filters']['field_car_term_target_id']['value'] = $term->tid;
    

    does not work whatsoever. So avoid that.

    I'd be thrilled if there was a better place to read about how to programatically add filters to a view. A place with more and better examples. But alas. Looking for hours I did not find such a place.

Production build 0.71.5 2024