Problem/Motivation
Incorrect theme is loaded on admin paths when critical_css is enabled.
Steps to reproduce
Set seven or any theme as admin theme and particle or any other theme as default theme. Enable critical_css and go to admin pages and you will notice the your default theme is loading instead of your admin theme.
Proposed resolution
Prevent Drupal\Core\Theme\ThemeManager->getActiveTheme() from being called too early.
| Comment | File | Size | Author |
|---|
Issue fork components-3165589
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
majid.ali commentedComment #3
johnalbinLooking at the current code in the critical_css module, it disables itself on admin pages. https://git.drupalcode.org/project/critical_css/-/blob/8.x-1.x/src/Asset...
So I don't think the issue description is accurate.
Comment #4
evaldas.uzkurasThe problem is that
Drupal\components\Template\Loader\ComponentsLoadercallsDrupal\Core\Theme\ThemeManager->getActiveTheme()too early and\Drupal\user\Theme\AdminNegotiatorcan't correctly determine admin theme because correct RouteMatch is not set yet.The issue is caused by critical_css because it decorates `asset.css.collection_renderer` service (https://git.drupalcode.org/project/critical_css/-/blob/8.x-1.x/critical_...) and adds twig service as dependency, which later constructs `components.twig.loader` service.
`asset.css.collection_renderer` is used by `ajax_response.attachments_processor` which is used by `ajax_response.subscriber`;
The correct RouteMatch is set by `router_listener`, which has smaller priority than `ajax_response.subscriber`, and is called later (while the active theme is already set)
For this reason we get incorrect theme
Attached a screenshot to display whole chain of services involved.

Comment #5
johnalbinThanks, Evaldas! That's super helpful info.
I think this is exactly the cause of the bug.
I looked at how Drupal core's
ThemeRegistryLoaderworks in detail and it causesDrupal\Core\Theme\ThemeManager->getActiveTheme()to be called too, but it doesn't do so during its constructor. It only triggers that method inThemeRegistryLoader::findTemplate(). We should do the same inComponentsLoader.This bug exists in both 3.x and 8.x-2.x.
Comment #7
johnalbinComment #8
johnalbinFixed in 3.x.
Comment #9
johnalbinThis needs to be backported to 8.x-2.x.
Comment #11
johnalbinComment #13
johnalbinEvaldas and Majid,
Can you check out the latest code on the 8.x-2.x branch and see if that fixes the bug? I haven't tested my fix against the critical_css module.
If the bug is fixed, I can make a new 8.x-2.2 release with the bugfix.
Comment #14
evaldas.uzkurasJohn,
2.x still not work correctly.
There is one more part that calls getActiveTheme (introduced with #3191968: Add alter hook for protected Twig namespaces in 2.1.0)
Drupal\components\Template\ComponentsInfois calling alter for ThemeManager on construct ($themeManager->alter('protected_twig_namespaces', $this->protectedNamespaces)) which is calling getActiveTheme.Comment #15
johnalbin*sigh* ok. Thanks for the new info! It really helps a lot.
So we'll need to add an initialization flag to
ComponentsInfoand not init() the namespaces data untilComponentsLoader::findTemplate()is called.Comment #18
johnalbinComment #20
johnalbinComment #22
johnalbinComment #24
johnalbinOk. One more time.
Can you check out the latest code on the 8.x-2.x branch and see if that fixes the bug?
If the bug is fixed, I can make a new 8.x-2.2 release with the bugfix.
Comment #25
evaldas.uzkurasIt's perfect now, the correct admin theme is activated.
Comment #26
johnalbinThanks for all your help, Evaldas!
https://www.drupal.org/project/components/releases/8.x-2.2