Skip to main content

Drupal 8 - Understanding theme preprocess hook and suggestions

Preprocess hooks explained by example

Scenario:

I have Drupal 8 with theme "scriptun" and content type "article" with entity reference field named "field_tags". When I view my article I see theme suggestions:

 

FILE NAME SUGGESTIONS:
   * field--node--field-tags--article.html.twig
   x field--node--field-tags.html.twig
   * field--node--article.html.twig
   * field--field-tags.html.twig
   * field--entity-reference.html.twig
   * field.html.twig

As you can see field--node--field-tags.html.twig is checked as used because I created this file in my theme directory.
Those theme file suggestions are also hooks for preprocess function. So basing on above suggestions we can use functions:

function scriptun_preprocess_field__node__field_tags__article(&$variables) {}
function scriptun_preprocess_field__node__field_tags(&$variables) {}
function scriptun_preprocess_field__node__article(&$variables) {}
function scriptun_preprocess_field__field_tags(&$variables) {}
function scriptun_preprocess_field__entity_reference(&$variables) {}
function scriptun_preprocess_field(&$variables) {}

Now which one is used?! I have field--node--field-tags.html.twig suggestions checked so of course it will be it, but last suggestion is always default hook, that will be used too. Other suggestions will be skipped. So in summary it`s looks like that:

function scriptun_preprocess_field__node__field_tags__article(&$variables) {
    // never executed
}
function scriptun_preprocess_field__node__field_tags(&$variables) {
    // CALLED
}
function scriptun_preprocess_field__node__article(&$variables) {
    // never executed
}
function scriptun_preprocess_field__field_tags(&$variables) {
    // never executed
}
function scriptun_preprocess_field__entity_reference(&$variables) {
    // never executed
}
function scriptun_preprocess_field(&$variables) {
    // ALWAYS CALLED
}

 As you can see, preprocess hooks are just suggestions, that allows us to preprocess variables passed to twig.

Now I have created new file in my theme directory: field--node--field-tags--article.html.twig
By looking on suggestions you can see, that this one is on the first place so it is more important than others. My theme will use this file instead of previous: field--node--field-tags.html.twig

FILE NAME SUGGESTIONS:
   x field--node--field-tags--article.html.twig
   * field--node--field-tags.html.twig
   * field--node--article.html.twig
   * field--field-tags.html.twig
   * field--entity-reference.html.twig
   * field.html.twig

Works! But my preprocess function don`t. Othere file was execuded, so we have to change our preprocess HOOK:

function scriptun_preprocess_field__node__field_tags__article(&$variables) {
    // CALLED!
}
function scriptun_preprocess_field__node__field_tags(&$variables) {
    // this one was called with previous file, now it`s never executed
}
function scriptun_preprocess_field__node__article(&$variables) {
    // never executed
}
function scriptun_preprocess_field__field_tags(&$variables) {
    // never executed
}
function scriptun_preprocess_field__entity_reference(&$variables) {
    // never executed
}
function scriptun_preprocess_field(&$variables) {
    // ALWAYS CALLED
}

Inside &$variables

& mean that variable is passed as reference. That`s why, any change on this variable is available in other functions without returning any value at the end.

$variables is an array where keys are variable names in twig template. By creating this function:

function scriptun_preprocess_field(&$variables) {
    $variables['some_scriptun_variable'] = date("Y-m-d");
}

we have current date available inside rendered twig for every field:

Current date: {{ some_scriptun_variable }}

Where those suggestions came from?

By going more deeply, theme suggestions are defined in theme_suggestions functions.
Let`s stick to our field module.  Just search for theme_suggestions_field in Drupal 8 modules directory. You will find system.module file inside system module with function:

/**
 * Implements hook_theme_suggestions_HOOK().
 */
function system_theme_suggestions_field(array $variables) {
  $suggestions = [];
  $element = $variables['element'];

  $suggestions[] = 'field__' . $element['#field_type'];
  $suggestions[] = 'field__' . $element['#field_name'];
  $suggestions[] = 'field__' . $element['#entity_type'] . '__' . $element['#bundle'];
  $suggestions[] = 'field__' . $element['#entity_type'] . '__' . $element['#field_name'];
  $suggestions[] = 'field__' . $element['#entity_type'] . '__' . $element['#field_name'] . '__' . $element['#bundle'];

  return $suggestions;
}

It`s clear now right?! You can even extend it by creating alter function:

function scriptun_theme_suggestions_field_alter(array &$suggestions, array $variables){
  $suggestions[] = 'my-own-scriptun-suggestion';
}

cache cleared, and we have new suggestion:

FILE NAME SUGGESTIONS:
   * my-own-scriptun-suggestion.html.twig
   x field--node--field-tags--article.html.twig
   * field--node--field-tags.html.twig
   * field--node--article.html.twig
   * field--field-tags.html.twig
   * field--entity-reference.html.twig
   * field.html.twig

 

See also other theming articles

Add new comment

CAPTCHA

This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.

We use cookies on our website to enhance your user experience. We also use Google analytics and ads.

Click here to read more I've read it