Views arguments

Created on 22 December 2015, almost 9 years ago
Updated 19 March 2024, 9 months ago

When embedding a view, I can't see how to pass arguments through to a view to do a filter or contextual filter.

I'm not sure if this is
1) I lack experience with Panels embedded views etc. so can't see what would be obvious to someone else
2) there's a discoverability problem with the UI; or
3) something is broken.

I do see that when I embed a view and go to the formatter settings UI for that view, there is a section called "Arguments:". But it is empty and has no controls.

I'm interested in tasks like:
A) embed in a page a view that contains all articles having the taxonomy tag "fish"
B) embed in a page a view that contains all articles that reference the page from the "more info" entity reference field on the article

I'm happy to test more and give feedback, but I'm a bit stuck getting started on this one!

🐛 Bug report
Status

Active

Version

9.1

Component

User interface

Created by

🇬🇧United Kingdom jonathanshaw Stroud, UK

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.

  • 🇮🇹Italy apaderno Brescia, 🇮🇹
  • 🇮🇹Italy apaderno Brescia, 🇮🇹

    I think there is something to fix in the code handling the embedded view.

          $view = Views::getView($display_field['settings']['embed_view']);
          $view->setDisplay($display_settings['settings']['view_display'] ?? 'default');
    
          $view->setAjaxEnabled($display_settings['settings']['enable_ajax'] ?? 'default');
    
          // Set the view URL to the current page for the exposed filter form
          // redirection.
          $view->override_url = Url::fromRoute('<current>');
    
          // Build the view arguments.
          $args = [];
          if (!empty($display_settings['settings']['arguments'])) {
            $view_object = \Drupal::service('entity_type.manager')->getStorage('view')->load($display_field['settings']['embed_view']);
            $view_display = $view_object->getDisplay();
            foreach ($view_display['display_options']['arguments'] as $argument) {
              if (isset($display_settings['settings']['arguments'][$argument['id']])) {
                $arg_values = $this->getViewsArgumentsValues($entities, $display_field, $display_settings['settings']['arguments'][$argument['id']], $parent_entity, $view_mode, $language);
                if (!empty($arg_values)) {
                  $args[] = implode('+', $arg_values);
                }
              }
            }
          }
    

    The code loads twice the view, when it should be sufficient to load it via Views::getView().

    It also expects that $view_object->getDisplay() returns an array, while the documentation for that method says it return a \Drupal\views\Plugin\views\display\DisplayPluginBase instance.
    I cannot find any magic method that would allow to handle the value returned by $view_object->getDisplay() as an array.

  • 🇮🇹Italy apaderno Brescia, 🇮🇹

    Furthermore, $view->setAjaxEnabled() casts its argument to a Boolean value. Instead of passing $display_settings['settings']['enable_ajax'] ?? 'default', it would be probably better to pass $display_settings['settings']['enable_ajax'] ?? TRUE.

  • 🇮🇹Italy apaderno Brescia, 🇮🇹

    Looking at the following code, used by DisplayPluginBase, I think I know how to change the code.

      /**
       * The display information coming directly from the view entity.
       *
       * @see \Drupal\views\Entity\View::getDisplay()
       *
       * @todo \Drupal\views\Entity\View::duplicateDisplayAsType directly access it.
       *
       * @var array
       */
      public $display;
    
      // Omissis
    
      public function initDisplay(ViewExecutable $view, array &$display, array &$options = NULL) {
        $this->view = $view;
    
        // Load extenders as soon as possible.
        $display['display_options'] += [
          'display_extenders' => [],
        ];
        $this->extenders = [];
        if ($extenders = Views::getEnabledDisplayExtenders()) {
          $manager = Views::pluginManager('display_extender');
          $display_extender_options = $display['display_options']['display_extenders'];
          foreach ($extenders as $extender) {
    
            /** @var \Drupal\views\Plugin\views\display_extender\DisplayExtenderPluginBase $plugin */
            if ($plugin = $manager
              ->createInstance($extender)) {
              $extender_options = isset($display_extender_options[$plugin
                ->getPluginId()]) ? $display_extender_options[$plugin
                ->getPluginId()] : [];
              $plugin
                ->init($this->view, $this, $extender_options);
              $this->extenders[$extender] = $plugin;
            }
          }
        }
        $this
          ->setOptionDefaults($this->options, $this
          ->defineOptions());
        $this->display =& $display;
    
        // Track changes that the user should know about.
        $changed = FALSE;
        if (!isset($options) && isset($display['display_options'])) {
          $options = $display['display_options'];
        }
        if ($this
          ->isDefaultDisplay() && isset($options['defaults'])) {
          unset($options['defaults']);
        }
        $skip_cache = \Drupal::config('views.settings')
          ->get('skip_cache');
        if (!$skip_cache) {
          $cid = 'views:unpack_options:' . hash('sha256', serialize([
            $this->options,
            $options,
          ])) . ':' . \Drupal::languageManager()
            ->getCurrentLanguage()
            ->getId();
          if (empty(static::$unpackOptions[$cid])) {
            $cache = \Drupal::cache('data')
              ->get($cid);
            if (!empty($cache->data)) {
              $this->options = $cache->data;
            }
            else {
              $this
                ->unpackOptions($this->options, $options);
              \Drupal::cache('data')
                ->set($cid, $this->options, Cache::PERMANENT, $this->view->storage
                ->getCacheTags());
            }
            static::$unpackOptions[$cid] = $this->options;
          }
          else {
            $this->options = static::$unpackOptions[$cid];
          }
        }
        else {
          $this
            ->unpackOptions($this->options, $options);
        }
    

    It seems that, instead of $view_display['display_options'], the module should use $view_display->display['display_options']. From that class, I cannot say $view_display['display_options']['arguments'] is even set, though. My Views knowledge does not allow me to find the answer.

    I guess that what I reported in my comments should be reported in a new issue, even though I do not know how to correct the code.

Production build 0.71.5 2024