Problem/Motivation
If a theme hasn't provided base theme setting, the theme will currently fallback to extending stable
. This works when there's only one version of stable
. However, in Drupal 9, there will be multiple stable versions (Drupal 8 stable aka stable
and Drupal 9 stable aka stable9
).
When Drupal 9 ships, we can choose to either either:
- move Drupal 8's Stable (
stable
) to contrib and a new Stable theme (stable9
) to core - keep Drupal 8's Stable (
stable
) in core and add a new Stable theme (stable9
to core
This decision doesn't need to be made in this issue.
In either scenario, themes must explicitly define which version of the Stable theme it wants to extend, by specifying either base theme: stable
or base theme: stable9
.
Note 1: this solution will also work for Drupal 10! 🥳
Note 2: we could choose to alias stable
to stable8
for consistency. But this would merely be a cosmetic nice-to-have.
Proposed resolution
Deprecate the option to omit the base theme
property in theme *.info.yml
files. Provide warning for themes that haven't configured their base theme and provide them with instructions that if they want their theme behavior remain the same in Drupal 9, they would have to add base theme: stable
.
In Drupal 9, the base theme
property will be required.
Remaining tasks
Consensus on approach.See #6 + #7.- Agree on naming: does Drupal 8's "Stable" theme keep the
stable
name or do we addstable8
as an alias, for consistency with future Drupal versions'stable9
,stable10
, et cetera? Green patch.See #38 (complicated update toBaseThemeDefaultDeprecationTest
) + #41 (removesBaseThemeDefaultDeprecationTest
)- Decide whether we want to extract "app root"-related changes to a separate issue — see #40. That'd make this patch more tightly scoped.
- RTBC.
- Commit.
User interface changes
None.
API changes
base theme
is no longer an optional property in a theme *.info.yml
file. Change record: https://www.drupal.org/node/3066038
Data model changes
None.
Release notes snippet
In Drupal 8, if a theme does not specify a base them, Stable is chosen as the base theme automatically. Starting with Drupal 9, a new stable base theme will be added to each major version with the latest markup from modules, and the old stable base theme will be deprecated. To facilitate this and avoid unintended regressions, the automatic fallback is deprecated and the base theme
property will be required starting with Drupal 9.0.0. To remain compatible with Drupal 9, themes that use Stable as their base theme should explicitly add this to their info files. See the change record on requiring the base theme
property for examples.
Comment | File | Size | Author |
---|---|---|---|
#53 | 3065545-53.patch | 28.47 KB | Wim Leers |
#53 | interdiff.txt | 5.66 KB | Wim Leers |
#51 | 3065545-51.patch | 28.29 KB | Wim Leers |
#51 | interdiff.txt | 2.12 KB | Wim Leers |
#50 | 3065545-50.patch | 26.98 KB | Wim Leers |
Comments
Comment #2
lauriiiComment #3
lauriiiComment #4
Wim LeersSo, in a nutshell, we need to make this work. I'll take this on.
Let's see what fails 🤓 Hopefully a lot.
Comment #5
Wim Leers3540 failures, excellent! (I guess the sheer number of failures causes DrupalCI to not report this back for some reason?)
Comment #6
Wim LeersFirst, working to understand the intent and scope of the issue here. This requires me to analyze the problem/motivation section, which currently reads like this:
Let's break this down to help us get on a path to consensus.
I think some of what is said here is impossible because Drupal currently does not support having multiple versions of a theme in a single Drupal installation. In other words: you can't have two
foo
themes with different versions.Therefore this option is currently impossible:
Unless that means that "Drupal 9 stable" would be a new
stable9
theme.This would be theoretically possible … except that a theme declaring
base theme: stable
now has no way to indicate which of the following is intended:stable
stable
stable
This I think is impossible.
Kind of: if by "which version" you mean "a renamed
stable
for Drupal 9".Based on this, my proposal would be:
stable9
theme.stable
will always be "the Drupal 8 stable theme"'s extension name. We could alias this tostable8
to have consistency.stable
akastable8
remains in core or is moved into contrib; the extension name remains the same.stable10
at that point.Comment #7
lauriiiYour hypothesis is correct. Sorry, the sentence that I wrote initially is confusing because I mentioned renaming just briefly as a side note. I should have been more clear that the plan isn't to have two themes that have the same machine name.
Comment #8
Wim Leers👍 Thanks for confirming!
test_stable
since the entire purpose of that theme is to test the current "default tostable
if nobase theme
specified" behavior.Comment #10
Wim LeersHm … this is what's causing most if not all of the remaining 1636 failures.
So I need to make the
test_stable
theme be discovered only by\Drupal\KernelTests\Core\Theme\StableThemeTest::testStableIsDefault()
. This turns out to be surprisingly hard.The only way to do it is by using
file_scan_ignore_directories
to make extension discovery ignoretest_stable
in all tests except for this one. But that leads to the next challenge:\Drupal\Core\Extension\ExtensionDiscovery::$files
is cached statically, across allExtensionDiscovery
instances, with no way of clearing this cache 😨I attempted various tricks, all without success.After spending a lot of time digging, I discovered
SettableDiscoveryExtensionListTrait
andTestThemeExtensionList
, all out of reach in a unit test class unfortunately.I settled on something that works although I definitely do not think it's elegant. OTOH … this is just going to be around until Drupal 9 ships, so does elegance truly matter? I think this is good enough.
Comment #12
Wim LeersI see that #10's interdiff and patch were incomplete. Here are the missing bits.
Comment #13
Wim LeersThis fixed it for kernel tests. Now repeating that for functional tests.
Comment #16
Wim LeersBefore I dig in deeper, I'd like confirmation from @lauriii and perhaps a framework manager that they approve of this approach. I'm down two ~150 failures, but the patch still is doing pretty exceptional things. Before I spend more time on it to bring it down to zero failures, I'd like a +1 on the approach.
Comment #17
lauriiiOverall the approach seems fine to me. 👍
It would be nice if we could explicitly mention that base theme property will be required in Drupal 9. This intention isn't currently documented here.
This is still just a proposal. Also, we haven't decided on naming. Is this something we have to decide in the scope of this issue? Any thoughts on trying to document this without going into specifics?
Should we open follow-up to Drupal 9 to actually make this required?
Comment #18
Wim LeersOkay, noted! @xjm also indicated she wanted to review the approach, so now assigning to her.
Comment #19
Wim LeersRelated to #17.2: #2659890-32: [Policy] [Plan] Drupal 9 and 10 markup and CSS backwards compatibility.
Comment #20
xjmSorry, to clarify: I'm interested in reviewing the new approach and will when I have time, but this does not need to be blocked on me. We could also get feedback from one of the framework managers. I'll see if anyone is interested in giving feedback here.
Comment #21
catchI think we can just say 'you must now specify 'stable' as a base theme specifically to use it, instead of it being added by default, see @change_record', and then document what Drupal 9/10 recommendations look like in the change record from a follow-up issue - i.e. I don't think we should block the issue on the specific plan, it also works self-contained just to get people to add the explicit dependency
Comment #22
Wim LeersI should've been more clear in #17: I am looking for sign-off on the approach of the test coverage.
Comment #23
alexpottIf we're removing this in Drupal 9 why are not doing regular legacy testing with @expectedDeprecation.
I think we should move this test into a new class. The WildWest theme shouldn't trigger this deprecation and having this code here is confusing.
Comment #24
alexpottAs for a better way of testing. Let's remove test_stable found themes and move it to a place where we can create a virtual filesystem to inject into \Drupal\Core\Extension\ThemeExtensionList as Drupal root. That way we can get rid of the much of the awkwardness.
Comment #25
Wim Leers#23:
Because merely installing the theme triggers the deprecation error, which means that the rest of the test's method assertions won't run.I though this was how it worked, and I'd swear I manually debugged this to check this, but apparently I was wrong! TIL! 😊Comment #26
Wim Leers#24: Thanks, that's the feedback I was looking for! Your proposal removes the awkwardness but it makes this one test super convoluted. I think that's the right trade-off.
Or at least, that's what I thought it would do. Unfortunately,
\Drupal\Core\Extension\ExtensionDiscovery::scanDirectory()
does this:I can work around that by ensuring
ExtensionDiscovery
is constructed with$root = 'vfs://root'
. But then the next problem hits me,\Drupal\Core\Extension\ExtensionDiscovery::scan($type, …)
does this, despite being limited to a particular extension$type
:It first scans a given search directory for all search types, then it extracts only the requested type. So it's impossible for me to override only
ThemeExtensionList
. We'll need to overrideExtensionDiscovery
just forThemeExtensionList
.However, after doing that, I ran into a new problem:
\Drupal\Core\Extension\ExtensionList::createExtensionInfo()
does:Since
InfoParser
is unaware of the root and assumes everything it is given is relative to the Drupal root on disk (and not some virtual file system), it fails to find the file in the virtual file system.No problem, I can work around this too! Just subclass
InfoParser::parse()
and prefix all incoming paths withvfs://root/
and then inject this custom info parser intoThemeExtensionList
. Yay, parsing now works.Alas … another problem arises.
$extension->getMTime()
now fails because\Drupal\Core\Extension\Extension::__call()
omits the root. I was able to fix this inExtension
itself.Great, now everything seems to be working. Except theme installation is failing because
test_stable
lives in the virtual file system, yet it depends onstable
which lives inside the real file system! 🤣We can pretend it also lives in the virtual file system. Doing that gets us a working solution.Comment #27
Wim LeersThere was at least one test relying on the
test_stable
theme. It looks like that was not truly necessary, but for now just simply pointing to the new location.Comment #28
Wim LeersNow if I'm lucky, the only remaining failing test is
\Drupal\Tests\system\Functional\Update\StableBaseThemeUpdateTest
. We'll have to see what to do about that test. I think we might be able to remove it altogether. It's testingsystem_update_8012()
, which was added before 8.0.0!Also: figuring out #26 took a very long time. It reaches into some areas with hard-coded assumptions. I spent several hours of my vacation trying to finish this up, then gave up when it seemed to take too long. Turns out this was the right call, since I spent another several hours on it today!
Comment #32
Wim LeersComment #34
Wim Leers#32 fixed the failures in
ExtensionListTest
. That test was passing invalid data toExtension
objects to work around a bug that I solved in #26:This reroll makes similar fixes in
ThemeExtensionListTest
.Comment #36
Wim Leers\Drupal\KernelTests\Core\Theme\BaseThemeRequiredTest::testWildWest()
can be simplified now 🥳Comment #38
Wim LeersInteresting twist for
StableBaseThemeUpdateTest
:system_update_8012()
was removed in favor ofsystem_update_8014()
by @alexpott in #2581443-35: Make Classy extend from the new Stable base theme.I think we may be able to use a pattern similar to what I used in
\Drupal\KernelTests\Core\Theme\BaseThemeDefaultDeprecationTest
, but I'm still seeing one unrelated update path test failure locally. Let's see what testbot says.I don't like this at all, but the only alternative I see is to simply remove this update path test.
Feedback would be much appreciated!
Comment #39
Wim LeersJust noticed #36's interdiff was wrong.
Comment #40
Wim LeersAll these changes make up for about half of the changes, these could be moved to a separate (blocking) issue if we like. Thoughts?
Comment #41
Wim LeersI think it might be saner to just remove
StableBaseThemeUpdateTest
. And if people disagree, it'd be great if they could provide proposals of how to keep it working while also complying with all other requirements.Comment #42
Wim LeersIssue summary updated, change record already exists. #38 and #41 are both green. #38 keeps
BaseThemeDefaultDeprecationTest
but makes it use the virtual file system, #41 removes the test.This needs review on a few aspects:
BaseThemeDefaultDeprecationTest
?WRT patch details: I know
\Drupal\KernelTests\Core\Theme\BaseThemeDefaultDeprecationTest
shouldn't useFooSomething
classes, but without consensus about the approach, renaming that is just busywork.Comment #43
Wim Leers@xjm mentioned in a meeting the other that we definitely want to avoid removing test coverage, even if it means making tests more complex. So please ignore #41 and instead review #38 :)
Comment #44
lauriiiWhat are the other requirements we have to comply with?
It could be useful to move them to a separate issue. Moving these extension system bug fixes to a separate issue allows us to give a more focused review.
Comment #45
lauriiiTalked with @Wim Leers and he asked me to clarify #44.3 a little. I think it would make sense to open a separate issue if this is a bug that could be worked on separately. It would be also great if we could create a failing test for the bug so that it gets tested even after these deprecation tests get removed.
Comment #46
Wim LeersLike @lauriii mentioned, we discussed #44 last night. I clarified #44.2 (which indeed was very poorly worded — sorry about that!): I was referring to the fact that ideally we would keep
StableBaseThemeUpdateTest
, usevfs://
(per @alexpott in #24), without complex code and without the need for tricky changes in existing tests. (Which is also what #44.3 is about, more about that in my next comment.)Per #44.1, we're going with the approach in #38 (which updates
StableBaseThemeUpdateTest
in pretty complex ways to not reduce test coverage), not #41 (which drops that test coverage). So, rerolling #38.This reroll also addresses point #44.4. Next up: #44.3.
Comment #47
Wim LeersWRT #44.3. The tricky thing is that those changes all are due to bugs in tests and code paths exercised only by tests. So we can't write a failing test, because that'd be a test testing a test 🙃
I could extract that into a separate issue, and I did: #3076797: \Drupal\Core\Extension\Extension's absence of validation has allowed multiple incorrect tests to be added
Since even this #3076797: \Drupal\Core\Extension\Extension's absence of validation has allowed multiple incorrect tests to be added, which would reduce the size of this patch.
issue is not getting a lot of attention, I doubt that issue that only touches internals is going to get more attention. So my fear is that if we split it out into a separate issue, that it will not get committed. I'd be happy to be wrong though! Hopefully see you inThat being said, I have good news: I found a way to split it off to a separate issue after all! Because, as it turns out, there’s a LOT of broken test code in core around this. 🙃This is good, because it justifies fixing this separately!
Comment #48
Wim LeersComment #49
Wim LeersRebased #46 on top of #3076797-15: \Drupal\Core\Extension\Extension's absence of validation has allowed multiple incorrect tests to be added.
Comment #50
Wim Leers#3076797: \Drupal\Core\Extension\Extension's absence of validation has allowed multiple incorrect tests to be added landed! Rebased #49.
Comment #51
Wim LeersFixed the sole coding standard violation. 😬
But that did not cause the test failures. What did, were the test themes that were added to Drupal core between #49 and #50. Those now need to be updated too. Easy enough.
Comment #52
lauriiiYay for green tests!
Should we also say explicitly that in Drupal 9 base theme is a required theme setting?
Should we rename these to something else than Foo classes?
Comment #53
Wim LeersDone & done. :) That second point is a really good catch 😅 (Not that it would've mattered a lot, but still.)
Comment #54
lauriiiAll the feedback has been addressed and the patch looks good for me. Marking as RTBC.
Comment #56
Wim LeersComment #58
catchCommitted 5448b07 and pushed to 8.8.x. Thanks!
Comment #60
Wim LeersComment #61
xjmUpdated the RN snippet to describe the disruption.
Comment #62
Kristen PolPer a Slack discussion with Gábor Hojtsy regarding usage of D9 tags (Drupal 9, Drupal 9 compatibility, Drupal 9 readiness, etc.), "Drupal 9 compatibility" should be used for contributed projects that need updating and "Drupal 9" was the old tag for D8 issues before the D9 branch was ready. Doing tag cleanup here based on that discussion.
Comment #63
ressa CreditAttribution: ressa at Ardea commentedWill Drupal 11 also use stable9, as Drupal 10 does currently? Or will there eventually be stable11 for Drupal 11, stable12 for Drupal 12, etc.?