10

In Drupal 7 I did something like:

  function mymodule_views_pre_render(&$view) {
    //dpm($view);
    if ($view->name == 'services') {
      $view->style_plugin->row_plugin->options['view_mode'] = variable_get('services_teaser');
    }
    else if ($view->name == 'portfolio') {
      $view->style_plugin->row_plugin->options['view_mode'] = variable_get('portfolio_teaser');
    }
  }

I don't know how to set the view mode on the fly, in Drupal 8. The idea is to be able to select the view mode for the view from a configuration form, instead of doing it from the view form.

How do I achieve this?

5 Answers 5

15

You can select VIew Mode as:

function YOUR_MODULE_entity_view_mode_alter(&$view_mode, Drupal\Core\Entity\EntityInterface $entity, $context) {
  if ($entity->getEntityTypeId() == 'taxonomy_term' && $entity->bundle() == 'tag' && $view_mode == 'full') {
    $view_mode = 'CUSTOM VIEW MODE';
  }
}
3
  • 1
    I did not know this existed and I am now very pumped about having it in my toolkit. Commented Oct 23, 2019 at 16:08
  • 1
    Not sure why this is the accepted answer when the question is about changing the view mode used in a view output. The answer by Stephan below is the correct one.
    – liquidcms
    Commented Mar 16, 2022 at 2:19
  • Definitely @liquidcms this isn't an answer to a question. It refers to something completly different.
    – David
    Commented Mar 16, 2022 at 9:13
4

Since the example code seems to be for a view, with hook_views_pre_build() you can programmatically set the view mode in a Drupal 9 view.

/**
 * Put the following lines on the top of the module file,
 * after the PHP opening tag and the documentation comment containing the
 * @file tag.
 */
use Drupal\views\Plugin\views\row\EntityRow;
use Drupal\views\ViewExecutable;

/**
 * Implements hook_views_pre_build().
 */
function YOUR_MODULE_views_pre_build(ViewExecutable $view) {
  if ($view->rowPlugin instanceof EntityRow && $view->rowPlugin->getEntityTypeId() === 'node' && $view->rowPlugin->options['view_mode'] === 'teaser') {
    $view->rowPlugin->options['view_mode'] = 'other_teaser';
  }
}

Maybe this is useful for others who need to migrate their Drupal 7 custom code to Drupal 9 or higher.

5
  • This question isn't about Views, but about a content view-mode
    – vrijdenker
    Commented Jan 27, 2022 at 10:05
  • 1
    @vrijdenker: Yes and no. The title of his question belongs to how to change the view mode programmatically, which could be done with hook_entity_view_mode_alter(). But his D7 code select a view mode for different views in a programmatically way. Maybe he want something, that website visitors of the view output could switch the view mode of displayed entities via some selectable field or for some amount of entities of the view result? Commented Jan 28, 2022 at 14:49
  • I'm sorry, you are absolutely right. I myself didn't read the question correctly. For some reason StackExchange won't let me undo my vote untill you edit the post. Maybe adding a space or a dot is enouch so that I can undo my vote.
    – vrijdenker
    Commented Jan 28, 2022 at 15:52
  • Our application was solved with @SteffenSchlaer's answer but we needed to select Views format view mode based on number of results. Using this code: $view->execute(); $count = count($view->result); solves this except sets up unwanted recursion. Using a drupal_static variable to break out of the 2nd call to this makes it all work.
    – liquidcms
    Commented Mar 16, 2022 at 2:23
  • I was using your code, but not all views have a rowplugin. That depends on the styleplugin...
    – commonpike
    Commented Jul 6, 2023 at 15:22
2

Extending @tim's answer, I found that I had to change the cache key as well.

function HOOK_entity_view_alter(array &$build, Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display) {
      if ($entity->getType() === 'my_content_type') {
        // Get the value of the "setting" field.
        switch ($entity->field_list_style->value) {
          case 'custom':
            // Set the view mode.
            $count = $build['field_my_entity_reference']['#items']->count();
            for ($i = 0; $i < $count; $i++) {
              $build['field_my_entity_reference'][$i]['#view_mode'] = 'custom_view_mode';

              $cache_key = array_search('default_view_mode', $build['field_my_entity_reference'][$key]['#cache']['keys']);
              $build['field_my_entity_reference'][$key]['#cache']['keys'][$cache_key] = 'custom_view_mode';
            }
            break;
        }
      }
    }
2

In a preprocess function, it can be done depending of a value of one field like this:

function hook_preprocess_paragraph(array &$variables) {
  $paragraph = $variables['paragraph'];
  if ($paragraph->field_paragraph_image_clickable->value === "0") {
    $variables['content']['field_paragraph_image_ref']['0']['#view_mode'] = 'image_without_link';
    unset($variables['content']['field_paragraph_image_ref']['0']['#cache']['keys']);
  }
0

If you have an entity reference field attached to a node, and want to offer the editor a choice of view modes through another field, you can change the view mode in the render array.

In this example my_content_type has a field field_my_entity_reference that is set up to be rendered using default_view_mode. The field_list_style field offers a list of display options that are used to override the default view mode.

function HOOK_entity_view_alter(array &$build, Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display) {
  if ($entity->getType() === 'my_content_type') {
    // Get the value of the "setting" field.
    switch ($entity->field_list_style->value) {
      case 'custom':
        // Set the view mode.
        $count = $build['field_my_entity_reference']['#items']->count();
        for ($i = 0; $i < $count; $i++) {
          $build['field_my_entity_reference'][$i]['#view_mode'] = 'custom_view_mode';
        }
        break;
    }
  }
}

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.