0

Given a known View, how would one dynamically generate a Form API select list of the routes to its Page Displays?

In my case, I have a Search API View (view.search) with a default site-wide search page (view.search.page_1) and separate search pages for different site sections, or "micro-sites" (e.g., view.search.page_2, view.search.page_3, etc.)

I have coded a custom block to replace the Drupal core Search form, which redirects to the site-wide search page, passing the fulltext query parameters as $link_options:

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {

    // Redirect to a search page, appending search keys.
    $search_route = 'view.search.page_1';
    $search_url = Url::fromRoute($search_route);
    $link_options = [
      'query' => [
        'search_api_fulltext' => $form_state->getValue('keys')
      ],
    ];
    $search_url->setOptions($link_options);

    $form_state->setRedirectUrl($search_url);
  }

Next, I would like to provide per-block configuration in the Block Plugin class implementation, so that the redirect route can be selected by a site admin when placing an instance of the block.

I'm about to hard-code this form select element, but it would be nice if the list would automatically update later if a new display were to be added to the View.

In a drush php:cli, I can use the entity type manager to load the View storage:

>>> $view = \Drupal::entityTypeManager()
  ->getStorage('view')
  ->load('search')
  ->getExecutable();

And I can call a specific display as long as I know its machine name:

>>> $display = $view->getDisplay('page_2');

But there does not seem to be a $view->getDisplays() method:

>>> $displays = $view->getDisplays();
PHP Error:  Call to undefined method Drupal\views\ViewExecutable::getDisplays() in Psy Shell code on line 1

In my module, I don't need to actually deal with any of the usual Views API stuff (e.g., filter and sort criteria, rendering a display, etc.). I just need the machine names of valid page displays so I can concatenate them with 'view.search.' . $displayname and pass that to Url::fromRoute() so my new Form knows where to redirect its query.

1

1 Answer 1

2

Assuming a recent version of Drupal (I checked 9.5 and 10.1 on api.drupal.org), you should be able to $view->get(‘display’); and have it return an array of all the displays. Don’t forget to typecheck $view, or at least check that it’s not null, before trying to call one of its methods.

NB: I haven’t tried it myself, so this is just what I gleaned from api.d.o. YMMV.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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