Problem/Motivation
As the drupal_render() method is deprecated, we should no longer use it in Drupal core.
Proposed resolution
Let's replace with \Drupal::service('renderer')->render();.
Remaining tasks
Some follow-ups are needed:
- Replace drupal_render() in documentation. (There is a lot of it.)
- Injecting the proper service where needed should be part of follow-up issues per maintainer's comments in #20.
Currently we're blindly replacing with\Drupalso the work is easy to do and review.
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #69 | interdiff.txt | 717 bytes | mile23 |
| #69 | 2704871_69.patch | 29.34 KB | mile23 |
| #67 | interdiff.txt | 1.62 KB | mile23 |
| #67 | 2704871_67.patch | 29.34 KB | mile23 |
| #65 | 2704871_65.patch | 30.96 KB | mile23 |
Comments
Comment #2
pepegarciag commentedComment #3
pepegarciag commentedComment #4
pepegarciag commentedChanging all ocurrences on node module files to \Drupal::service('renderer')->render().
Comment #5
manuel garcia commentedLet's store the service in a variable so we don't have to call it twice.
Let's inject the service instead.
Let's inject the service instead.
Comment #6
pepegarciag commentedTo inject the service on this point, I needed to modify the ExecutableInterface, but maybe the best solution would be to call the renderer service from the execute method implemented on UnpublishByKeywordNode class.
Comment #7
manuel garcia commentedComment #8
penyaskitoWe cannot do API changes at this point, the service must be injected in the constructor.
Same here.
You need to do the same you already did in
NodeListBuilderComment #10
pepegarciag commentedComment #12
pepegarciag commentedTry to fix #8. Hope it works!
Comment #14
pepegarciag commentedTry to fix previous failed test! Hope it works for now
Comment #15
pepegarciag commentedComment #16
manuel garcia commentedI'm pretty sure we shouldn't be making changes to the CHANGELOG.txt ;-)
Comment #17
pepegarciag commentedThanks #16 apologies for my mistake. Should be fine now!
Comment #18
penyaskitoLooks good to me and it's a good improvement, thanks for working on this one.
The only thing I'm not really sure it's if constructor arguments are considered an API change. I'm RTBCing this one so we get feedback from core committers.
Comment #19
penyaskitoComment #20
alexpottCan we just have one patch to do a find and replace on the entire core to replace
drupal_render()with\Drupal::service('renderer')->render().And then we can have followup issues to inject the renderer service where necessary.
See https://www.drupal.org/core/scope
Also, now irrelevant because I think we should handle injection separately, this should all go on one line.
Comment #21
penyaskitoComment #22
penyaskitoI would say this is a Novice task, steps are described in the IS.
Comment #23
snehi commentedDone as suggested by Alex.
Used following command.
grep -rl 'drupal_render()' core/ | xargs sed -i 's/drupal_render()/\\Drupal::service('renderer')->render()/g'I hope that is ok.
Comment #25
gargsuchi commentedThis patch applies the needed change in the core directory.
Comment #26
gargsuchi commentedComment #28
snehi commentedLet @Alex to jump into this.
Comment #29
mile23Patch in #25 applies and converts most calls to drupal_render() that aren't in documentation. There's still one in core/includes/common.inc.
Added follow-ups to issue summary.
Comment #30
gaurav.pahuja commentedComment #32
wim leersThis is in a service. In services, the
rendererservice should be injected.Comment #33
mile23@wim leers: Check out #20. The service will still work with \Drupal, and we'll poke through and inject usages appropriately in a follow-up. This way we at least have deprecated drupal_render() with an easy-to-review patch.
Comment #34
mile23Here's the beginnings of that follow-up: #2729597: [meta] Replace \Drupal with injected services where appropriate in core
Comment #35
mile23Looks like a failing test in
Drupal\views_ui\Tests\PreviewTest:fail: [Fatal error] Line 0 of :
[19-May-2016 17:02:00 Australia/Sydney] Uncaught PHP Exception LogicException: "Render context is empty, because render() was called outside of a renderRoot() or renderPlain() call. Use renderPlain()/renderRoot() or #lazy_builder/#pre_render instead." at /var/www/html/core/lib/Drupal/Core/Render/Renderer.php line 241
Comment #36
thomas cysI'm still learning Drupal 8 so i read a lot of code from core and core modules. Solutions like these only teaches people bad practices.
You already see lots of contrib modules using \Drupal::service('foo') outside of legacy procedural code and that's sad imho.
Comment #37
mile23Absolutely.
However, this patch is big and will be hard to review and commit if we don't do that.
drupal_render()is officially deprecated whereas\Drupalis not.We'll do the IoC injection work on #2729597: [meta] Replace \Drupal with injected services where appropriate in core
If we could get those two tests passing in #30... :-)
I think it's the change in the interdiff. That might need to be the
bare_html_page_rendererservice instead ofrenderer.Comment #38
rajeshwari10 commentedHi Mile23,
Done changes as per your suggestions.
Please review.
Thanks!!
Comment #40
snehi commented+1 for RTBC.
Comment #42
ieguskiza commentedHi,
I fixed the problem with the latest patch but I'm unsure if it is inside of the scope of the issue since it involves another deprecated function: drupal_render_root.
I can remove this fix and move it into an entirely separate issue if needed, but in the meantime, the patch is ready to review.
Comment #44
ieguskiza commentedComment #45
ieguskiza commentedComment #46
manuel garcia commentedThanks @ieguskiza for working on this!
Should we be using this here?
Should this be part of this patch or should we split this off into a different issue?
Patch looks good RTBC to me, but I'm guessing we should clarify these two questions before we RTBC this... or perhaps RTBC it to get answers to these qeustions?
Comment #47
ieguskiza commentedHi @Manuel Garcia,
thanks for your review.
To be fair I only tried to fix the patch provided in the previous comments so I'm at a loss on why we are using bare_html_page_renderer in that case. Maybe @Mile23 can give us some insight since it was him who proposed it in the first place.
About your second comment, I agree we should just stick to the scope of the issue and only replace the drupal_render calls here. I can create a separate related issue for the replacing of drupal_render_root() with \Drupal::service('renderer')->renderRoot().
Comment #48
dimaro commentedReading comments #46 and #47 I upload this patch to apply the change commented in the second suggestion of comment #46.
On the other hand, I'm not sure if we should add the 'bare_html_page_renderer', as discussed in the first suggestion of comment #46.
Comment #49
manuel garcia commentedThanks @dimaro for that, RTBCing to get committers feedback
Comment #50
xjmYep, looks like that one
bare_html_page_rendereris needed for this to pass.There are still tons of documentation and string references to
drupal_render(), but I think that also makes sense to address in a followup issue. I've created #2834889: Replace documentation and string references to drupal_render() for that.After I filter out all the string and docs references, as well as references to
drupal_render_root()which already has a related issue, here's what's left:The definitions of the deprecated functions, a test module function name, and then a couple of keys for something. I'll check on what those last are.
Comment #52
xjmI had to fix one coding standards error:
The use statement is not actually needed since we are using the service. :)
For everyone who raised concerns on this issue about not doing proper DI yet, we will definitely do that in followups. I encourage you to help in #2729597: [meta] Replace \Drupal with injected services where appropriate in core! The goal for this first step is to not have any reliance on the deprecated procedural function.
Comment #53
xjmAlso, let's create a specific followup as a child of #2729597: [meta] Replace \Drupal with injected services where appropriate in core for the DI for these and other instances in core.
Comment #54
wim leersThis seems very wrong. This should definitely use the
rendererservice.@Manuel Garcia also raised this in #46.1.
I don't even understand how this can possibly pass, since
\Drupal\Core\Render\BareHtmlPage(RendererInterface)::render()does not exist! :OComment #56
xjmAlrighty, reverted since it looks like this does need more discussion. Thanks @wimleers.
Comment #57
wim leersThe occurrences of the string
drupal_renderin those tests only exist because they're used as the cache keys (and hence cache IDs) fordrupal_render()-related test coverage. Feel free to change all those occurrences torenderer!Comment #58
manuel garcia commented0_o
Alright then, let's see what the bot says... addressing #54 and #57.
Comment #59
mile23Followup for proper IoC injection of renderer service: #2834982: Replace non-test usages of \Drupal::service('renderer') with IoC injection
Comment #63
mile23Reroll of #58. There are still a ton of comment usages.
Comment #65
mile23Try again...
Comment #66
zeip commentedLooks otherwise good, but this patch should not change any documentation: Now the patch makes a change to a comment in core/lib/Drupal/Core/Menu/menu.api.php, which is in scope for #2834889: Replace documentation and string references to drupal_render() . So basically, if that's removed this should be ok. Changing back to Needs work.
Comment #67
mile23There were a couple other doc changes, as well. Removed those.
Comment #68
zeip commentedSorry, I missed one more thing in the previous review: In core/modules/views_ui/src/Form/BreakLockForm.php the array syntax has been changed from the short syntax to array(). AFAIK this is against the D8 coding standards, was there a specific reason for this? If not, the syntax should probably be changed back and only the called function changed.
The few other documentation changes were a good catch, didn't notice them on the first run! Thanks for the quick update of the patch. Changing back to Needs work pending the array syntax thing. I think we should be done after clearing that up.
Edit: Just noticed that it has been previously array() also in the core code, so the array syntax thing was actually probably only a re-roll mistake, and there wasn't any reason for it. Let's fix that, sorry for not noticing it on the first review.
Comment #69
mile23If you look at the testbot results for the last patch, you'll see that it agrees with you about the array syntax. :-)
Amended here.
I couldn't find any other occurrences of array() in the patch.
Comment #70
zeip commentedThat's true, the testbot apparently also noticed it :)
Everything seems to be in order now, so marking the issue RTBC. Thanks for all the hard work!
Comment #72
lauriiiI searched for usages of drupal_render() and all of the existing instances are mentions in the documentation, exception messages or api.php files so this looks good for me.
Committed 7f27bba and pushed to 8.4.x. Thanks!
Comment #73
lauriii