Drupal 7: Views, view modes, templates and conditional field formatting

Using drupal 6 I had chosen contemplate module for theming a content
type, I also thought it was the right thing.

But the problem was the need to have another place where to store
theming files, or put it in db, that is a practice I do not like.

Also there could be a number of Views in a website, with different
visualization, and choosing field view mode for a view is something I
do not like, because there is a better way, in my opinion.

My practice is to use custom view modes, (module Entity view modes
make it easy to define new view modes), and then customize i theme
file. So in every view choose to visualize entity with the chosen view
mode. (This does not work for Views Bulk Operation, though)

Every view modes could be setted up to have its own template in theme,
this way:

template.php:

function THEMENAME_preprocess_node(&$variables, $hook) {
  $variables['theme_hook_suggestions'][] = 'node__'.$variables['node']->type;
  $variables['theme_hook_suggestions'][] = 'node__'.$variables['node']->type.'__'.$variables['view_mode'];
}

And in templates/node–type–mode.tpl.php visualizzation can be
customized for every view mode.

There is a problem when one needs to show different formatting option
for a single field depending in entity (node) content, tipically other
field’s values.

$style = 'shrinked';
if($node->field_name ...) $style='shrinked';
$v = field_view_field('node',$node,'field_image',
		      array(
			    'type' => 'image',
			    'label'=> 'hidden',// inline, above
			    'settings'=>array(
			    		    'image_style'=> $style,
		    			    'image_link'=> 'content',
		   		),
			    ));
if($v) print render($v);

and so using this to render various field, or use

$image = field_get_items('node', $node, 'field_image');
$output = field_view_value('node', $node, 'field_image', $image[0], array(
  'type' => 'image',
  'settings' => array(
    'image_style' => 'thumbnail',
    'image_link' => 'content',
  ),
));

(refer to http://www.computerminds.co.uk/articles/rendering-drupal-7-fields-right-way where I found this for another task tough)

Drupal site say don’t use this like that.

In http://api.drupal.org/api/drupal/modules!field!field.module/function/fie… it said to use

render($content[FIELD_NAME])

that of course don’t let you decide how to show content.

Instead hook_field_display_ENTITY_TYPE_alter() can make a number of
tricks without writing html in template:

function THEMENAME_field_display_node_alter(&$display,$context) {
  if($context['entity_type'] != 'node'
     || $context['entity']->type!='mycontetype') return;
  if(isset($context['entity']->field_promotion) &&
     $context['entity']->field_promotion['und'][0]['value']) {
    if($context['field']['type'] == 'specialtype') {
      global $user;
      if($user->uid != 1 && $context['view_mode'] == 'teaser') {
        // do not show special field in teaser mode for no main user
	$display['type'] = 'hidden';
      }
    }
    if($context['field']['field_name'] == 'field_image') {
      if(isset($context['entity']->field_checked['und']) &&
	 $context['entity']->field_checked['und'][0]['value']) {
	if($context['view_mode'] == 'teaser') {
	  $display['label'] = 'above';
	  $display['settings']['image_style'] = 'thumbnail';
	  // or also:
	  //$display['type'] = 'galleryformatter_default';
      	  //$display['module'] = 'galleryformatter';
      	  //$display['weight'] = 100;
	}
	return;
      }
    }
  }
}

here could be moved the label, changed the type of formatter (has to
be done together with the corrisponding module), settings and weight,
almost all what you can do in template file without putting
conditional code there. Also, from a performance prospective, using
code in template is wrong because the field is already rendered a that
time. Calling field_view_field in template file is not the drupal way.

Also in the code above I wrote to do not show a field type ‘specialtype’ for most user in ‘teaser’ view mode, such a thing is very powerful.

 


Posted

in

,

by

Tags: