Problem
Components! fails to discover templates from the primary theme when "use admin theme" is enabled and admin theme is active.
For example, when editing a view that displays rendered content.
Proposed Resolution
During namespace resolution and template discovery, include both the admin theme and primary theme.
Remaining tasks
Update discovery mechanism in Components RegistryReviewsTests- Change record (is this necessary for beta releases?)
User interface changes
none
API changes
ConfigFactoryInterface
argument added to Drupal\components\Template\ComponentsRegistry
constructor and service definition.
Data model changes
none
Symptom
Fatal errors like
Twig\Error\LoaderError: Template "@organisms/header-top/header-top.twig" is not defined in "themes/custom/aedt_theme/src/templates/layout/region--header-top.html.twig" at line 9. in Twig\Loader\ChainLoader->getCacheKey() (line 142 of vendor/twig/twig/src/Loader/ChainLoader.php).
Steps to reproduce
- Define a component namespace in your theme
- Create a page template that embeds another component using that namespace
- Login as a user with permission to view the admin theme (but not user 1)
- Setup a custom 403 page
- Edit a node you don't have permission to edit
Expected behavior
View the 403 page.
Observed behavior
Fatal error described above.
This issue persists even after the component definition has been updated with the 3.x API changes.
Here's an example component library definition:
components:
namespaces:
organisms:
- src/_patterns/03-organisms
And this is how the region--header-top.html.twig file looks like:
{% if content %}
{% include '@organisms/header-top/header-top.twig' with {
'content': content,
'attributes': attributes
} %}
{% endif %}
Comment | File | Size | Author |
---|---|---|---|
#45 | components-template_undefined_on_admin_pages-3107993-45.patch | 3.54 KB | dgroene |
Issue fork components-3107993
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
capysara CreditAttribution: capysara at Bounteous commentedNot related to this specific module, but adding directory and path to the include statement as noted here worked for me: https://www.drupal.org/project/drupal/issues/2817553#comment-13820148
Comment #3
tobiberlinI found the same error - everything worked before the update but for me it was the update from Drupal core 8.9.3 to 8.9.6 or the update from Components version 1 to version 2... I am not sure yet because I did these updates in parallel.
The solution from the linked comment is not really a solution as the idea of the "'@organisms/header-top/header-top.twig'" syntax is that it is working independently from the current twig template files location.
Comment #4
tobiberlinFor me I found a solution: The component was defined in a theme but the template file which used the component was defined in a module. This module's template file was rendered within another theme. When I moved the component definition and the component files to the module everything worked. Strange that this worked before...
Comment #5
JohnAlbinThere's not enough information for me to figure out what is going on.
Comment #6
JohnAlbinI'm closing this since I don't have enough details (like directory paths) to help solve this issue.
Please re-open if you want to provide more details.
Comment #7
garypigott39 CreditAttribution: garypigott39 as a volunteer commentedOk so we also had this issue; the scenario we had was we were using several themes including the emulsify theme where we had a definition for assorted namespaces. Now these werent being picked up in Node edit and we received the aforementioned template not found error.
Looking at the ComponentsLoader class we could see that setActiveTheme() was loading all module based namespaces but was ignoring any theme names identified by `$theme_info = $this->componentsInfo->getAllThemeInfo();` the solution for us was to add the following just after the theme_info variable was set
This then ensured that the namespaces were picked up.
The other alternative which also worked for us was to add the namespaces to any module's info file.
This was in version 8.2.4 of the module
Comment #8
larowlanAdded steps to reproduce into the issue summary
Hit this when updating from 8.9.16 to 9.2.0 and from components 1 to 2
Comment #9
larowlanReclassifying this as a bug report for now, as it definitely relates to active theme switching mid request
Comment #10
larowlanLooking at core, there's been no changes to ThemeManager's handling of setting/resetting active theme since 2015
Comment #11
ipwa CreditAttribution: ipwa at manifesto commentedI was getting the following error:
Twig\Error\LoaderError: Template "@molecules/announcement/_announcement.html.twig" is not defined in "modules/custom/announcement/templates/announcement.html.twig" at line 19. in Twig\Loader\ChainLoader->getCacheKey() (line 142 of /var/www/html/vendor/twig/twig/src/Loader/ChainLoader.php).
Same sort of situation:
The patch in #7 fixed things for me, thanks Gary!
Comment #12
JohnAlbinHuh. I tried to delay the check of the active theme until the very last moment because I knew Drupal switches active theme mid-request sometimes. But it seems it still wasn't enough? Maybe this is a core bug too? Regardless if its a core bug, we'll add a work-around in this module for the issue.
Lee, thanks for helping me to recreate the issue.
I'll try to take a look at this issue in more detail in the next week.
Comment #13
larowlanThanks John
I found another way to replicate this, but its probably my fault.
I've got a module, which has a twig template that references a template from the theme, via the theme namespace.
I've got paragraphs setup on the edit for using a preview-view mode to show a preview of the item before editing.
This invokes the template from the module, which tries to load the theme namespace. But the theme isn't active because I'm editing a node, so its using the admin theme.
Probably falls under 'you're doing it wrong' but might make it easier to reproduce for testing sake.
Comment #14
larowlanFor others in the same misfit boat as my description above, just referring to the theme namespace from the profile info file and setting the protection flag in the them was enough to resolve this default vs admin theme issue (albeit by hacking around it)
Comment #15
Kasey_MK CreditAttribution: Kasey_MK commentedThank you, #7 worked for us too. We fiddled a lot with the components namespaces syntax in our theme info.yml and in our twig files but nothing was working after upgrading to Components 2 on 8.9.16
Comment #17
pixelwhip CreditAttribution: pixelwhip commentedI was running into this error using Layout Paragraphs in conjunction with UI Patterns and the Components module. I would get this error when editing a node using the admin theme that contained content in the form of Paragraphs that were themed with UI Patterns which were defined in the front-end theme where they referenced a template via a component namespace also defined in the front-end theme.
The patch from the above merge request resolved the issue for me. https://git.drupalcode.org/project/components/-/merge_requests/28.patch
Comment #18
JohnAlbinSo, the patch in #7 breaks tests.
Specifically, the patch casually merges all theme namespaces into the namespaces of the active theme (or at least what Drupal is reporting as the active theme). That behavior is potentially a regression for the following issues: #3027672: Any other theme can override the active theme's component-libraries, #3080827: Base and sub theme hierarchy is not taken into account
The tests aren't particularly good in 8.x-2.x (they were refactored in 3.x), but they are sufficient to show that the failing test expects that only the namespaces defined by the active theme, its base themes and modules are to be available. The active theme should not be allowed to use namespaces of some random other theme that is not in its base theme lists.
As I said in another issue: "its weird that a theme could define a dependency on another theme that is not in its base theme list and that the theme would define that dependency deep inside a Twig template and not in the .info.yml and .libraries.yml files where all the other dependencies are defined." I stand by that statement. Letting a theme have a hidden dependency is a really bad idea.
However, as previous comments have shown, we need to make an exception for the admin theme; it should be allowed to see the namespaces of the default theme. We should also consider if the admin theme will be allowed to see the namespaces of all installed themes. I'm not sure. I'd lean towards "no", but I'd listen to counter arguments.
So, as I understand the issue now, the proper fix for this issue would be for the admin theme to have the default theme's namespaces be available.
Comment #19
JohnAlbinConsidering this affects core modules like layout builder (when the admin theme is active for the edit layout page and the layout components are in the frontend theme), this is kind of a big deal. Bumping the priority.
Comment #20
zezeze CreditAttribution: zezeze commentedI believe I have an issue related to this. We just updated our Drupal core to 9.2.7 from 8.9.2 and we are using Components 8.x-2.4.
My components are located in root/vendor/cfaes/cfaes-components and the components declaration is:
Many of my custom modules use the @cfaesComponents namespace with no problem and if a view template (in a custom module) is utilizing a component from the theme I can see it rendered in the view as well as the view preview.
However after the upgrade to 9.2.7 my custom modules that utilize my theme's components in overridden views templates fail to render in the view preview (but still render when viewing the page where the view is being used).
When editing a display in a view I get the following error:
Note: After reading #4 I took the same component definition from the theme and placed it in the custom module as well and boom, the view preview works. Is this how it should be (I swear before the update my view previews were able to sort out where the components were).
Comment #21
ctrlADelThe use case that brings me here is an outlier I'm sure, I have a custom layout deriver that creates layouts based on json definitions which contain namespaced template paths. I noticed recently that after a cache rebuild if the first page I hit is an admin page then an error is thrown when trying to access the front end
Twig\Error\LoaderError: Template "modules/custom/custom_layouts/@templates/section/two/two-column.html.twig" is not defined.
but if a frontend page is hit first after cache clear then everything works fine.I think the capability to merge all installed theme namespaces into the admin theme needs to at least be possible if not on by default. While most sites will have just one default theme the active theme is negotiated by ThemeNegotiators and can change dynamically when one is implemented. In the situations where more than one theme is in use a disclaimer/note that the site is responsible for avoiding namespace collisions seems fine.
Comment #22
tjh CreditAttribution: tjh at Agile Six Applications for Department of Veterans Affairs commentedRunning into this while using Components and a custom theme that is extending Claro. This theme is acting as both the admin & default theme, so it handles admin routes as well as node view pages for proofing content. The actual front end of the website is decoupled.
Drupal version: 9.3.9
Components version: 2.4
My component templates are available at
themename/dist/components/
e.g.themename/dist/components/alert/alert.twig
My themename.info.yml file:
Referencing a component in a theme template (
status-messages.html.twig
):It also fails if I reference the complete path to the template, e.g.
@cmds/alert/alert.twig
Error:
The namespace is not defined for either admin or regular routes. Expected behavior would be that the namespace defined by theme & used only in that theme's templates would be available regardless of admin/default theme. It is both and yet namespace is undefined for either.
Can also the confirm that the patch in #7 did not work for my use case. Nor did moving the components namespace to a module .info.yml instead of the theme.
Edit: Also tried Components version: ^3.0@beta and the same error is present
Comment #23
tjh CreditAttribution: tjh at Agile Six Applications for Department of Veterans Affairs commentedFollow up to my last comment... I forgot to enable the module! Ha! I added to composer but never ran `drush en components` afterwards.... Doing that, it works as expected with admin themes and 3.0@beta . Very silly mistake on my part. Thanks for the excellent module!
Comment #24
JohnAlbinSo I dug into the code. In both 8.x-2.x and 3.x, the Components module simply reads the current theme using
\Drupal\Core\Theme\ThemeManager->getActiveTheme()
and the internals of that method are using\Drupal\Core\Theme\ThemeNegotiator
. So it feels like the Components module is doing things "the right way". But obviously, it's failing to see the active theme has changed when inside a subrequest.Does a subrequest not tell the ThemeManager that the active theme has changed? Or is there a different ThemeManager inside the subrequest?
Right now, Components module gets the ThemeManager via dependency injection. Do I need to grab the ThemeManager from
\Drupal::service('theme.manager')
instead?I'm not sure when I'll get to test this theory, but I'll post back once I have. Unless someone beats me to it. :D
Comment #25
Kris77 CreditAttribution: Kris77 commentedPatch #7 is not applicable with last 3.0@beta.
Comment #26
AaronBaumanIssue persists into 3.x, and neither existing patch nor MR apply.
Not sure how to reroll, because it seems to have been entirely rewritten.
Comment #27
AaronBaumanAny updates here?
Comment #28
AaronBauman@JohnAlbin I don't think grabbing theme manager from
\Drupal::service()
will make a differenceThemeManager
is instantiated at the beginning of the request, and itsdefaultTheme
property is statically initialized only once.So in order to get the proper theme on a sub-request, we need to re-instantiate Drupal's
ThemeManager
service every time prior to callinggetActiveTheme()
.IMO this seems like a terrible waste of resources, and worthy of a fix in core, if this is indeed what's happening.
In my case - views preview of rendered content - I don't think a sub-request is involved.
A view is edited using admin theme, and views preview attempts to render the preview in admin theme.
But to render the entity we need a template defined in the default / non-admin theme, which is not available and thus the error.
Comment #30
AaronBaumanOpened new MR against 3.x https://git.drupalcode.org/project/components/-/merge_requests/32
First commit is test only, to demonstrate the issue.
Subsequently, I will update with the patch that's working for me.
Comment #31
AaronBaumanOK, so comment #28 TEST ONLY demonstrates the bug.
And the MR addresses the bug thusly:
- If a given template is not found in the current active theme, and the active theme is not the default theme, also check the default theme.
This change requires adding
ConfigFactory
to dependencies, so that we can grab the active theme.If we think it's better to check ALL enabled themes, we could do that through
ThemeExtensionList
without adding any new dependencies.Comment #32
ironsizide CreditAttribution: ironsizide at Message Agency commentedThe fixes in MR 32 are working for me nicely in Drupal 9.5.9.
Comment #33
sanoopuio CreditAttribution: sanoopuio commentedI get this error on 3.0.0-beta3, not sure how to continue
Comment #34
Sana.Neyazi CreditAttribution: Sana.Neyazi commentedHi @aronbauman, Could we know when we can expect Drupal 10 stable release of
component
module?Comment #35
AaronBaumanNo commits on this project and no comments from maintainers for over a year 😬
Dunno what's happening but that's not a good sign.
Comment #36
Yujiman85 CreditAttribution: Yujiman85 at Zivtech commentedI had the same issue with templates not being defined in Twigs using "extends" after the update to the latest version. It seems I was able to fix the situation by updating the namespaces in the info.yml file for my custom theme from the old API to the new one as per https://www.drupal.org/docs/contributed-modules/components/registering-twig-namespaces. Not sure if this will work for anyone else but worth a shot if your situation is at all similar.
Old:
New:
So far I haven't run into any breaking issues but if I do I'll come back to update
Comment #37
sanoopuio CreditAttribution: sanoopuio commentedThanks for hint, it works . https://www.drupal.org/docs/contributed-modules/components/registering-t...
# This example YAML creates 3 namespaces: @atoms, @quarks, @universe
Comment #38
Abhinand Gokhala K CreditAttribution: Abhinand Gokhala K as a volunteer and at Billit Corp. for Billit Corp. commentedSolution #36 worked for me. Thanks.
Comment #39
thallesWorks fine to me!
Comment #40
Yujiman85 CreditAttribution: Yujiman85 at Zivtech commentedSince this technically works like it's supposed to after changing how the namespaces are structured, I'm going to move this over to "Closed (works as designed)". If that isn't right someone please move it back. The documentation for the API is there but it's two clicks deep from the module page, maybe there could be a more noticeable section highlighting how to structure the namespaces? Especially now since the old way doesn't seem to work after moving to v3.
Comment #41
AaronBaumanI don't think this should be closed, as this issue persists even for themes whose namespace definitions have been update for the new API.
This is not a problem with implementations, this is a problem with Components! module's discovery system.
The current MR includes a test to demonstrate the bug per comment #28, as well as a resolution for it.
Issue summary updated and set back to RTBC
Comment #42
kekkisRTBC +1. Created a local patch from MR in #28 and it fixes our problem which is exactly what the test describes.
Comment #43
dgroene CreditAttribution: dgroene at The College Board commentedPlease ignore- did not realize the merge request was already against 3.x... and I cannot delete the file now...
Comment #44
dgroene CreditAttribution: dgroene at The College Board commentedComment #45
dgroene CreditAttribution: dgroene at The College Board commentedPatch from MR 32, without the testing changes
Comment #47
dgroene CreditAttribution: dgroene at The College Board commentedComment #48
raywalters CreditAttribution: raywalters at Palantir.net commentedApplying the merge request patch in this issue along with the merge request from https://www.drupal.org/project/ui_patterns/issues/3335833 for ui patterns resolved my issue.
Twig\Error\LoaderError: Template "modules/contrib/ui_patterns/templates/pattern-teaser.html.twig" is not defined. in Twig\Loader\ChainLoader->getCacheKey() (line 10 of /var/www/html/docroot/modules/contrib/ds/templates/ds-entity-view.html.twig).