Problem/Motivation
Theme functions were deprecated back in 8.1.x and slated for removal in Drupal 9. However, we improved our deprecation policy during the lifecycle of Drupal 8 and added warnings to developers; these warnings were never added to the theme function system, and theme functions are still used in Drupal 8 contrib.
Contrib code search: http://grep.xnddx.ru/search?text=function%20theme_&filename=
Proposed resolution
Deprecate theme functions properly using trigger_error()
etc for removal in Drupal 9.
OR
Deprecate theme functions properly using trigger_error()
etc for removal in Drupal 10.
Remaining tasks
Add the deprecations and tests.
User interface changes
None
API changes
Developers will be warned when they use deprecated theme functions functionality.
Data model changes
None
Release notes snippet
Theme functions were deprecated prior to Drupal 8.8.0's release in favour of Twig templates. However the deprecation did not use Drupal's deprecation APIs to notify module and theme developers. From Drupal 8.9.0 the use of theme functions will start to trigger deprecation notices.
Comment | File | Size | Author |
---|---|---|---|
#46 | 3109480-32.patch | 47.56 KB | catch |
#32 | interdiff.3109480.31-32.txt | 719 bytes | longwave |
#32 | 3109480-32.patch | 47.56 KB | longwave |
Comments
Comment #2
lauriiiDiscussed with @catch and @alexpott on Slack since this has some security concerns which creates some urgency around this. The main problem is that theme functions are lacking auto escaping. This makes the developer experience potentially confusing since developers will have to remember when to worry about escaping.
To estimate the disruption, we looked deeper into the the usages of theme functions. A lot of the usages are in modules without any Drupal 8 releases. Some of the modules have releases but theme functions aren't actually called anywhere.
If we want to move forward with this prior to Drupal 9, we should add a proper deprecation in a future release of Drupal 8.8.x so that people can have as much time to remove usages of theme functions as possible. I'm tagging this for release manager review so they can make a final decision on this.
Comment #3
catchI did spot checks on a few modules from that grep.
For example xmlsitemap defines a theme function for an admin page, but it's dead code and never used.
Search API also defines a theme function for an admin page, but it is still used.
Several other modules don't have 8.x releases yet (i.e. abandoned 8.x branches with no release on the project page and no recent commits).
So if we deprecate in 8.8.x properly for 9.x we'll force (my guess) 5-10 maintained modules with some usage to do extra work to be 9.x compatible. This is not huge but it is more than nothing given 8.8.0 is already out.
If we don't deprecate for 9.x, I think we should still deprecate in 8.9.x for Drupal 10 to encourage people to actually finish porting from Drupal 7 / security harden, and because it's actually been deprecated for years now just without our full deprecation framework implemented for it.
Comment #4
lauriiiThere could be some themes customizing those theme functions too. It's likely that if a module ships with a theme function, that the override is also a theme function. It seems like that the Search API theme function isn't something that people would override often, but it might be a good idea to look into some of the other modules to try to ensure there aren't any instances that would be commonly overridden by people.
Comment #5
xjmWhat are the security concerns? Or is there a private issue where we can or should be discussing?
Comment #6
longwave@xjm I think the security concerns are just that theme functions do not and cannot autoescape their output, making it very easy to inadvertently allow XSS.
Comment #7
xjmLet's start working on a patch for this now; we can make the decision about whether to backport a deprecation to 8.8.x for 9.0.x removal vs. backporting for 10.0.x removal once we see what the impacts of the deprecation would be. After chatting with @catch it sounds like the deprecation might be a little involved, since we're not deprecating just a function or method; we're deprecating the ability to create a kind of API.
Meanwhile we should also detect them directly in Upgrade Status I think, because I think a lot of themes and theme functions don't have test coverage in contrib. Let's file an issue for that too.
Comment #8
longwaveTrivial patch to get the ball rolling.
Comment #10
longwaveSo the biggest problems here are two test modules, common_test and theme_test. I think we are safe to remove theme functions from common_test as it is used in multiple places and doesn't test theme functionality directly. This patch does that removal.
theme_test is going to be more complicated. I think the best solution might be to clone it to a theme_deprecated_test module, remove the theme functions from the original, and convert all the deprecated test parts to legacy tests that use the cloned module.
Comment #12
catchSecond part of #10 sounds like a good plan to me.
Comment #13
longwaveWork in progress; the test modules that use theme functions have been split out and ThemeSuggestionsAlterTest has been split up as well, but lots more tests to split up or add
@group legacy
to.Running this locally I also seem to still get the new deprecation messages in tests where I don't expect them, need to figure out what is triggering that.
Comment #15
longwaveStill more to do but this should clean up any false positive deprecation messages now.
Comment #17
longwaveNot quite sure what to do with ThemeTest::testPreprocessForSuggestions() and ThemeTest::testNegotiatorPriorities() yet.
Comment #19
longwaveI think it is OK to convert these to Twig as theme function functionality is still tested elsewhere.
Comment #21
longwaveComment #22
xjmComment #23
bnjmnmI'm beginning a review of the patch in #21 and noticed the issue summary is a little out of sync regarding version numbers. Tagging to "needs issue summary update" (would typically just update it myself but there's just enough potential to add something incorrect that I'd prefer someone who has been active in the issue )
Comment #24
catch@bnjmnm so it's inconsistent because we're a bit undecided. But I think it makes sense to write a patch for 9.0.x removal and the version numbers are the easiest thing to change if we end up deciding to deprecate for 10.0.x instead.
Comment #25
catch@bnjmnm so it's inconsistent because we're a bit undecided. But I think it makes sense to write a patch for 9.0.x removal and the version numbers are the easiest thing to change if we end up deciding to deprecate for 10.0.x instead.
Comment #26
bnjmnmMakes sense regarding the issue summary, removing the tag since the need to update isn't certain until this exits undecided status.
I plan to do a full review but providing a partial one for now as I may not be able to resume until tomorrow.
These could be misinterpreted as the routes/hooks themselves being deprecated. Could these comments be rephrased? (may be additional instances of this in the patch)
Could this be updated to reflect that it's specifically testing suggestions that make use of deprecated theme functions?
'variables' isn't needed.
There's a theme function
test_theme_theme_test_function_suggestions__module_override
still in this file that should be moved, or if it can't there should be a comment explaining why and a @todo to remove when theme functions are removed.common_test_empty
and the accompanying template can be removed entirely. I had my suspicions but didn't want to suggest until I confirmed this by creating a test patch and drupalci was fine with it.Comment #27
bnjmnmHere's the rest of the review. Looks like pretty minor stuff.
Tried to avoid too much scrutiny on code that was clearly just moved and not original to this patch - my goal there was to confirm the right things were properly moved to the right place as opposed to relitigating tests that will be removed shortly(?). #26.4 was an exception to this.
Although it should be pretty clear what is going on when theme_deprecated_test is removed, adding a @todo to the issue where that will occur will make things clearer.
Would be helpful to do this in the unit and kernel RegistryTest as well.
Comment #28
longwaveThanks for the detailed review!
#26.1, #26.2, #27.2: I reworded a number of comments and renamed "deprecated" things to "legacy" which hopefully makes it clearer.
#26.3, #27.1: Added @todos pointing to the removal issue.
#26.4, #26.6: Removed these.
#26.5: This and two other functions have been moved to the legacy theme that will be deleted entirely in the future.
Comment #29
bnjmnm#28 is looking good! One additional thing came to mind - there should be test coverage for the deprecation itself . A test similar to
\Drupal\Tests\Core\Asset\LibraryDiscoveryTest::testAssetLibraryDeprecation
would provide the necessary coverage.Comment #30
longwaveQuick question: as the change record predates 8.0.0 should the deprecation message start "Theme functions are deprecated in drupal:8.0.0" even though we are introducing this much later?
Looking at the diff again I also think I want to refactor the tests even further to make the legacy tests even simpler to delete in the followup, will try to get to that and #29 in the next day or two.
Comment #31
longwaveRefactored all the tests; we now have legacy unit, kernel and functional tests which will be simple to remove later. #29 is solved by using @expectedDeprecation in the unit and kernel tests to confirm the deprecation is triggered correctly.
I also answered my own question in #30; elsewhere we mark deprecations as "in drupal:8.0.0" even if the actual deprecation was added much later, so I reworded the deprecation here to start from 8.0.0 as well.
Comment #32
longwaveFixed up some comments.
Comment #33
catchYes it should be the version that the functionality was deprecated rather than the version we added the deprecation notice usually - as if we'd had a fully-worked-out deprecation process at the time.
Comment #34
catchComment #35
bnjmnmAll my feedback from #31 and #32 is nicely addressed. I did an additional round of manual test runs where I intentionally changed and removed things to confirm the tests work and that no unnecessary code is present and it was in good shape.
The patch itself seems RTBC worthy at this point but it seems like it would be best to hold off until this gets release manager review/policy specifics. If I'm incorrect on that rationale let me know and I'll change the status.
Comment #36
catchSo IMO removing support for this in 9.x is still a good idea - theme functions can't use Twig autoescape, which was why we deprecated them in 8.x in the first place.
We have a change record for this from 2015: https://www.drupal.org/node/2575445
Comment #37
catchComment #38
bnjmnmTagging with Drupal 9.0.0-beta1 requirement so this can be visible in a search vs just via the parent issue.
Comment #39
lauriiiThe deprecation message looks good. I also checked that no test coverage is lost by the change. Besides that, I applied only the change for
Drupal\Core\Theme\Registry
and ranDrupal\KernelTests\Core\Theme\RegistryTest
to ensure the deprecation error is thrown.It also looks like @catch is feeling positive about this change so I'm moving this to RTBC to wait for a final decision from the release managers.
Comment #40
longwaveThis applies to all three branches for me (with fuzz), adding tests just to be sure.
Comment #41
Gábor HojtsyJust noting based on chat discussion that @catch is awaiting feedback from @xjm to make sure both release managers are on board with the target version of the deprecation especially.
Comment #42
xjmBased on the extent of http://grep.xnddx.ru/search?text=function%20theme_&filename= I'm not totally comfortable deprecating this for removal before 9.0.0. I think it should have been done before 8.8 for it to be a 9.x deprecation.
If we're concerned about the security impact of this (and I am), we could deprecate for 10.0.x, but backport it to 8.9.x or even 8.8.x as an exception to the general "9.1.x" policy, and potentially follow the approach we used for string formatting placeholders and
trigger_error()
with no@
in 9.0.x.Comment #43
Gábor HojtsyComment #44
xjm@catch proposed simply changing the deprecation to 10.0.x here, backporting it to at least 8.9.x, and filing a followup to remove the
@
from thetrigger_error()
in 9.0.x only.Comment #45
Gábor HojtsyRetitling for clarity.
Comment #46
catchJust did a find and replace for s/9.0.0/10.0.0/g
Comment #47
longwave#46 looks good.
Opened #3117330: Trigger errors in deprecated theme functions to follow up in 9.0.x.
Can we remove the "needs release manager review" tag now?
Comment #48
longwaveComment #49
catchRemoving tag.
Comment #50
alexpottThis looks great. Yay for proper deprecation testing and @trigger_error!
Leaving open against 8.8.x as we might commit it there once 8.8.3 is out.
Committed and pushed 4a70ba3774 to 9.0.x and f8870768f5 to 8.9.x. Thanks!
Comment #53
mondrakeI am afraid this has broken testing on PHPUnit CLI for groups:
Comment #54
Mile23Issue here: #3118477: RegistryTest, RegistryLegacyTest both define the same class, use mock instead
Comment #55
catchWe should probably postpone the backport here on #3118477: RegistryTest, RegistryLegacyTest both define the same class, use mock instead, but the fatal error is only an issue if running tests in a very specific way (i.e. not on DrupalCI, and not running them individually, which are the more common), so no reason to roll this back against 8.9.x/9.0.x IMO. Moving to 'postponed'
Comment #56
longwave#3118477: RegistryTest, RegistryLegacyTest both define the same class, use mock instead was committed so NW to incorporate those changes here for 8.8.x.
Comment #57
xjm@catch and I discussed this again and agreed not to backport the issue to 8.8.x. New deprecations are minor-only as a rule, and this one in particular could be pretty disruptive. It already caused some confusion that was reported in Drupal Slack just from what's already been committed (which led to #3120954: Add function name to the deprecation message about theme functions being filed).
With the 8.9.x deprecation as well as #3117330: Trigger errors in deprecated theme functions, we're still ensuring that contrib and custom modules are going to find out about this soon.
Comment #58
xjmComment #59
phenaproximaTagging for a release note and re-opening until we have one.
Comment #60
catchComment #61
catch