Drupal 7 custom node view modes
Monday, December 20, 2010 - 16:06
One of the cool new things in Drupal 7 is the ability to easily add new “View modes” for nodes. View modes are available for other entities like comments also, but I’m gonna only cover the nodes for this time.
Before, Drupal had only two “hard-coded” node view modes, the full node view and the teaser view. These two provided us just enough flexibility for most simple content listings, but quite often we needed to turn to Views in Fields mode to get more flexibility. By flexibility in this case I mean displaying the same content in different ways in different contexts.
In Drupal 7 we can create additional view modes by simply implementing hook_entity_info_alter() in our custom module.
After defining the new view mode, we can go to content type’s “Manage Display” page and select which fields to display plus some additional options for fields, like which image style to use for image fields, for example.
Next we need to get this view mode used somewhere. We’re gonna create a View for that. Set the View to Style = Unformatted, Row style = Node and select the “Another teaser” view mode from the row style options. Optionally you can create a page display with a path for the View for easier testing.
Up to this point nothing is that different than creating a view in “fields” mode, and select the desired fields one by one in the view itself. The differences are mostly how we can apply some theming and custom layout for the content.
To get the most out of this we’ll propably want to add a custom node.tpl.php template for this view mode. Custom node template enables easy and flexible theming and we can use standard hook_preprocess_node() function for example to control the variables we have available in the template. To make Drupal use a different .tpl.php file for view mode we need to add a new template suggestion in hook_preprocess_node().
There are many other ways to get the exactly same outcome, like the Display Suite module, but seems to be an overkill for a simple need what we just covered. While Views in fields mode is still most often the way to go, this opens a completely fresh option if you need to reuse the templates in multiple views, or you need to display every content type in a different way in the same listing without doing gigantic template files for views.
Before, Drupal had only two “hard-coded” node view modes, the full node view and the teaser view. These two provided us just enough flexibility for most simple content listings, but quite often we needed to turn to Views in Fields mode to get more flexibility. By flexibility in this case I mean displaying the same content in different ways in different contexts.
In Drupal 7 we can create additional view modes by simply implementing hook_entity_info_alter() in our custom module.
/**
* Implements hook_entity_info_alter().
*/
function MYMODULE_entity_info_alter(&$entity_info) {
$entity_info['node']['view modes']['another_teaser'] = array(
'label' => t('Another teaser'),
'custom settings' => TRUE,
);
}
After defining the new view mode, we can go to content type’s “Manage Display” page and select which fields to display plus some additional options for fields, like which image style to use for image fields, for example.
Next we need to get this view mode used somewhere. We’re gonna create a View for that. Set the View to Style = Unformatted, Row style = Node and select the “Another teaser” view mode from the row style options. Optionally you can create a page display with a path for the View for easier testing.
Up to this point nothing is that different than creating a view in “fields” mode, and select the desired fields one by one in the view itself. The differences are mostly how we can apply some theming and custom layout for the content.
To get the most out of this we’ll propably want to add a custom node.tpl.php template for this view mode. Custom node template enables easy and flexible theming and we can use standard hook_preprocess_node() function for example to control the variables we have available in the template. To make Drupal use a different .tpl.php file for view mode we need to add a new template suggestion in hook_preprocess_node().
/**
* Implements hook_preprocess_node().
*/
function MYMODULE_preprocess_node(&$vars) {
if($vars['view_mode'] == 'another_teaser') {
$vars['theme_hook_suggestions'][] = 'node__' . $vars['type'] . '__another_teaser';
}
}
Duplicate standard node.tpl.php for the content type you need, like node--article--another-teaser.tpl.php. (NOTE: use underscores in template suggestions, dashes in the filename).There are many other ways to get the exactly same outcome, like the Display Suite module, but seems to be an overkill for a simple need what we just covered. While Views in fields mode is still most often the way to go, this opens a completely fresh option if you need to reuse the templates in multiple views, or you need to display every content type in a different way in the same listing without doing gigantic template files for views.
http://www.wunderkraut.com/blog/drupal-7-custom-node-view-modes/2010-12-20
Comments
This really rocks!
Impressive! This will change
:). Can't wait to start
THANX !!!
I also tried Display Suite for this, but currently it doesn´t work correctly with views and of course is an overkill. THANKS AGAIN !!!
Thanks
Also thanks for the drupal 7 tips. Looking forward to working on new projects so can start with D7.
Thanks for this cool
This is especially powerful in D7 since you can now define field order per view mode (in CCK D6, field display order = form display order, for all view modes)
Note that Display Suite in D7 got notably skimmed down since much of its features are now handled in core, or can plug directly on the main core field UI, instead of having to develop a complete alternate UI in D6.
Display Suite notably offers a UI to create your own custom view modes - although, as you point, creating them through code is quite straightforward.
$view_mode
AFAIK $vars['build_mode'] is not available in preprocess_node functions, but $vars['view_mode'] is.
I took the creation of template suggestions a small step further by doing this:
/**
* Implements hook_preprocess_node().
*/
function MYMODULE_preprocess_node(&$vars) {
$vars['theme_hook_suggestions'][] = 'node__' . $vars['type'] . '__' . $vars['view_mode'];
}
As a result, I can now use this file naming pattern for all possible node type & view mode combinations: node--NODE-TYPE--VIEW-MODE.tpl.php.
You are right,
Thanks for the hint to use a general vars['view_mode'] in the template suggestions.
"Preview Trimmed Version"
I am very new to Drupal and can´t figure out why my html codes doesn´t work in content when saved. If i check the preview -- "Preview Trimmed Version" is how i want it to be displayed in content when saved. Now "content" displays in the "Preview full version" which is not how the html codes should turn out. I checked the html codes and they are correct. Please, if any one knows how to solve this it would be great! Thank you.
yes but ...
it's perfect for what i need, but where i put the code :
/**
* Implements hook_entity_info_alter().
*/
function MYMODULE_entity_info_alter(&$entity_info) {
$entity_info['node']['view modes']['another_teaser'] = array(
'label' => t('Another teaser'),
'custom settings' => TRUE,
);
}
?
I must create a new module just for that?
Im a newbie...
sorr for my poor english
Custom module
See: http://drupal.org/node/361112
Another useful tip relating
Instead of creating separate template files per view mode you can use the $view_mode variable in your default node type template file.
for example in your "node--news_post.tpl.php" file, you can set the output of your "another_teaser" custom view mode with the following...
custom teaser output code here
update to Views 3
Could you, or anybody who feels like it, comment on how you should do do this using Views 3?
And is a view really necessary? It seems like overkill to me, what good is a display mode in core if you can't use it without a contrib module...
thx for the nice snipped.
I had the same problem. Set
you shouldn't use a string if
Using this code to create a JSON view formatter...
I want to try doing this in D7 and VIews3, but no luck out of the box. So I ran across your article, and I am wondering if this could be a solution.
So one of the "another teaser" I would create a view of type JSON. and all of the FILES, and IMAGES would be URL's. The output would have a path with a .json extension. What more am I missing, and am I going int he right direction? perhaps there is some sample code out there that I could look at?
thanks
Thanks for this article
In case it helps anyone else, I discovered the 'hook_entity_info_alter' feature in the node_example module (example_node_list), but they failed to mention where this modification would manifest itself in the Drupal admin area. It didn't even occur to me that it added a new view mode in the Manage Display tab. So simple! That detail would be helpful.
Anyway, thanks for helping me connect the dots!
How to show only one node
How do I use this view with a specified node? I don't want to look at all the nodes on the same page. I want to be able to select one node and then perhaps switch between view modes for just that node. I imagine I can possibly pass an argument to the view and filter the view based on that argument but I don't know how or if there is an easier/better way.
Thanks again.
unable to see new view mode
I am not sure what wrong I am doing. I created new module in sites\all\modules\ as energy_landing. Created .info and .module file enable module but still I cant see new view mode.. Please help
I'm at the same place. Did
Thank you!
Small but powerful
This tutorial has been copied
You need to clear the cache twice
For some reason the new view mode didn't appear without clearing the cache twice. Very useful tutorial. Thanks!
Make it into Drupal?
You could just use Entity
Yes, this was my pick after
Thank you!
This post helped me again ;)
Great!
choosing multiple page for same content
I want , when i create a content, to choose multiple node/pages to display my content. For exemple when i'm creating my article i want a fields who allow me to select multiple link of my website.
Is there a way to do that with, just creating a new view or content type ? Or should i alter a module or create a new one for my purpose ?
A link with a turtorial or similar case should be fine too ;)
thank you in advance for your response.
Why not using the hook_entity
What an eye opener!
Thank you very much!!!
Entity view mode
simple question
Thanks.
adjust visibility in the code
If you want to adjust the visibility of a field from within the code, so you don't have to mess around with the UI at all, you will likely have to do something like this:
$node->content['my_field_of_interest']['#hidden'] = FALSE;
otherwise the field may be hidden in your new view mode. It may be worth noting this alternative as part of the tutorial, below where you say «we can go to content type’s “Manage Display” page and select which fields to display».
... in hook_node_view
Clear and concise
If you set
'custom settings' => FALSE,
if won't be enabled by default (on all content types) and you can choose which content types to enable it on.