If a preprocess function is defined for a non-existing template Drupal assumes that template exists

Created on 3 October 2019, almost 5 years ago
Updated 27 June 2023, about 1 year ago

Problem/Motivation

This problem causes template suggestions to fall back to the base template (e.g. node) instead of the next strongest suggestion. Imagine a situation when you want to have a common node--[view-mode].html.twig but also have a specific function the alters some variables which you want to separate from the base theme_preprocess_node function, e.g. theme_preprocess_node__node_type__view_mode. The node--[view-mode].html.twig template won't be used, node.html.twig will be used instead.

Long description

I stumbled upon this during development. I have 2 node types where both use the same custom view mode, Card in this case. As I'm utilizing twig inheritance I wanted to define three templates:

  • node--card.html.twig (which extends node.html.twig)
  • node--foo--card.html.twig (which extends node--card.html.twig)
  • node--baz--card.html.twig (which extends node--card.html.twig)

I had to alter some variables in one of the templates, so I created a my_theme_preprocess_node__foo__card in the my_theme.theme.

Then I wanted to make some changes in node--card.html.twig so I temporarily removed node--foo--card.html.twig and that's when I noticed that nodes listed in a view that should be using the node--card.html.twig template are using node.html.twig instead.

After removing/commenting out my_theme_preprocess_node__foo__card in my_theme.theme the correct template was used.

Steps to reproduce

1. Standard profile installation
2. Create a view that lists articles with the teaser view mode
3. Enable twig debugging
4. Create a Bartik subtheme
5. Create a node--teaser.html.twig
6. In the subtheme's subtheme.theme file create a subtheme_preprocess_node__article__teaser function
7. Enable the subtheme
8. Navigate to the previously created view and check the browser devtools which template is being used
9. Delete/comment out the subtheme_preprocess_node__article__teaser function, rebuild the cache and check the view again, the correct template is being used

I guess the reason why this happens is that when Drupal is collecting the preprocess hooks it's looking for the hook_theme implementations and it's not checked if the preprocess is running for an existing template.

Proposed resolution

I think there is value in defining hook_preprocess_HOOK for very specific theme implementations without an existing template, but the template suggestion order should still be respected.

Remaining tasks

Figure out the solution.

🐛 Bug report
Status

Active

Version

9.5

Component
Theme 

Last updated 1 day ago

Created by

🇭🇺Hungary gaborkurucz

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇺🇸United States ronchica

    I have just experienced a similar issue. To start, in order to implement Search API Solr on Pantheon, I added a new view mode "Search Index" to most of the content types and paragraphs.

    I created a custom general template to only output content, no markup: "node--search-index.html.twig". However there are content types that have some preprocessed content I would like indexed, and this wasn't happening. All content types have custom templates for specific view modes.

    Preprocess functions (template_preprocess_node for example) were not being fired at all when processing a node for the Search Index view mode. I created a custom view mode template (node--article--search-index.html.twig) that was being indexed by Search API, but again, the content did not contain anything from the preprocess function.

    Following the steps above, I created a view mode preprocess function, template_preprocess_node__article__search_index, cleared cache and indexed. This preprocess was fired, and Search API had the preprocessed content. After deleting the function, clearing cache, and reindexing, the original preprocess is fired and all content was indexed.

    I experienced similar issues working with paragraphs as noted in issue #2897906, listed as a related issue.

    This is confusing (and old), so maybe there is something I am missing here about how to structure the templates, but the behavior is definitely inconsistent. It took me a while to figure out what was going on (why preprocessed content wasn't making it into the search index), although it is working now.

Production build 0.71.5 2024