Pass value into a view using block input

We had a similar requirement on a previous project with Layout Builder: We used a block_content entity. We are using the Block field module to create a field_view containing a reference to the views block.

Every other field on the custom block content entity basically was a faked Views UI: Every filter that we wanted to expose to the editors, was created as field on the block_content (mostly taxonomy term references), and then mapped to views exposed filters in a special field formatter widget for the block field.

It is a bit of hack, but our editors were quite happy with it. The field formatter below is tailored to our specfic needs, but might help to get some ideas.

<?php

namespace Drupalwt_dgmPluginFieldFieldFormatter;

use DrupalComponentPluginExceptionContextException;
use DrupalCoreCacheCacheableMetadata;
use DrupalCoreFieldFieldItemListInterface;
use Drupalblock_fieldPluginFieldFieldFormatterBlockFieldFormatter;
use DrupalCorePluginContextAwarePluginInterface;
use DrupalviewsElementView;
use DrupalviewsPluginBlockViewsBlock;

/**
 * Plugin implementation of the 'block_field' formatter.
 *
 * @FieldFormatter(
 *   id = "autolist_blockfield",
 *   label = @Translation("Block field with filters from Auto-List block"),
 *   field_types = {
 *     "block_field"
 *   }
 * )
 */
class AutoListBlockField extends BlockFieldFormatter {

  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    /** @var $parentEntity Drupalblock_contentEntityBlockContent */
    $parentEntity = $items->getEntity();
    if ($parentEntity->getEntityTypeId() != 'block_content' || $items->getFieldDefinition()->getName() != 'field_view') {
      return parent::viewElements($items, $langcode);
    }

    $elements = ();
    foreach ($items as $delta => $item) {
      /** @var Drupalblock_fieldBlockFieldItemInterface $item */
      $block = $item->getBlock();

      if (!($block instanceof ViewsBlock)) {
        continue;
      }

      // copy & paste parent::viewElements()
      if ($block instanceof ContextAwarePluginInterface) {
        try {
          $contexts = Drupal::service('context.repository')->getRuntimeContexts($block->getContextMapping());
          Drupal::service('context.handler')->applyContextMapping($block, $contexts);
        }
        catch (ContextException $e) {
          continue;
        }
      }
      if (!$block || !$block->access(Drupal::currentUser())) {
        continue;
      }

      // apply my custom filters and sort options to the views block
      $view = $block->getViewExecutable();
      $display = $view->current_display;

      $args = ($parentEntity->id());
      $view->setArguments(($parentEntity->id()));

      $filters = ();

      /* ### alter views filter ### */
      if ($parentEntity->hasField('field_contentypes')) {
        $filters('type') = array_column($parentEntity->get('field_contentypes')->getValue(), 'value');
      }
      foreach ($parentEntity->getFields() as $fieldName => $field) {
        if ($field->getFieldDefinition()->getType() == 'entity_reference' && $field->getFieldDefinition()->getSetting('target_type') == 'taxonomy_term') {
          if (!$field->isEmpty()) {
            $filters($fieldName . '_target_id') = array_column($field->getValue(), 'target_id');
          }
        }
      }
      /* ### alter views sort ### */
      $sort = $parentEntity->get('field_sort')->value;
      $filters('sort_by') = $sort;
      $view->setExposedInput($filters);

      $view->setItemsPerPage($parentEntity->get('field_quantity')->value);

      $view->display_handler->setOption('title', $parentEntity->get('field_title')->value);

      //@see DrupalviewsPluginBlockViewsBlock::build()
      $output = $view->buildRenderable($display, $args, FALSE);
      $output = View::preRenderViewElement($output);

      $elements($delta) = $output;

      CacheableMetadata::createFromRenderArray($elements($delta))
        ->addCacheableDependency($parentEntity)
        ->applyTo($elements($delta));
    }
    return $elements;
  }

}

PS: Ajax has to be enabled on the views block, otherwise setting $filter did not work correctly for us.