TheRegistry::processExtension()
creates the list of the preprocess hooks is gathered fromimplemented for a single theme hook with the following code.
foreach ($prefixes as $prefix) {
if (isset($info['template']) && function_exists($prefix . '_preprocess')) {
$info['preprocess functions'][] = $prefix . '_preprocess';
}
if (function_exists($prefix . '_preprocess_' . $hook)) {
$info['preprocess functions'][] = $prefix . '_preprocess_' . $hook;
}
}
$prefixes
is initialized from the following code. In particular, see the if ($type == 'module') { /* … */ }
part, which is the one that allows to modules to add their own variable preprocessors (a.k.a. preprocess hooks).
(I left only the relevant comment to make the code shorter. All the comments can be read in the linked documentation page, which shows also the method code.)
if ($type == 'module') {
$prefixes[] = 'template';
// Add all modules so they can intervene with their own variable
// preprocessors. This allows them to provide variable preprocessors
// even if they are not the owner of the current hook.
$prefixes = array_merge($prefixes, $module_list);
}
elseif ($type == 'theme_engine' || $type == 'base_theme_engine') {
$prefixes[] = $name . '_engine';
$prefixes[] = $theme;
}
else {
$prefixes[] = $name;
}
$module_list is initialized with $module_list = array_keys($this->moduleHandler->getModuleList());
The code that invokes themthe preprocess hooks does not use the methods from the ModuleHandler
class I listed earlier, since it builds the list of preprocess hooks to invoke using Registry::processExtension()
, which means hook_module_implements_alter()
is not invoked for preprocess hooks.
The list of modules returned by ModuleHandler::getModuleList
is ordered by the modules weight. This means that changing a module weight will change the order preprocess hooks are invoked.