Closed (fixed)
Project:
Drupal core
Version:
11.x-dev
Component:
theme system
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Reporter:
Created:
7 Sep 2014 at 10:16 UTC
Updated:
12 Jan 2026 at 10:31 UTC
Jump to comment: Most recent, Most recent file


Comments
Comment #1
joelpittetTranslation is trying to avoid dealing with complex objects. There are comments to that effect. Can we render the render array before providing it the trans block's context?
It's intended to work as the t() does as much as possible and same for t() it won't render a Renderable Array. If we do need to support render arrays in trans (which I kinda hope we don't). Maybe we should do that at the t() level?
Comment #2
joelpittetIs this the error you are getting BTW?
TwigTransTokenParser:105?
Or am I wrong in that assumption?
Comment #3
berdirNope, I got warnings from checkPlain(), so it apparently it is passing it right through.
I don't really agree with your argumentation :) t() does not and IMHO should not treat render arrays specially because nothing on the PHP side does. There you need to know if you have a render array, an object or a string. You can't do 'some string' . $render_array anywhere.
However, isn't twig supposed to hide those differences? If it would be a different syntax inside a trans element then it might make sense, but it is the same {{ something }} that handles render arrays just fine outsided. @effulgentsia also assumed that it would work, see his comments in the referenced issue.
Comment #4
joelpittetSo you do agree with my argument:) That's what I'm saying :P We shouldn't treat render arrays specially. I just mentioned that an option, though I don't agree it's the right way and would be undone when we go Renderable Objects in the future.
Twig does hide those difference by finding print statements
{{ var }}and wrapping that fromprint $var;toprint twig_render_var($var);Which internally finds render arrays and calls drupal_render() on them.But inside trans block it was prevented from using complex objects and filters because it was tricky for whomever was writing it to deal with all the cases.
It is a bit confusing as those tokens look like print, so I agree it's a bit confusing. Actually a good person to get some context on this would me @Mark Carver. Let's see if he can shed some light.
Comment #5
star-szrComment #6
fabianx commentedAll we need to do here is replace t($x) with t(twig_render_var($x)) in the output.
I am not worried about the performance impact anymore, which would be the only reason _not_ to do this ...
This should be a simple search+replace patch and some little work on tests.
Comment #7
wim leersThis problem came up in #2450993-140: Rendered Cache Metadata created during the main controller request gets lost.
Comment #8
thenchev commentedHere is a start.
Comment #9
thenchev commentedComment #11
wim leersIs this still actually a problem? I'm not sure I fully understand what the issue is about.
Comment #12
star-szrYeah definitely needs an IS update. I think the issue is that if fluffy_kittens is a render array, this doesn't work:
Comment #13
fabianx commented#12 is correct.
Comment #14
calebtr commentedPer IRC chat with joelpittet, I'm changing #8 to remove the ::escapeFilter method and use ::renderVar() instead
Comment #16
thenchev commentedFixed wrong argument.
Comment #18
joelpittetComment #19
xjmThanks for tagging this for rc target triage! To have committers consider it for inclusion in RC, we should add a statement to the issue summary of why we need to make this change during RC, including what happens if we do not make the change and what any disruptions from it are. We can add a section
<h3>Why this should be an RC target</h3>to the summary.Comment #20
thenchev commentedSo so far i removed some unneeded arguments that were left over from escapeFilter() and added test for render array. Looking for some feedback on improving this.
Comment #21
thenchev commentedComment #23
thenchev commentedLets see what this breaks.
Comment #24
slashrsm commentedFew comments. 1. and 2. from my IRC discussion with @chx.
dont break the scalar optimization
can we use " instead of \' ?
Let's not introduce unrelated changes.
Comment #25
thenchev commentedFixes from #24
Comment #26
dawehnerThis is super odd ... given that this invalidates a lot of documentation of the method. Now the __toString() method is no longer called
Comment #27
dawehnerAh actually the behaviour is right, that interface is already markup, so it should not be cast to a string, as this looses information.
What about doing something like escapeFilter() which is :
so also check for
\Twig_Markup?Comment #28
slashrsm commentedComment #29
thenchev commentedremoved one more unrelated change and added
\Twig_MarkupComment #30
dawehnerIMHO a dedicated test for
render($MarkupInterfaceObject),/code> would be niceComment #31
thenchev commentedAdded test for markup.
I found later TwigExtensionTest where i could have added the check, don't have enough time now.
Comment #32
dawehnerMH, that feels wrong, I thought more about using render_var() directly?
Comment #33
thenchev commentedRemoved the last test for markup and added a new one that directly tests if renderVar is returning the markupinterface obj.
Comment #34
joelpittetThank you @Denchev
Has tests for renderable arrays and
FormattableMarkup(forMarkupInterface).I'll add a change record.
Comment #35
joelpittetHere's a CR: https://www.drupal.org/node/2615198
Comment #36
andypost@joelpittet please provide example what will work in CR because now it confusing
Comment #38
joelpittet@andypost That example worked when I tried the CR example. Which part is confusing?.


