Follow-up to #2704871: Replace usages of deprecated method drupal_render()
Problem/Motivation
In #2729597: [meta] Replace \Drupal with injected services where appropriate in core we generally decided to convert usages of \Drupal methods to inversion-of-control injection, by method.
This issue converts usages of \Drupal::service('renderer') to injection.
In some places in core, this can lead to circular dependencies, such as in #2529438: Inject renderer service into ThemeManager, disuse drupal_render()
Proposed resolution
Convert usages of \Drupal::service('renderer') to use IoC injection where applicable.
Exclude theme systems, which are handled in #2529438: Inject renderer service into ThemeManager, disuse drupal_render()
Remaining tasks
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|
Issue fork drupal-2834982
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
mile23This might be a little postponed on #2704871: Replace usages of deprecated method drupal_render(), but anyone who isn't afraid of a reroll can start here.
Comment #3
mile23A patch to start with...
Non-test usages replaced, except for these:
Drupal\Core\Ajax\CommandWithAttachedAssetsTraituses renderer without injection. See: #2733703: [plan] Service traits should require IoC injectionDrupal\Core\Entity\EntityDisplayBaseuses\Drupalto get the renderer. Since it's a plugin, we should be able to useContainerFactoryPluginInterface, to inject, but since it's also an entity we can't, because entities usecreate().Drupal\Core\Render\Element\Actionsuses\Drupalto get the renderer inpreRenderActionsDropbutton(), which is static. You'd think that the caller would be responsible for doing the rendering, but it is not. It contains a todo: // @todo Move this to #pre_render. Needs issue.Drupal\field_ui\Element\FieldUiTable: also called from static.Comment #6
aviral2809 commentedComment #7
martin107 commentedThis patch no longer applies...
@aviral2809 If you like I will help you with the reroll?
This issue injected the renderer --- it may be good as a pattern to copy.
#2869903: ContextualController: remove ContainerAwareTrait
If you want help just let me know....
Comment #8
martin107 commentedHere is just a straight reroll
The only conflict I had to manually resolve was a conversion of array() to []
Comment #9
martin107 commentedmy mistake
Comment #12
martin107 commentedAfter looking at the current patch, I can see the problem
ViewFormBase breaks an established Drupal pattern for Base classes.
it is subtle but by convention Base classes do not provide _construct() and create() methods.
ViewFromBase is extended 10 times! .. so all patches touching those dependencies would have to adjust 10 constructors.
This argument makes me queasy but the 10 descendants to ViewFormBase get an extra method
$this->renderer() a single place which contains the antipattern.
\Drupal::service('renderer')
--- the argument being it concentrates the pain points, the thing to be refactored before Drupal9 to a single location.
Comment #14
martin107 commentedFor similar reasons to #12
EntityForm::_construct() is not called/ not useful
I don't like a Form having a dependency on the renderer service.
it seems overcomplicated. the solution is to recognise that the dependency is actually fake!
In this instance we are using the renderer service as a helper function to make a series of CacheableMetadata helper calls
in short render is a "pass through" service and we should just remove the dependency.
Comment #15
martin107 commentedI am spinning off a side issue to untangle the renderer for other services.
we need to deprecate some RenderInterface:methods() so the problem won't be resolved until Drupal9 :(
Comment #16
mile23So if there is a need for cacheable metadata to be managed by
EntityForm, it seems like that change would be to remove the dependency onRenderer, and then add code to manage the metadata the wayRenderer::addCacheableDependency()does. Or add a @todo with a followup issue to do that if it's out of scope here.+1. The comments in #12 and #14 are similar to the reasoning behind #2733703: [plan] Service traits should require IoC injection and #2471663: Undeprecate EntityHandlerBase
Anyway, the goal here is to minimize dependency on
\Drupal, acknowledging that we can't completely remove it, especially for traits and base classes, so thisAnythingBase::renderer()pattern is appropriate.Comment #21
martin107 commentedLots, but not all of the patch here - has had to be duplicated as part of the solution to
#2876274: Renderer: deprecate mergeBubbleableMetadata() and addCacheableDependency()
I have move that issue to a state where I think it is complete.
Given the conflicts with this patch ... I think we should pause here and reroll when the other is committed.
I would still love to get this in before Drupal9
Comment #22
martin107 commentedMile23 , sorry I did not mean to derail your issue.
#2876274 blew up into a 60Kb patch.. now that is near complete I am going to start working on this again.
but just limiting changes to
\Drupal::service('renderer')->renderRoot()
\Drupal::service('renderer')->render()
[ the other patch will deal with all the rest ]
the final patch here should also be reasonably large..
Comment #23
martin107 commentedThis is not a candidate for best use of grep in 2019 but
git grep --name-only "\Drupal::service('renderer')->render" | grep -v 'Test\.php' | grep -v '\.module' | grep -v '\.inc' | grep -v '\.api\.php' | grep -v '.install'
27 things to replace
core/lib/Drupal/Core/Ajax/CommandWithAttachedAssetsTrait.php
core/lib/Drupal/Core/Render/Element/Actions.php
core/lib/Drupal/Core/Render/Element/Tableselect.php
core/lib/Drupal/Core/Theme/ThemeManager.php
core/lib/Drupal/Core/Utility/TableSort.php
core/modules/book/src/Form/BookAdminEditForm.php
core/modules/comment/src/Plugin/views/field/EntityLink.php
core/modules/comment/src/Plugin/views/field/StatisticsLastCommentName.php
core/modules/contextual/src/Plugin/views/field/ContextualLinks.php
core/modules/field_ui/src/Element/FieldUiTable.php
core/modules/file/src/Element/ManagedFile.php
core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php
core/modules/filter/src/Plugin/Filter/FilterCaption.php
core/modules/filter/src/Plugin/Filter/FilterHtml.php
core/modules/history/src/Plugin/views/field/HistoryUserTimestamp.php
core/modules/image/src/Form/ImageStyleEditForm.php
core/modules/image/src/Plugin/Field/FieldWidget/ImageWidget.php
core/modules/node/src/NodeListBuilder.php
core/modules/node/src/Plugin/Action/UnpublishByKeywordNode.php
core/modules/rdf/tests/src/Kernel/Field/FieldRdfaTestBase.php
core/modules/search/tests/modules/search_extra_type/src/Plugin/Search/SearchExtraTypeSearch.php
core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php
core/modules/update/src/Form/UpdateManagerUpdate.php
core/modules/views/src/Analyzer.php
core/modules/views/src/Plugin/views/area/Result.php
core/modules/views/src/Plugin/views/field/PrerenderList.php
core/modules/views_ui/src/Form/BreakLockForm.php
Comment #25
thallesHi @martin107, you create a new parameter in

Drupal\file\Plugin\Field\FieldWidget\FileWidgetBut this parameter was no injected in

Drupal\image\Plugin\Field\FieldWidget\ImageWidget, I think this can be a problemComment #27
s_bhandari commentedFound one in core Views module and adding a patch for the same.
Comment #28
junglePer the parent issue, adjust the scope to do it for non-test code.
Comment #29
suresh prabhu parkala commentedPlease review!
Comment #30
jungleThanks @Suresh Prabhu Parkala, tests did not pass.
Comment #32
suresh prabhu parkala commentedPatch for 9.2.x, please review.
Comment #36
narendra.rajwar27Adding re-rolled patch for 9.5.x
This patch does not include changes in file
core/modules/book/src/Form/BookAdminEditForm.phpfrom patch #32, because the changes of this file are already covered here: https://www.drupal.org/project/drupal/issues/1169576#comment-14692162Comment #40
spokjeComment #41
spokje