This project is not covered by Drupal’s security advisory policy.

This module makes Display suite field templates programmatically available outside of Display suite layouts, and integrates them with renderkit / cfrplugin.

This is essentially a proof-of-concept for this issue in the Display suite issue queue:
#2767947: Make ds_extras field templates available outside of DS layouts

(Explanations on this page are partially copied from https://www.drupal.org/node/1795368)

How does Drupal core render fields?

By default, Drupal core wraps fields in multiple HTML elements, as e.g., in:

<div class="field field-name-field-size field-type-text field-label-above">
  <div class="field-label">Size:&nbsp;</div>
  <div class="field-items">
    <div class="field-item even">34</div>
  </div>
</div>

This wrapper html is independent of the field formatter. E.g. in the example, the formatter only produces the 34. The wrapper html is produced by theme_field(), or any theme implementation overriding it, and any process and preprocess functions for theme_field().

Customization would typically happen in a theme override like THEMENAME_field(), or with a more targeted implementation like THEMENAME_field__body__article().

The problem here is that your theme would need to be aware of site configuration such as bundle names and field names. This makes your theme hard to reuse, and it requires you to change your theme code whenever you change the respective configuration. It is a problem very typical for Drupal: Code depending on configuration.

What are DS field templates?

Display suite provides a mechanism to change this wrapper html for field displays within a Display suite layout.
A DS field template can be chosen per displayed field in a view mode, as a fallback per field instance, and as a global fallback for all field displays controlled by Display suite.

DS field templates have no effect on fields displayed outside Display suite layouts.

The main advantage is that the code defining the field template is completely unaware of your site configuration, and can be easily reused on other projects. The setting that associates a field template with a field in a view mode lives in the database, or in an exported feature, which are allowed to depend on configuration.

Internally it works like this:

  1. Drupal core uses the field formatter and builds a render array with $element['#theme'] === 'field'.
  2. drupal_render($element) triggers theme('field', ..), which triggers the (pre)process functions.
  3. ds_extras_preprocess_field() checks if the view mode has a Display suite layout attached, and if the field within this view mode has a field template configured, or can use one of the fallback field templates. (*)
  4. ds_extras_preprocess_field() adds theme hook suggestions based on the field template.
  5. Drupal core's theme('field', ..) calls one of the theme hook suggestions instead of theme_field().
  6. The respective function, e.g. theme_ds_field_minimal(), produces different wrapper html than the native implementation of theme_field().

(*) To determine the field template for a given field displayed in a view mode, ds_extras_preprocess_field() directly queries the respective configuration via ds_get_layout() and ds_get_field_settings(). This means that this will only work for view modes with display suite layout.

DS field template plus

This module uses hook_theme_registry_alter() to replace ds_extras_preprocess_field()with its own _ds_ft_plus_ds_extras_preprocess_field(). The main difference is that this function does not query the configuration, but instead looks into $element['#ds_ft_plus_field_template'].

The actual query happens in ds_ft_plus_field_attach_view_alter(), which calls ds_get_layout() and ds_get_field_settings() and writes the configuration into $element['#ds_ft_plus_field_template'].

So far the resulting behavior is, or should be, equivalent to what we had without this module.

However: This new architecture allows other code to set field templates on field displays that are not within Display suite layouts!
E.g. via hook_field_attach_view_alter().

Given a render array with $element['#theme'] === 'field', one can set

$element['#ds_ft_plus_field_template'] = array(
  'func' => 'minimal',
);

and then the field will be rendered with the configured field template.

Integration with renderkit / cfrplugin

Renderkit has one implementation of EntityDisplayInterface which renders a field: class EntityDisplay_FieldWithFormatter. This class is also exposed as a cfr plugin.

Typically this will just render the field with '#theme' => 'field' like in core, so the regular field wrapper html will appear.

In recent versions of renderkit (~July 2016), this class accepts an optional FieldDisplayProcessorInterface object, which can alter the render array for the field display.

Adapters exist for e.g. ListFormatInterface. So the same ListFormat implementation can be used for field items or for e.g. views rows.

The ds_ft_plus module provides a specific implementation class FieldDisplayProcessor_DsFieldTemplate implements FieldDisplayProcessorInterface, which sets $element['#ds_ft_plus_field_template'] so the field will be rendered with the provided field template configuration.

This trick is only possible with the surgery described above.
Since this is a bit experimental and might have side effects, it was decided to put this into a standalone module, and not make it part of renderkit.

Project Information

Downloads