3

Is it possible to change the view mode of a view result in hook_views_pre_render?

For example I have 3 different view modes (teaser, teaser-full, teaser-short). The goal is to have the view repeat these 3 teaser templates in the view page/listing, but I'm firstly struggling to change the view mode at all.

I tried the below, but it doesn't seem to do anything.

function themename_views_pre_render(ViewExecutable $view) {
  foreach ($view->result as $index => $row) {
    $view->row_index = $index;
    $view->rowPlugin->options['view_mode'] = 'teaser';
  }
}

Note: If I drop a breakpoint into the code, it is being hit. But still gets rendered out as default view mode.

  • 2
    After adding the function, did you do a cache rebuild? If you drop a breakpoint into the code, is the code being hit? – Kevin Aug 15 '16 at 15:34
  • @Kevin yes it is being hit, but still gets rendered out as default view mode. – Janey Aug 15 '16 at 17:56
3

I was able to change the view mode in the hook_views_pre_execute() hook. I believe _views_pre_render() is too late.

function custom_module_views_pre_execute(ViewExecutable $view) {
  // Some logic to determine view mode...

  $view->rowPlugin->options['view_mode'] = 'list';
}
0

You could do it using the Views UI:

  1. Install Entity API module

  2. Make Fields your format

    enter image description here

  3. Since you have Entity API, you can add Rendered Entity as a field.

enter image description here

  1. Select your view mode.

enter image description here

  1. Add more render entity fields for your other view modes (repeat steps 3 and 4).
0

The Views Parity Row solves this problem. Worked well for my needs, I just wanted a different view mode for first row item so had to apply this patch for Drupal 8. Works well for other use cases.

enter image description here

0

I wasn't able to get custom_module_views_pre_execute(ViewExecutable $view) example to work.

After inspecting with xdebug, I was able to use this:

function custom_module_preprocess_views_view(&$variables) {
  if ($view->id() == 'view_name' && $view->current_display == "display_name") {
    if (count($view->result) == 1) {
      // Change view mode to teaser when there is only 1 item.
      $variables['rows'][0]['#rows'][0]['#view_mode'] = 'teaser';
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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