How to programmatically render a view with contextual filters?

Programmatically rendering a view with contextual filters is not something you need to do every day, but it's good to know that you can do it very easily. And you can do it in two different ways.

The buildRenderable method

The first option you have is to get a view using the Views class and then call the buildRenderable() method. Let's add a form element that is printing a view:

use Drupal\views\Views;
$view = Views::getView('user_list');

// ... some form
$form['user_list'] = $view->buildRenderable('block_1', [$user_id]);

In this example, we are rendering the view called User list (machine name is user_list). The first param in the buildRenderable method is the display ID and the second param is an array of arguments passed along to the view (in other words that's our contextual filter).

If you pass an invalid display ID the method will return a NULL value, and if everything is okay, you'll get a renderable array with #type that is equal to view.

The view render element

The second option is to use the view render element provided by the core. Let's use the same view as in the first example:

$form['user_list'] = [
  '#type' => 'view',
  '#name' => 'user_list',
  '#arguments' => [$user_id],
];

This is a much more elegant solution in my opinion. Real-world example usage of this render element can be found in Drupal Commerce that uses it to render the Commerce order item table view.

You can pass multiple values for contextual filters in the form of 1+2+3 (for OR) or 1,2,3 (for AND).

'#arguments' => ['1+2'],

In this case, we are passing ids 1 and 2 to the User list view. Just make sure that your contextual filter is configured to allow multiple values.

Contextual filters - Drupal 8 and 9
Contextual filters - Drupal 8 and 9

You can find this option in the More section of the contextual filter.