In Drupal 11.3.0, a change landed that modernizes how Views plugins handle their preprocess callbacks. If you are maintaining custom Views plugins or themes, this is important to know.
Background: How It Worked Before
Traditionally, Drupal discovered preprocess functions implicitly.
For example, if you had a Views display plugin with a theme hook called views_display_example, Drupal would look for this function automatically:
/
* Preprocess for views_display_example.
*/
function template_preprocess_views_display_example(array &$variables) {
// Add your preprocess logic here.
}
This worked, but it relied on procedural naming conventions, which made things harder to track and less consistent with Drupal’s move towards object-oriented patterns.
What Changed in Drupal 11.3.0
Implicit discovery of template_preprocess_HOOK() functions is being deprecated.
Instead, Views plugins now expect an explicitly defined preprocess callback inside a ThemeHooks class.
Drupal will automatically create a theme hook definition for Views plugins that set a theme key in their plugin definition. Then it looks for a corresponding method in the ThemeHooks class.
The new pattern is:
Drupal\module_name\Hook\ModuleNameThemeHooks::preprocessCamelizedThemeHookName()
Example: Old vs. New
🔴 Before (Deprecated)
A Views display plugin defines theme: "views_display_example".
The old preprocess function looked like this:
/**
* Preprocess for views_display_example.
*/
function template_preprocess_views_display_example(array &$variables) {
$variables['extra'] = 'Hello from preprocess!';
}
🟢 After (Drupal 11.3.0+)
Now you move the logic into a dedicated class under the Hook namespace:
namespace Drupal\views_example_display\Hook;
class ViewsExampleDisplayThemeHooks {
/**
* Initial preprocess callback for views_display_example.
*/
public function preprocessViewsDisplayExample(array &$variables) {
$variables['extra'] = 'Hello from preprocess!';
}
}
Service Registration
Drupal automatically registers this class as a service if it contains at least one preprocess method.
But you can also explicitly declare it in your module’s services.yml:
services:
Drupal\views_example_display\Hook\ViewsExampleDisplayThemeHooks:
autowire: true
Why This Matters
✅ Consistency – All preprocess logic now follows the same OOP structure.
✅ Discoverability – It’s easier to locate preprocess logic in the Hook class instead of scattered procedural functions.
✅ Future-proofing – This aligns with Drupal’s long-term move away from procedural hooks.
Impact on Developers and Themers
- Module developers: Move your
template_preprocess_HOOK()functions intoThemeHooksclasses. - Themers: No change in custom
hook_preprocess_HOOK()usage – your overrides still work.
Conclusion
This change is another step in Drupal’s transition towards cleaner, object-oriented patterns. If you maintain Views plugins, review your preprocess functions and migrate them into ThemeHooks classes before procedural discovery is fully removed.
Comments