Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 293902

Handle module preprocess functions as OOP hooks

$
0
0

Problem/Motivation

hook_preprocess, hook_preprocess_HOOK, and template_preprocess_HOOK functions are still required to be in a .module/.inc file.

Steps to reproduce

N/A

Proposed resolution

  1. ModuleHandler::invoke in pre-Drupal 11.1 didn't check whether the $module parameter was, indeed, a module, it just called the $module_$hook function. This was routinely used for non-module purposes, for example Views used to pass core as a module. This functionality survives in ModuleHandler::legacyInvoke which ModuleHandler::invoke calls as a fallback.
  2. Therefore, it is possible to call $this->moduleHandler->invoke($prefix, $preprocess_hook) with whatever $prefix is used in Drupal\Core\Theme\Registry::processExtension: theme engines, themes, the fixed string template, and, of course modules. Using invoke like this not only calls every existing preprocess function without a problem but when $prefix is a real module then we get OOP functionality for free.
  3. This requires caching the prefix and the hook separately. We could store them like this: ['module' => $prefix, 'hook' => 'preprocess_'. $hook] and then because named arguments work together with the splat operator (they were designed together for PHP 5.6 but named arguments needed to wait until 8.0 -- we are well past that version), we can just pass such an array to invoke directly.
  4. Also, we could add the fixed string template as a module in appropriate places -- HookCollectorPass and ModuleHandler -- and then template_preprocess* also can be implemented as OOP without many problems.
  5. We add two new attributes extending Hook to make it easier to write preprocess and template_preprocess hooks. For now we do not extend TemplatePreprocess from Preprocess because it's not yet clear what api module can support -- the way Hook is changed internally also serves api purposes. Constants are easy to support.
  6. Finally we modify Registry to use invokeAllWith for gathering hook_preprocess_HOOK to avoid checking missing preprocess functions

All this requires surprisingly little code to provide both full backwards compatibility and OOP capability. What this does not provide is the ability to implement preprocess hooks in OOP code multiple times by the same module. This is not even planned as it would require a significant overhaul of the theme registry system. Do not let perfect be the enemy of good enough.

Remaining tasks

Quick note, the approach has changed a fair bit to address @berdir's feedback.
Review this MR https://git.drupalcode.org/project/drupal/-/merge_requests/10826

Need to address grouped preprocess functions.

Interdiff showing just the scanning changes for preprocess functions: https://git.drupalcode.org/issue/drupal-3495943/-/merge_requests/1/diffs

In a followup, refactor ModuleHandler and ThemeHandler so they have a common base (they used to be the same thing after all) and provide OOP capability for hooks by themes. This likely needs #2941757: Extension System, Part IV: Properly register all installed extensions/namespaces during container generation first.

Original approach (hidden): https://git.drupalcode.org/issue/drupal-3495943/-/tree/3495943-handle-mo...
@berdir's original invokeall approach (hidden): https://git.drupalcode.org/project/drupal/-/merge_requests/10762
New approach with only functional changes (hidden): https://git.drupalcode.org/project/drupal/-/merge_requests/10825

User interface changes

N/A

Introduced terminology

API changes

Added #[Preprocess] and #[TemplatePreprocess] hook attributes extending #[Hook]. It is recommended these attributes to be committed to every supported branch for the same reason Hook and LegacyHook was. Aspiring contrib authors can use the LegacyHook attribute and pattern with preprocess hooks much like with any other hook to maintain a single branch which is compatible with Drupal before and after this patch.

Data model changes

N/A

Release notes snippet


Viewing all articles
Browse latest Browse all 293902

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>