Problem/Motivation
Twig allows to create variables inside the templates using the set command. When one of these variables is used as an Attribute, the rendering of this attribute throws the following error:
Error: Call to undefined method Twig\Markup::render() in Drupal\Core\Template\Attribute->__toString() (line 329 of core/lib/Drupal/Core/Template/Attribute.php)
Steps to reproduce
Add this code into one of your twig templates (eg. page.html.twig)
{% set test_attr %}
This is a test
{% endset %}
{%
set attributes = create_attribute()
.setAttribute('data-test', test_attr)
%}
{{ attributes }}
Expected result would be to display data-test="This is a test".
Current result is a fatal error.
Proposed resolution
In \Drupal\Core\Template\Attribute::createAttributeValue(), expand the condition on instances of MarkupInterface to be true on instances of \Stringable objects.
| Comment | File | Size | Author |
|---|
Issue fork drupal-3537801
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:
- 3537801-fatal-error-when
changes, plain diff MR !12831
Comments
Comment #3
duaelfrComment #4
smustgrave commentedWhat happens though if you add markup like
Comment #5
duaelfrThe Attribute object already filters HTML from values so that shouldn't be an issue. I believe this is covered by some tests.
Comment #6
smustgrave commentedGotcha, then seems like a fine change. The test only run is also showing https://git.drupalcode.org/issue/drupal-3537801/-/jobs/5996750
Comment #7
rajesh.vishwakarma commentedIt working fine after adding the patch. I tested with Drupal 11.2.2
RTBC +1
Comment #8
pdureau commentedI am not comfortable with the starting point, because this is not supposed to happen:
For a simple string like that, this Twig syntax is available:
But I am OK with the change, replacing
($value instanceof MarkupInterface)by($value instanceof Stringable), because:MarkupInterfaceextendsStringable.I will wait a bit, to not rush, and I will merge if no objections.
Comment #9
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 #10
smustgrave commentedWas a clean rebase.
Comment #13
catch#8 is a good explanation for this being OK.
I updated an inline comment via gitlab suggestions just above the change here - it was still talking about 'safe string' objects which was an early Drupal 8 concept that eventually became MarkupInterface. We're slowly moving towards Stringable elsewhere and this is consistent with that, the conversion from markup to plain text happens immediately after that line, so any HTML in there will be escaped - we're not actually using MarkupInterface to preserve markup in this specific case, it's just saving people casting them to string (and escaping) themselves.
Comment #16
pdureau commented