Fun with entities and Field UI: Views displays

Drupal 7 introduced entities. It's such a great concept, I'm able to easily port Views displays - part of Display suite - to Drupal 7. It is now part of the main package, bundled in a sub module called Display suite Extras, which also includes the 'region to block' and 'switch view mode on a per node basis' features. More goodies, less code, even more power. But back to Views, entities and overriding templates.

For those who don't know exactly what I'm talking about, a quick summary. In the Drupal 6 version of Views displays, you're able to select a single display of a view and rearrange the template variables so you don't have to override the views-view.tpl.php template file. It uses the drag and drop screen that Display suite comes with, but for D7 we decided to use the manage display screens that Field UI provides. This is great because it supports all entities, so any entity that is fieldable use the same forms in which we simply inject our extra regions. However, Views is not an entity, but in comes hook_entity_info to the rescue!

To make sure we can use the Field UI forms, we declare our own entity called 'ds_views', which is not fieldable and only has one default bundle.

<?php
/**
* Implements hook_entity_info().
*/
function ds_extras_entity_info() {

 
// Register a views entity on behalf of Views.
 
$return = array(
   
'ds_views' => array(
     
'label' => t('Display suite Views'),
     
'bundles' => array(),
    ),
  );
  return
$return;
}
?>

So now that we have an entity, we create our own menu callback function which will ask for the field ui form. Display Suite will call all additional fields and add the layout options too.

<?php
function ds_extras_vd_field_ui() {
 
module_load_include('inc', 'field_ui', 'field_ui.admin');
 
$build = drupal_get_form('field_ui_display_overview_form', 'ds_views', 'views', 'default');
  return
$build;
}
?>

However, when calling the Field UI form, we'll get a message saying this entity does not have not any fields. To solve that problem, we can implement hook_field_extra_fields and return one field. In this case, the title will be overridden later on because we also implement hook_ds_fields() which will return our fields for views. 

<?php
/**
* Implements hook_field_extra_fields().
*/
function ds_extras_field_extra_fields() {

 
// Register a single field so fields for vd be picked
  // up nicely in the display overview form.
 
$extra['ds_views']['views'] = array(
   
'display' => array(
     
'title' => array(
       
'label' => t('Title'),
       
'description' => t('Title'),
       
'weight' => 10,
      ),
    ),
  );

  return
$extra;
}
?>

In the screenshot you see a couple template variables which you can now put into the regions of the chosen layout.

Impressive isn't ? Hacky ? Well .. maybe a little bit. There is even more code, because now the combination of a view and a display is recorded as a bundle within the entity I just created above. I've recorded a short screencast so you can see it in action. If you want to try it yourself, download the second alpha release of Display suite for D7 and have fun!

Comments

Submitted by Manuel Garcia on February 19, 2011 - 21:17

Wow it's amazing how cool DS has become in d7

Can't wait to get around to playing with it - thanks for the hard work!

Submitted by yched on February 20, 2011 - 03:29

Heh. Nice to see Field UI is versatile enough that people want to reuse it :-)

Would be interesting to think of which abstraction gains would be needed to remove the hackish part of this (turning Views into entities with 'extra fields' so that Field UI can deal with them)

One idea I've been playing for quite some time (but too late within the D7 cycle) is to officially introduce the notion of 'Display' : an object that encloses display settings for an object, i.e components ('Field API' fields, 'extra' fields...) with order and settings.
(no more spreading this info between N field instance definitions + a serialised array in the variables table + ...)

You can then map a display to
- an entity type + bundle + view mode
- something else (a view...)

Submitted by swentel on February 20, 2011 - 15:16

That's exactly what we're tyring to explore with Display Suite right now: every object in a Drupal installation has a potential different display based on the context (view mode), I even have a proof of concept for page entities, but that's a bridge too far to even release :) If you're in Chicago, we should have a brainstorm about it, I'd be very interested to work on this for the D8 cycle (and you can count Stalski in it for this too)

You are here