Same name and namespace in other branches
  1. 8.9.x core/lib/Drupal/Core/Theme/Registry.php \Drupal\Core\Theme\Registry::build()
  2. 9 core/lib/Drupal/Core/Theme/Registry.php \Drupal\Core\Theme\Registry::build()

Builds the theme registry cache.

Theme hook definitions are collected in the following order:

  • Modules
  • Base theme engines
  • Base themes
  • Theme engine
  • Theme

All theme hook definitions are essentially just collated and merged in the above order. However, various extension-specific default values and customizations are required; e.g., to record the effective file path for theme template. Therefore, this method first collects all extensions per type, and then dispatches the processing for each extension to processExtension().

After completing the collection, modules are allowed to alter it. Lastly, any derived and incomplete theme hook definitions that are hook suggestions for base hooks (e.g., 'block__node' for the base hook 'block') need to be determined based on the full registry and classified as 'base hook'.

See the Default theme implementations topic for details.

Return value

array The built theme registry.

See also

hook_theme_registry_alter()

1 call to Registry::build()
Registry::get in core/lib/Drupal/Core/Theme/Registry.php
Returns the complete theme registry from cache or rebuilds it.

File

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

Class

Registry
Defines the theme registry service.

Namespace

Drupal\Core\Theme

Code

protected function build() {
  $cache = [];

  // First, preprocess the theme hooks advertised by modules. This will
  // serve as the basic registry. Since the list of enabled modules is the
  // same regardless of the theme used, this is cached in its own entry to
  // save building it for every theme.
  if ($cached = $this->cache
    ->get('theme_registry:build:modules')) {
    $cache = $cached->data;
  }
  else {
    $this->moduleHandler
      ->invokeAllWith('theme', function (callable $callback, string $module) use (&$cache) {
      $this
        ->processExtension($cache, $module, 'module', $module, $this->moduleList
        ->getPath($module));
    });

    // Only cache this registry if all modules are loaded.
    if ($this->moduleHandler
      ->isLoaded()) {
      $this->cache
        ->set("theme_registry:build:modules", $cache);
    }
  }

  // Process each base theme.
  // Ensure that we start with the root of the parents, so that both CSS files
  // and preprocess functions comes first.
  foreach (array_reverse($this->theme
    ->getBaseThemeExtensions()) as $base) {

    // If the base theme uses a theme engine, process its hooks.
    $base_path = $base
      ->getPath();
    if ($this->theme
      ->getEngine()) {
      $this
        ->processExtension($cache, $this->theme
        ->getEngine(), 'base_theme_engine', $base
        ->getName(), $base_path);
    }
    $this
      ->processExtension($cache, $base
      ->getName(), 'base_theme', $base
      ->getName(), $base_path);
  }

  // And then the same thing, but for the theme.
  if ($this->theme
    ->getEngine()) {
    $this
      ->processExtension($cache, $this->theme
      ->getEngine(), 'theme_engine', $this->theme
      ->getName(), $this->theme
      ->getPath());
  }

  // Hooks provided by the theme itself.
  $this
    ->processExtension($cache, $this->theme
    ->getName(), 'theme', $this->theme
    ->getName(), $this->theme
    ->getPath());

  // Discover and add all preprocess functions for theme hook suggestions.
  $this
    ->postProcessExtension($cache, $this->theme);

  // Let modules and themes alter the registry.
  $this->moduleHandler
    ->alter('theme_registry', $cache);
  $this->themeManager
    ->alterForTheme($this->theme, 'theme_registry', $cache);

  // @todo Implement more reduction of the theme registry entry.
  // Optimize the registry to not have empty arrays for functions.
  foreach ($cache as $hook => $info) {
    if (empty($info['preprocess functions'])) {
      unset($cache[$hook]['preprocess functions']);
    }
  }
  $this->registry[$this->theme
    ->getName()] = $cache;
  return $this->registry[$this->theme
    ->getName()];
}