theme_hook_suggestions and custom view modes

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
left's picture

During last week's meet up, I was lucky to be able to discuss my most recent Drupal investigations (as suggested to me in Oct's meet up) - View modes (confusingly also called Display modes).

Over the past month, I'd found this Tim Cosgrove on View modes and opted to go the custom route (over using Display Suite or entity_view_mode module).

My particular use case involves Fieldgroups, Panels, Views, Fences, and custom view modes.

I succeeded in making a custom module for my view mode. The code seemed to do 2 things. One - define my view mode so it shows up as a tab in Manage Display on content types (and in the module manager), and Two - defines how I can name my tpl files to override the node when displayed with that view mode.

/
* Implements hook_entity_info_alter().
* The first attribute in the array defines an arbitrary label for the view mode machine name.
* 'custom settings' => TRUE displays the view mode as a default at the top of the display modes settings screen
*/

function view_mode_landing_page_entity_info_alter(&$entity_info) {
  $entity_info['node']['view modes']['landing_page'] = array(
    'label' => t('Landing Page'),
    'custom settings' => TRUE,
  );
}

/
* Implements hook_preprocess_node().
*/
function view_mode_landing_page_preprocess_node(&$vars) {
  /*dpm(entity_get_info());*/
  if($vars['view_mode'] == 'landing_page') {
    $vars['theme_hook_suggestions'][] = 'node__' . $vars['type'] . '__landing_page';
  }
}

Questions:

  1. I have a custom module per view mode eg. view_mode_landing_page, view_mode_accordion. Could I have a single custom module that would includes all my custom view modes?
  2. The theme_hook_suggestions in the above code - Should this go into my template.php? At the moment it's in the .module file.

My project requires extra markup to be added near the image element so I looked into how to override the field.tpl (using Fences) BUT I couldn't figure out how to name the tpl file so that it would affect field--field-image--node-type--view-mode i.e. the field only when displayed using a specific view mode.

I believe this naming structure is not possible "out-of-the-box", without defining it in using theme_hook_suggestions. In all the documentation I've seen, the field theme hooks are limited to:
field--field-name--content-type.tpl.php
field--content-type.tpl.php
field--field-name.tpl.php
field--field-type.tpl.php

I attempted to emulate the hook_preprocess_node function, but for a field, to no avail.

After discussing it at the meeting, I at least got confirmation that it's possible so I tried again. And although I managed it, more questions...

/**
* Implements hook_preprocess_field().
*/
function MYTHEME_preprocess_field(&$vars) {
$vars['theme_hook_suggestions'][] = 'field__' . $vars['element']['#field_name'] . '__' . $vars['element']['#bundle'] . '__' . $vars['element']['#view_mode'];
}

Questions:

  1. What is bundle?
  2. Why/how does this differ to the node function - ['element']['#whatever'] vs ['type']? I ask because although the field and node preprocess functions are similar, they are too different for me to have guessed correctly. It feels like I'm missing something rather fundamental.

It is likely I will eventually find the answers to these questions myself, but if anyone has any input, please feel free to enlighten me :)

Comments

Tim's presentation is great

conorc's picture

Hi Lisa,

just flicked through Tim's presentation and it looks great.

Would a module like Custom Formatters, in conjunction with Display Suite be a viable alternative?

Someone else might be better at dissecting Bundles in D7, but here's a handy description:

Hope this helps,

Conor

Hi Lisa A lot in there... You

alanburke's picture

Hi Lisa
A lot in there...

You can can define all your custom view modes in a single custom module - no issue there.
The preprocess_node function can live happily in a module. It would work in the theme too,
but the module is fine.

If you're using fences, the template overrides are a little different - fences module changes the default set of themeing template suggestions, as I understand it.
Use devel_themer module to know what the potential theme suggestions are available.

So a bundle is a 'subtype' of entities.
Drupal 7 has entities of type node, user, taxonomy term etc.
Within each entity, there are subtypes called bundles. For nodes, they are better known as 'content types'.
So a content type == a bundle.

Not sure I follow the last part too well, but themeing fields and theming nodes are not quite the same.
Nodes and Fields are structured quite differently, so while the basics of themeing are the same, that's about it.

Hope that helps a little,
Alan

override node--content-type--viewmode.tpl.php teaser

left's picture

I found my original post while googling theme hook suggestions for view modes. I don't know what that signifies exactly...but it was surprisingly informative. I now understand my problem better :)

This time, a different project, similar mix of modules (minus the Panels) - Fieldgroups, Views, Fences, and custom view modes...

So I had the opportunity to make a single module for all my custom view modes, instead of a module per view mode.

I noticed that when I made a module per view mode, I get the advantage of using the module manager to enable/disable each view mode. I can't really think of a valid use case for this however, so I think a single module is nicer.

I am trying to create an override for node--content-type--viewmode.tpl.php for teaser view.

Teaser is a default view mode, so I assumed the theme hook suggestion was already available, but it doesn't seem to be - at least not with a custom content type.

So I uncommented my zen theme subtheme's preprocess node function and added
$vars['theme_hook_suggestions'][] = 'node__' . $vars['node']->type . '__' . $vars['view_mode'];

Which is lovely, because now I can remove the specific theme suggestion hooks from my custom view mode module, and let the generic preprocess function take care of all future custom view modes. And I can also add the field theme hook suggestions from the first post do to the same for fields.

So that's my hands-on answer to questions 1&2 from Part A...

Thanks for the comments and clarification Alan and Conor. It's a great feeling when things start falling into place, and discussion (and/or monologues!) can really help.