Registry::processExtension

protected Registry::processExtension(array &$cache, $name, $type, $theme, $path)

Process a single implementation of hook_theme().

Parameters

array $cache: The theme registry that will eventually be cached; It is an associative array keyed by theme hooks, whose values are associative arrays describing the hook:

  • 'type': The passed-in $type.
  • 'theme path': The passed-in $path.
  • 'function': The name of the function generating output for this theme hook. Either defined explicitly in hook_theme() or, if neither 'function' nor 'template' is defined, then the default theme function name is used. The default theme function name is the theme hook prefixed by either 'theme_' for modules or '$name_' for everything else. If 'function' is defined, 'template' is not used.
  • 'template': The filename of the template generating output for this theme hook. The template is in the directory defined by the 'path' key of hook_theme() or defaults to "$path/templates".
  • 'variables': The variables for this theme hook as defined in hook_theme(). If there is more than one implementation and 'variables' is not specified in a later one, then the previous definition is kept.
  • 'render element': The renderable element for this theme hook as defined in hook_theme(). If there is more than one implementation and 'render element' is not specified in a later one, then the previous definition is kept.
  • See the Theme system overview topic for detailed documentation.

string $name: The name of the module, theme engine, base theme engine, theme or base theme implementing hook_theme().

string $type: One of 'module', 'theme_engine', 'base_theme_engine', 'theme', or 'base_theme'. Unlike regular hooks that can only be implemented by modules, each of these can implement hook_theme(). This function is called in aforementioned order and new entries override older ones. For example, if a theme hook is both defined by a module and a theme, then the definition in the theme will be used.

string $theme: The actual name of theme, module, etc. that is being processed.

string $path: The directory where $name is. For example, modules/system or themes/bartik.

Throws

\BadFunctionCallException

See also

\Drupal\Core\Theme\ThemeManagerInterface::render()

hook_theme()

\Drupal\Core\Extension\ThemeHandler::listInfo()

twig_render_template()

File

core/lib/Drupal/Core/Theme/Registry.php, line 420

Class

Registry
Defines the theme registry service.

Namespace

