Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
suggested commit message:
Issue #2329795 by fietserwin, bzitzow, alexrayu, tstoeckler | illutek, dawehner: Fixed Make it possible to add information to theme info files during development.
Since the other issue had first (but partial fix) merged the users involved.
Problem/Motivation
All the information stored in $theme.info.yml files is not changeable at all once a theme is enabled/installed. We need to ensure that we somehow store the two states: system.theme.data and the active theme object.
Proposed resolution
use addTheme()
Remaining tasks
- (done) tests added
- (done) review
User interface changes
No.
API changes
Comment | File | Size | Author |
---|---|---|---|
#8 | 2329795-6-theme-state.patch | 6.97 KB | tstoeckler |
#5 | 2329795-6-theme-state-fail.patch | 10.86 KB | tstoeckler |
Comments
Comment #1
dawehnerYou need for example the following snipped.
Comment #2
tstoecklerWith this patch I can add stuff like libraries to my theme run
drush cr
and have them be detected by the system.If this gets in, it definitely needs to be mentioned on https://www.drupal.org/drupal-8.0 : Drupal 8 will allow you to add JavaScript and CSS from your theme!!! I wish I could have that feature when working on D7 sites right now. Oh wait...............
Comment #3
tstoecklerTo add some context for those following along at home:
When you enable a theme, the contents of its info file are cached in state and read from there on every request. The bad part is that this state entry is never ever cleared or re-built in any way. That means that you can add JS/CSS/libraries to your theme and put them in your info file, but they will never ever be loaded, because they are not in the state entry.
The sucker that is responsible for this is ThemeInitialization::getActiveThemeByName(). As you can see, as soon as the state entry exists it always early returns and never re-builds it. This function is also the only place in core that state entry is referenced at all.
Surely it would be nice to put the clearing of this state entry somewhere more semantic that
drupal_
"Sledgehammer"_flush_all_caches()
, but this at least works and gets the critical out of the way. I briefly discussed this with @dawehner and there's really no sane place (else) to put it. If we want things to be nice and shiny we probably have to refactor the theme system a fair bit.Comment #4
dawehnerIs there any proper way to test this? You would have to alter the
theme.info.yml
file, but I can't see how we can actually add modules in the files directory? Do we have to trust us here?Comment #5
tstoecklerSure, here we go.
Some notes:
- I had to change
DefaultNegotiator
(the event listener that determines the active theme by asking the default theme stored in config) to inject the config factory instead of the config object directly, otherwise it will not react to changes of the active theme in the same request.- I fixed a really nasty bug in
ThemeHandler::refreshInfo()
where it was writing to$this->list
directly instead of using$this->addTheme()
. That doesn't properly set the$theme->libraries
, etc. properties properly, so that the library added for the test still wasn't being found even though it was in$theme->info['libraries']
. This doesn't show up as a bug on actual sites, because it only affects the rest of the request afterrefreshInfo()
was called. On the next request the themes will be added properly withaddTheme()
. (Yes, the fact that we have both$theme->info['libraries']
and$theme->libraries
and they are synced only at one very specific place in code is insane (as is also mentioned in the code), but that's not for this issue to fix)Comment #7
dawehnerYeah never execute anything in the constructor phase, it is simple as that.
Nice!
Comment #8
tstoecklerAhh, just realized that I forgot "-C -M" in the diff, sorry for that. Here's the exact same patch with that.
Comment #9
star-szrAwesome, it sounds like this is a proper fix + test for #2273769: Theme .info.yml file changes are not picked up even after clearing cache or running rebuild.php!
Comment #10
tstoecklerAhh, thanks for referencing that, I wasn't aware of that issue.
Comment #11
YesCT CreditAttribution: YesCT commentedadded a suggested commit message to summary in case committer wants to merge the people involved in the two issues.
(also gave the patch a read and it looks ok to me)
Comment #12
YesCT CreditAttribution: YesCT commentedComment #14
catchSo this doesn't feel like the ideal fix, but #2235901: Remove custom theme settings from *.info.yml is also going to touch this code and getting the critical bug fixed with test coverage should help with the refactor.
Committed/pushed to 8.0.x, thanks!