8

In Drupal 8 views modes are supported by core, which makes the Entity view modes module obsolete. I will like to have the ability to change my view mode per node without using the Display Suite module.

Does anyone know if I can do this by only using Drupal core or a module that is lighter than Display Suite module?

Ideally, I would like to have a select list to pick my view mode at the node level.

5
  • 1
    That is per content type, I need this from the node level. Commented Mar 2, 2016 at 22:11
  • You could use any field value (from a taxonomy reference or select list field maybe) together with hook_entity_view_mode_alter to very easily build that yourself. Added answer below.
    – leymannx
    Commented Jul 27, 2018 at 21:26
  • 2
    Possible duplicate of How can I programmatically change the view mode?
    – leymannx
    Commented Oct 4, 2018 at 13:01
  • Hey @leymannx, looking over the dates between this question and drupal.stackexchange.com/questions/213334/… and it looks like I asked it first. Why this question is the duplicated? Commented Oct 4, 2018 at 15:38
  • 1
    The exact times of each question are important. The fact the other question has an answer with a solution is the thing that is important. It's about curating the site so the knowledge contained here is as easy to find as possible with as little duplication as possible.
    – Felix Eve
    Commented Oct 5, 2018 at 9:41

5 Answers 5

7

I've used the View Mode Selector module in Drupal 7 for exactly that purpose. I haven't tried it in Drupal 8, but it has an 8.x-1.0-beta1 release created on June 16, 2020.

6
  • This is the only correct answer. The code in preprocess does not work, it will not change the fields already prepared for rendering. In ui you can only change the view mode per content type, this is not what the question is about.
    – 4uk4
    Commented Mar 3, 2016 at 8:36
  • @4k4 look the comments in the question, the op asked for per content type.
    – Vagner
    Commented Mar 3, 2016 at 11:16
  • I think "That is per content type, I need this from the node level" means, "I don't need per content type, I need this from the node level". See also the title of the question.
    – 4uk4
    Commented Mar 3, 2016 at 14:07
  • 4k4 anyway, just @darol100 to say.
    – Vagner
    Commented Mar 3, 2016 at 15:04
  • @4k4 – I'd recommend hook_entity_view_mode_alter instead. Added answer below.
    – leymannx
    Commented Jul 27, 2018 at 21:19
16

That's a task for hook_entity_view_mode_alter().

Change the view mode of an entity that is being displayed.

See the following working sample that automatically lets the node whose ID is 123 be rendered in the teaser view mode when accessed as full page. You could simply add your own logic (type, user, datetime etc.) as well.

/**
 * Implements hook_entity_view_mode_alter().
 */
function MYMODULE_entity_view_mode_alter(&$view_mode, Drupal\Core\Entity\EntityInterface $entity, $context) {

  // Change the view mode to teaser on full page view for node ID 123.
  if ($entity->getEntityTypeId() == 'node' && $entity->id() == '123' && $view_mode == 'full') {
    $view_mode = 'teaser';
  }
}

As you can maybe imagine, from $entity you can get any field value of a node. You could also add some select list field or taxonomy reference to your content type and then adjust that value node-wise. Finally you can use above code snippet to switch the view mode depending on these values. Mission accomplished.

1
  • The module suggested in the accepted answer has been last updated three years ago; using a custom module with the code shown in this answer is probably better. I apologize for the edit: I fixed the link to the documentation page, since the existing one was redirecting to Drupal 10 documentation. (Recent changes in api.drupal.org URLs caused the existing links to either return a 404 error or redirect users to Drupal 10 documentation, which is not probably what should be shown for a Drupal 8 question.)
    – avpaderno
    Commented Jun 19, 2023 at 21:26
4

Edit: just realised original post said without using Display Suite. Will leave answer here anyway should it be useful to others, who came across this question and may wish to know how it's done with Display Suite.

Another options which is available is to use the Display Suite module. I would be tempted to use this over the View Mode Selector module, which does not yet have a stable release. By using Display Suite you will not only be dealing with a stable module, but will also be covered by Drupal's security policy which only applies to stable module releases (alpha, beta and dev modules are not covered).

To switch display modes on individual nodes you need to:

  1. Install the Display Suite and Display Suite Switch View Mode modules, both of which are included in the Display Suite module package.

enter image description here

  1. Go to the edit page for the content/node you want to change. On the edit form will be a tab called Display settings. Inside this tab you can select the display mode to use for this node.

enter image description here

For a more comprehensive description of this process see: Using Display Suite in Drupal 8: How to Use Switch View Mode Sub-module

2

To define a view mode per content type (nodes types) is simple, Drupal 8 already can do that.

Go to Structure -> Content type -> Manage Display

Manage Display

If you want just one view mode for your node (I mean, all nodes of a particular type render in the same way), just use only the default view mode and mange how it will display. The image below shows a screen with more explanation.

Explanation

0

This is similar to Drupal 7. You will want to use template_preprocess_node() to change the view mode before rendering.

<?php

/**
 * Implements template_preprocess_node()
 **/
function THEME_preprocess_node(&$variables) {
  $node = $variables['node'];

  // Check if a field that lists view modes is asking for
  // a different one than currently set. If it is, change it.
  // There is a D7 module that might be ported to D8:
  // https://www.drupal.org/project/view_mode_field

  $variables['#element']['#view_mode'] = 'teaser';
  $variables['view_mode'] = 'teaser';

  // might need to rework other node variables
  $variables['teaser'] = true;
}
?>
0

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.