4

We have to get the current node's view_mode from within the mymodule_preprocess_page(&$variables) hook. When we tried the following we could not get the view_mode after performing some validation to make sure we have a node object.

In the Basic page, we have a Related Articles section that is an entity reference to the Article content type. This returns multiple nodes depending upon the page and we want to ensure the template_preprocess_node() hook is ran only once.

How can we get the current node's view_mode from within the template_preprocess_page(&$variables) hook?

Here is what we tried to do

function mymodule_preprocess_page(&$variables) {
  $node = $variables['node'];
  if(isset($node) && is_object($node) {
    // Tried printing variables but cannot find `view_mode`
    ksm($node);
  }
}
1
  • @4k4 I updated the question with more information regarding our pages. We essentially added an entity reference to the basic page so we just want to be sure the hook is only run once. Mar 14, 2019 at 21:27

3 Answers 3

5

It's possible you are using the wrong hook. hook_preprocess_page() is not for the content type page. Use a preprocess hook for nodes and check the content type:

function mymodule_preprocess_node(&$variables) {
  if ($variables['node']->getType() === 'page') {
    $view_mode = $variables['view_mode'];
    // preprocess only nodes of the content type "Basic Page"
  }
}
1
  • 1
    I'm actually in need of getting current node's view mode in hook_preprocess_html(). Can it be done? The node can be retrieved by $node = \Drupal::routeMatch()->getParameter('node');. but that node wouldn't contain the current context, if that makes sense?
    – Ejaz
    Apr 23, 2020 at 9:12
4

I needed to put a class based on view mode onto my pages. I seem to remember that view mode is handled separately from the node data. My solution was actually based on using the Display Suite submodule Switch View Mode (was already using DS). This module creates a new base field in the entity and sets the view mode to it.

This let me use the following code to create the class:

$view_mode = $node->ds_switch->value;
if (!empty($view_mode)) {
   $variables['page_class'] .= " node-view-{$view_mode}";
}

This solution won't work with out the module. A bit of tracing on how this works shows that it is based on using hook_entity_view_mode_alter() to get the view mode and add it to the ds_switch field on the node.

This field seems to be added by using the hook_entity_base_field_info(). See the ds_switch_view_mode.module file in the Display Suite code for details on this.

2

You should set a custom node parameter by overriding template_preprocess_node in your .theme file. For example:

function mytheme_preprocess_node(array &$variables, $hook) {
  if(isset($variables['view_mode'])) {
    $node = $variables['node'];
    $node->current_view_mode = $variables['view_mode'];
  }
}

When this is added you can access the custom parameter in template_preprocess page as $node->current_view_mode.

See also Sharing variables between node preprocess and page preprocess

2
  • This! I've been trying to do this and thought it just wasn't possible. So simple. Using this approach, you can then access view mode in template_preprocess_page() with $view_mode = $variables['node']->current_view_mode; If the OP is trying to get access to the view_mode in template_preprocess_page(), this should be the accepted answer. Thank you @batigolix! Jun 2, 2023 at 16:50
  • This doesn't work if the page is invalidated and the node is not, for example by a cache tag other than the node cache tag or a cache context only set on page level.
    – 4uk4
    Jun 5, 2023 at 6:34

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.