Skip to content

Latest commit

 

History

History
107 lines (91 loc) · 4.81 KB

3.5-preprocessors.md

File metadata and controls

107 lines (91 loc) · 4.81 KB

Preprocessors

The Drupal 8 preprocessor layer sits directly between the data and the template layers. It should be used for preparing variables to be used by the template, but not perform any of the actual rendering, as that should be handled by Twig instead.

Preprocessing for template files

From Theme system overview:

If the theme implementation is a template file, several functions are called before the template file is invoked to modify the variables that are passed to the template. These make up the "preprocessing" phase, and are executed (if they exist), in the following order (note that in the following list, HOOK indicates the hook being called or a less specific hook. For example, if '#theme' => 'node__article' is called, hook is node__article and node. MODULE indicates a module name, THEME indicates a theme name, and ENGINE indicates a theme engine name). Modules, themes, and theme engines can provide these functions to modify how the data is preprocessed, before it is passed to the theme template:

  • template_preprocess(&$variables, $hook): Creates a default set of variables for all theme hooks with template implementations. Provided by Drupal Core.
  • template_preprocess_HOOK(&$variables): Should be implemented by the module that registers the theme hook, to set up default variables.
  • MODULE_preprocess(&$variables, $hook): hook_preprocess() is invoked on all implementing modules.
  • MODULE_preprocess_HOOK(&$variables): hook_preprocess_HOOK() is invoked on all implementing modules, so that modules that didn't define the theme hook can alter the variables.
  • ENGINE_engine_preprocess(&$variables, $hook): Allows the theme engine to set necessary variables for all theme hooks with template implementations.
  • ENGINE_engine_preprocess_HOOK(&$variables): Allows the theme engine to set necessary variables for the particular theme hook.
  • THEME_preprocess(&$variables, $hook): Allows the theme to set necessary variables for all theme hooks with template implementations.
  • THEME_preprocess_HOOK(&$variables): Allows the theme to set necessary variables specific to the particular theme hook.

CSS Creation

In a notable change from Drupal 7, CSS class creation has been moved out of preprocessors and directly into templates themselves. To better illustrate, see the following example from CSS classes being moved from preprocess to Twig templates:

The Old Approach

<?php
function template_preprocess_field(&$variables, $hook) {
  // ...
  $variables['attributes']['class'] = array(
    'field',
    'field-' . $variables['entity_type_css'] . '--' . $variables['field_name_css'],
    'field-name-' . $variables['field_name_css'],
    'field-type-' . $variables['field_type_css'],
    'field-label-' . $element['#label_display'],
  );
  // ...
}
?>
<div{{ attributes }}>
  {% if not label_hidden %}
    <div class="field-label{% if title_attributes.class %} {{ title_attributes.class }}{% endif %}"{{ title_attributes|without('class') }}>{{ label }}:&nbsp;</div>
  {% endif %}
  <div class="field-items"{{ content_attributes }}>
    {% for delta, item in items %}
      <div class="field-item"{{ item_attributes[delta] }}>{{ item }}</div>
    {% endfor %}
  </div>
</div>

The New Approach

<?php
function template_preprocess_field(&$variables, $hook) {
  // ...
  $variables['entity_type'] = $element['#entity_type'];
  $variables['field_name'] = $element['#field_name'];
  $variables['field_type'] = $element['#field_type'];
  $variables['label_display'] = $element['#label_display'];
  // ...
}
?>
{%
  set classes = [
    'field',
    'field-' ~ entity_type|clean_class ~ '--' ~ field_name|clean_class,
    'field-name-' ~ field_name|clean_class,
    'field-type-' ~ field_type|clean_class,
    'field-label-' ~ label_display|clean_class,
    label_display == 'inline' ? 'clearfix',
  ]
%}
{%
  set title_classes = [
    'field-label',
    label_display == 'visually_hidden' ? 'visually-hidden'
  ]
%}
<div{{ attributes.addClass(classes) }}>
  {% if not label_hidden %}
    <div{{ title_attributes.addClass(title_classes) }}>{{ label }}:&nbsp;</div>
  {% endif %}
  <div{{ content_attributes.addClass('field-items') }}>
    {% for delta, item in items %}
      <div{{ item_attributes[delta].addClass('field-item') }}>{{ item }}</div>
    {% endfor %}
  </div>
</div>

Additional Resources