Drupal\Core\Theme

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
protected function processExtension(array &$cache, $name, $type, $theme, $path) {
  $result = array();
 
  $hook_defaults = array(
    'variables' => TRUE,
    'render element' => TRUE,
    'pattern' => TRUE,
    'base hook' => TRUE,
  );
 
  $module_list = array_keys($this->moduleHandler->getModuleList());
 
  // Invoke the hook_theme() implementation, preprocess what is returned, and
  // merge it into $cache.
  $function = $name . '_theme';
  if (function_exists($function)) {
    $result = $function($cache, $type, $theme, $path);
    foreach ($result as $hook => $info) {
      // When a theme or engine overrides a module's theme function
      // $result[$hook] will only contain key/value pairs for information being
      // overridden.  Pull the rest of the information from what was defined by
      // an earlier hook.
 
      // Fill in the type and path of the module, theme, or engine that
      // implements this theme function.
      $result[$hook]['type'] = $type;
      $result[$hook]['theme path'] = $path;
 
      // If a theme hook has a base hook, mark its preprocess functions always
      // incomplete in order to inherit the base hook's preprocess functions.
      if (!empty($result[$hook]['base hook'])) {
        $result[$hook]['incomplete preprocess functions'] = TRUE;
      }
 
      if (isset($cache[$hook]['includes'])) {
        $result[$hook]['includes'] = $cache[$hook]['includes'];
      }
 
      // Load the includes, as they may contain preprocess functions.
      if (isset($info['includes'])) {
        foreach ($info['includes'] as $include_file) {
          include_once $this->root . '/' . $include_file;
        }
      }
 
      // If the theme implementation defines a file, then also use the path
      // that it defined. Otherwise use the default path. This allows
      // system.module to declare theme functions on behalf of core .include
      // files.
      if (isset($info['file'])) {
        $include_file = isset($info['path']) ? $info['path'] : $path;
        $include_file .= '/' . $info['file'];
        include_once $this->root . '/' . $include_file;
        $result[$hook]['includes'][] = $include_file;
      }
 
      // A template file is the default implementation for a theme hook, but
      // if the theme hook specifies a function callback instead, check to
      // ensure the function actually exists.
      if (isset($info['function'])) {
        if (!function_exists($info['function'])) {
          throw new \BadFunctionCallException(sprintf(
          'Theme hook "%s" refers to a theme function callback that does not exist: "%s"',
          $hook,
          $info['function']
          ));
        }
      }
      // Provide a default naming convention for 'template' based on the
      // hook used. If the template does not exist, the theme engine used
      // should throw an exception at runtime when attempting to include
      // the template file.
      elseif (!isset($info['template'])) {
        $info['template'] = strtr($hook, '_', '-');
        $result[$hook]['template'] = $info['template'];
      }
 
      // Prepend the current theming path when none is set. This is required
      // for the default theme engine to know where the template lives.
      if (isset($result[$hook]['template']) && !isset($info['path'])) {
        $result[$hook]['path'] = $path . '/templates';
      }
 
      // If the default keys are not set, use the default values registered
      // by the module.
      if (isset($cache[$hook])) {
        $result[$hook] += array_intersect_key($cache[$hook], $hook_defaults);
      }
 
      // Preprocess variables for all theming hooks, whether the hook is
      // implemented as a template or as a function. Ensure they are arrays.
      if (!isset($info['preprocess functions']) || !is_array($info['preprocess functions'])) {
        $info['preprocess functions'] = array();
        $prefixes = array();
        if ($type == 'module') {
          // Default variable preprocessor prefix.
          $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') {
          // Theme engines get an extra set that come before the normally
          // named variable preprocessors.
          $prefixes[] = $name . '_engine';
          // The theme engine registers on behalf of the theme using the
          // theme's name.
          $prefixes[] = $theme;
        }
        else {
          // This applies when the theme manually registers their own variable
          // preprocessors.
          $prefixes[] = $name;
        }
        foreach ($prefixes as $prefix) {
          // Only use non-hook-specific variable preprocessors for theming
          // hooks implemented as templates. See the @defgroup themeable
          // topic.
          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;
          }
        }
      }
      // Check for the override flag and prevent the cached variable
      // preprocessors from being used. This allows themes or theme engines
      // to remove variable preprocessors set earlier in the registry build.
      if (!empty($info['override preprocess functions'])) {
        // Flag not needed inside the registry.
        unset($result[$hook]['override preprocess functions']);
      }
      elseif (isset($cache[$hook]['preprocess functions']) && is_array($cache[$hook]['preprocess functions'])) {
        $info['preprocess functions'] = array_merge($cache[$hook]['preprocess functions'], $info['preprocess functions']);
      }
      $result[$hook]['preprocess functions'] = $info['preprocess functions'];
    }
 
    // Merge the newly created theme hooks into the existing cache.
    $cache = $result + $cache;
  }
 
  // Let themes have variable preprocessors even if they didn't register a
  // template.
  if ($type == 'theme' || $type == 'base_theme') {
    foreach ($cache as $hook => $info) {
      // Check only if not registered by the theme or engine.
      if (empty($result[$hook])) {
        if (!isset($info['preprocess functions'])) {
          $cache[$hook]['preprocess functions'] = array();
        }
        // Only use non-hook-specific variable preprocessors for theme hooks
        // implemented as templates. See the @defgroup themeable topic.
        if (isset($info['template']) && function_exists($name . '_preprocess')) {
          $cache[$hook]['preprocess functions'][] = $name . '_preprocess';
        }
        if (function_exists($name . '_preprocess_' . $hook)) {
          $cache[$hook]['preprocess functions'][] = $name . '_preprocess_' . $hook;
          $cache[$hook]['theme path'] = $path;
        }
      }
    }
  }
}
doc_Drupal
2025-01-10 15:47:30
Comments
Leave a Comment

Please login to continue.