Drupal\Core\Theme\Registry usually works like this:

  • In the constructor, $theme_name is NULL.
  • When first needed, Registry->init() is called with $this->themeName, which at this time is NULL.
  • This fills $this->theme with the current theme, whereas $this->themeName is still NULL.
  • Later, $this->registry[$this->theme->getName()] may be filled with theme registry entries for the current theme.
  • Later, $this->runtimeRegistry[$this->theme->getName()] may be filled with the runtime registry for the current theme.
  • There is no situation where $this->theme or $this->themeName or the result of $this->theme->getName() would be changed after its first initialization.
    (at least I found none)
    And if it would happen, it would probably break things.

Proposed change

We should remove all artifacts that suggest that Theme\Registry would support more than one theme:

  • $this->registry[$theme_name] becomes $this->registry.
  • $this->runtimeRegistry[$theme_name] becomes $this->runtimeRegistry.
  • $this->themeName should be initialized in $this->init().
  • The parameter $theme_name in $this->init() is redundant, and should be removed.

Follow-up

In a follow-up issue, we could make a proxy split, like so:

One class where $theme_name and $theme object are passed into the constructor.
This will contain most of the logic.
In this class we no longer need to worry about whether it has been initialized or not.

Another class which acts as a proxy layer, and which lazily creates the "real thing" when it is needed.

Comments

donquixote created an issue. See original summary.

donquixote’s picture

Issue summary: View changes
donquixote’s picture

Status: Active » Needs review
StatusFileSize
new10.05 KB

Let's see if this breaks anything.

Locally this is a branch with various distinct commits:

* 9af751c (HEAD -> Theme-Registry-2957451-8.6.x) Issue #2869859: Stop pretending that Theme\Registry is for more than one theme.
* f6079ee (CS+) Initialize Registry->runtimeCache so that it is never NULL.
* ea601c9 (CS) Split arguments to multiple lines.
* 656110d (CS) Break constructor arguments to multiple lines.
* 6fde882 (CS) Document that Registry->runtimeCache can be NULL.
* 0695b1b (CS) Add inline @var doc for result of array_reverse().
* 7344691 (CS+) Use === when comparing with strings.
* d00af06 (CS+) Add third parameter TRUE in in_array().
* f8676ba (CS+) Use str_replace() instead of strtr().
* c28df38 (CS) Use single quotes.
* f45028b (CS+) Add (previously undeclared) property Theme\Registry::$themeInitialization.

EDIT: This will fail.

Status: Needs review » Needs work

The last submitted patch, 3: D8-2957451-3-Theme-Registry.patch, failed testing. View results

donquixote’s picture

Status: Needs work » Needs review
StatusFileSize
new13.05 KB

In #3 I forgot half of the required changes.
Trying again.

donquixote’s picture

StatusFileSize
new13.94 KB

The last submitted patch, 5: D8-2957451-5-Theme-Registry.patch, failed testing. View results

donquixote’s picture

StatusFileSize
new8.05 KB

Trying a patch which has only the CS changes and not the functional changes.

The last submitted patch, 6: D8-2957451-6-Theme-Registry.patch, failed testing. View results

donquixote’s picture

I just notice that Registry->initialized is never set to TRUE in init()!!
Ouch.
This is a bug in 8.6.x.

donquixote’s picture

I just notice that Registry->initialized is never set to TRUE in init()!!

The effect is:
Every call To ThemeManager->render() calls Registry->getRuntime()
which calls Registry->init()
which calls Registry->themeManager->getActiveTheme()

This means that, as soon as themeManager->activeTheme changes, ThemeManager->render() will render in the new active theme.
We could say this is great, it means theming functionality is always up to date.
But at what cost?
We repeat the same redundant operation each time we execute a theme hook. This is not right.

donquixote’s picture

Testing my hypothesis about ->initialized.

The last submitted patch, 12: D8-2957451-12-TEST-initialized-true.patch, failed testing. View results

donquixote’s picture

#12/#13 shows:

  • Drupal\Core\Theme\Registry::$initialized always stays FALSE.
  • The check for $this->initialized in Registry::init() is pointless.
  • In the current implementation, Registry must call $this->themeManager->getActiveTheme() repeatedly.
    We can assume that this has a performance impact.
donquixote’s picture

Some clarification:

The problem here is NOT the "theme system" itself with its "theme hooks", which some consider archaic and want to modernize.
You can think what you want about this, but it is not the problem here.

The real problem here is how different components deal with the possibility that the "active theme" can change mid-request.
So, it is a question of how information and state travels in our architecture, the order in which stuff happens in bootstrap, how per-theme logic is organized.

This needs to be cleaned up, no matter if we switch to plugins or whatever else has been suggested afterwards.

donquixote’s picture

Status: Needs review » Active

This issue is not "Needs review". The patches were just to see what would happen.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

andypost’s picture

There's a case when at least 2 themes are required - when you collect layouts from frontend (default theme) to display them as list at "manage display" pages (in admin theme)

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.