Before:After:I just chucked the snippets in bartik's
bartik_preprocess_node()andnode.html.twig.Comment #39
andypostRTBC++
@joelpittet sorry, looks I misread "s/now/not" - thanx a lot for screens, added to summary
Comment #40
alexpottGiven that #2226493: Apply formatters and widgets to Node base fields got fixed without this I'm not sure this is a bug. As far as I can see we should only put this into 8.1.x. The patch seems to be missing documentation and a change record.
Comment #41
xjmhttps://www.drupal.org/node/2615198 was just missing the reference to this issue so I added that.
Asked @alexpott what he meant about needing documentation and he clarified that there is no update to API documentation. Setting NW for that.
Comment #42
xjmI was also wondering if it makes sense for markup objects and render arrays to be lumped together in this issue? It seems like in general we have an expectation that markup objects should be usable anywhere we would use a string in rendering, but that render arrays are another whole can of worms (which is why #2505497: Support render arrays for drupal_set_message() was not accepted).
Comment #43
berdirThis issue started as support for render arrays, it existed before we had markup objects :)
Yes, render array are a different thing on the PHP side. But that's not true for Twig templates. You can do {{ whatever }} with anything, almost anywhere. Isn't it kind of the goal that themers don't have to know about render arrays?
I'm fine with pushing this to 8.1.x. But note that #2226493: Apply formatters and widgets to Node base fields had to use drupal_render() in preprocess to avoid this. That's very hard to understand for themers and it's also inefficient, we render those things all the time, even if we don't use them in the template. That said, I guess these days you could also use whatever|render but that's not exactly straight forward either :)
Comment #44
joelpittet+1 to #43.
I'd like Twig to deal with render arrays when printing in all cases.
Comment #45
lauriii+1 for making #43 in a follow-up!
Comment #46
lauriiiWe have CR, latest patch applies still so I think this is RTBC.
Comment #47
alexpottLooking at this I still feel it is missing documentation - however looking at this the only place where
{% trans %}is in core/lib/Drupal/Core/Language/language.api.php and I'm not sure this is appropriate for there. We're missing a place to put documentation for how Drupal integrates with Twig and our customisations - we should have a place to document things like|withoutand{% trans %}. So let's not try and add this here.I guess we should also file a followup to remove the
drupal_render()added totemplate_preprocess_node()in #2226493: Apply formatters and widgets to Node base fields.I've thought a lot about security implications of this patch and I don't think it changes anything even though we've changed
TwigExtension::renderVar(). That said I think we should improve the@returndocumentation ofTwigExtension::renderVar(). Currently it is:I think it should it is either a scalar, MarkupInterface or Twig_Markup.
Comment #49
andypostComment #50
andypostStill need to address #47
Comment #51
agoradesign commentedIf this change will be committed, is there a chance to push it to 8.1.x too? It seems, that Entity API will need this work -> https://github.com/fago/entity/pull/38. If yes, than I guess only before rc1 in 2 weeks...
I don't know, if there's a possible workaround within Entity API. I only fear the following scenario:
Commerce 2.x (that will be a very important D8 module) depends on 8.1.x as well as on Entity API 1.x. Currently, the pull request for making Entity API 1.x fit for 8.1.x, only passes tests, when the patch from this issue is applied => neverending patching and patch re-rerolling until 8.2.x is released
Comment #52
berdirAs commented over there, the fact that the entity module relied on this is a bug, a bug that is fixed in the Pull request that you linked.
It would still be very nice to see this fixed, but this does not block entity or commerce in any way.
Comment #53
agoradesign commentedThanks 4 clarifying. I've mixed up the two patches/issues you mentioned in the PR. @bojanz already told me in a Commerce issue thread. However, I agree that this one looks also very useful in general.
Comment #56
joelpittetHere's a review
This line shouldn't be needed at all. In the line below
if (is_object($arg)) {condition it should be covered by the__toString()check that is already in there which covers both the interface and theTwig_Markup.nit: can we put
<strong>for html5?Comment #57
joelpittetHere's the changes I mentioned in #56, had to change the test because it was expecting the object though
renderVarwill render it as the method name suggests.Tested locally and it seems to work, let the testbot double check.
Comment #60
joelpittetHmm I'll dig in deeper into the fails, it looked like that was needed, thanks for automated test coverage.
Comment #61
star-szrJust attempting a reroll of #57, no changes.
Comment #63
joelpittetSorry I fell in a rabbit hole and then saw a bunny. Thanks for picking this up @Cottser
Comment #65
paul_canning commentedAny update on this issue?
Looks like the latest patch failed for 8.4.
Comment #67
darvanenComment removed. Sorry, wrong issue.
Comment #69
manuel garcia commentedRerroll of #61
Comment #71
manuel garcia commentedReferencing the "drupal_core" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.Attempting to fix these errors...
Comment #76
golddragon007 commentedIt's not possible still to use |function on a variable within trans...
Comment #80
webflo commentedRe-roll #71.
Comment #82
webflo commentedComment #86
duaelfrRerolled #82's patch on D9.5 and fixed tests (I hope)
(This patch applies on 9.4 too)
Comment #88
duaelfrRerolled on 10.1.x
Comment #89
duaelfrI should have trusted @webflo in the first place :)
Bringed back the code I removed in #86 and fixed tests accordingly.
The attached patch is for people that needs this for D9 right now.
Comment #91
ravi.shankar commentedTried to fix the failed test of patch #89.
Comment #95
godotislateRebased MR against 11.x, and h/t alexpott for changing MR target branch.
Changed to use an inline template test instead. All tests passing now.
Comment #96
godotislatePer note from alexpott on Slack, pushed commits to clean up some todos around this issue.
Comment #97
smustgrave commentedSo tested this by kinda following the CR (which updated the version numbers)
Copied
$variables['render_array'] = [
'#prefix' => '',
'#markup' => 'trans render array',
'#suffix' => '',
];
Into olivero_preprocess_page_title and placed
{% trans %}
This is a {{ render_array }}.
{% endtrans %}
In the page_title.html.twig file.
Got a fatal error
Applied the MR
Now the error is gone and "This is a trans render array" appears just fine.
Comment #99
quietone commentedUpdating credit
Comment #100
quietone commentedI read the comments, the MR and the CR. I didn't seen any unanswered questions. I don't see a review of the change record and I made an edit anyway so I am tagging for that for review.. There is one question in the MR.
Comment #101
godotislateAddressed MR comment. I also removed custom assert messages per #3131946: [policy] Remove PHPUnit assertion messages when possible, and standardize remaining messages in the tests.
Also updated the CR and the issue title, because I think the word "placeholder" is confusing. Not sure exactly what Twig's terminology is for
{{ ... }}syntax, but from the docs, there's this:I've updated language in this issue title to replace "placeholder" with "expression" or "rendered expression" for lack of better terminology.
Comment #102
smustgrave commentedFeedback appears to be addressed on the MR and CR reads fine and the example helps a lot.
Comment #103
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #104
godotislateNot sure what the NR bot was on about, but rebased.
Comment #106
nod_Committed and pushed 2c8c0a2efb2 to 11.x and 2042dcf3a4f to 11.2.x. Thanks!
Comment #110
nod_Comment #113
murzFaced fatal errors in custom Twig templates on several websites after upgrading to Drupal Core with this change, because the Twig function "render" started to return an object instead of a string for translated strings. Reported a separate issue #3556376: The Twig "render" function started to return TranslatableMarkup object instead of string for translations about this.
Comment #114
plopescWe also experienced a similar issue with several views where we used the custom twig template using the rewrite option feature.
We has scenarios like
{{ unpublished_on|render|format_date('long') }}that suddenly throw a WSOD page.For us, we solved it doing
{{ unpublished_on.__toString()|format_date('long') }}.Comment #115
grevil commentedIndeed, these fixes caused many fatal errors for some of our customers sites. I escalated #3556376: The Twig "render" function started to return TranslatableMarkup object instead of string for translations.