8.5.x Registry.php Registry::build()
8.0.x Registry.php Registry::build()
8.1.x Registry.php Registry::build()
8.2.x Registry.php Registry::build()
8.3.x Registry.php Registry::build()
8.4.x Registry.php Registry::build()
8.6.x Registry.php 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

\Drupal\Core\Utility\ThemeRegistry The build theme registry.

See also



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


Defines the theme registry service.




protected function build() {
  $cache = array();

  // 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 {
    foreach ($this->moduleHandler
      ->getImplementations('theme') as $module) {
        ->processExtension($cache, $module, 'module', $module, $this

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

  // 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
    ->getBaseThemes()) as $base) {

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

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

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

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

  // Let modules and themes alter the registry.
    ->alter('theme_registry', $cache);
    ->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']);
    ->getName()] = $cache;
  return $this->registry[$this->theme