- Issue created by @sea2709
- Assigned to Christian.wiedemann
- π©πͺGermany Christian.wiedemann
christian.wiedemann β made their first commit to this issueβs fork.
- π©πͺGermany Christian.wiedemann
This is a core issue. The component is rendered inside a form field which is not mapped by ui patterns.
Or I am wrong?
- Status changed to Postponed: needs info
7 months ago 5:26pm 20 September 2024 - π«π·France pdureau Paris
Indeed, it doesn't look like an UI Patterns issue, because this snippet uses stuff we are trying to avoid with UI Patterns 2:
- Twig blocks and embeds, especially when used without "only" keyword (but we may address this later: π [2.0.0-alpha3] Replace component() function by native Twig mechanisms? Active )
|raw()
filter
{% embed 'careerforce_skin:sdc-button' with { text: attributes.value|raw, variant: variant} %} {% block children %} {{ children }} {% endblock %} {% endembed %}
So this may be a "support request".
What are the
careerforce_skin:sdc-button
component definition & template? - Issue was unassigned.
- πΊπΈUnited States sea2709 Texas
Thanks for your response. Not sure if my implementation is correct. The idea is I would like the submit buttons are rendered by using a button SDC component, so that's why I created a twig template file input__submit.html.twig and rendered the button component here.
This piece of code went well on UI Patterns 2.0.0-beta1, I only encounter the invalid component exception after I upgraded to beta2.
{% embed 'careerforce_skin:sdc-button' with { text: attributes.value|raw, variant: variant} %} {% block children %} {{ children }} {% endblock %} {% endembed %}
I did some debugging and this is what I found
On beta-1, during the component validation process, the
props
variable has 2 propertiesvariant
andtext
On beta-2, during the component validation process, the
props
variable has 3 propertiesvariant
,text
andattributes
I thinkattributes
should be an object or an array, not a string. I guess maybe somewhere on UI Patterns 2-beta2, the attributes prop is converted to a string - π«π·France pdureau Paris
You are getting an error which was "fixed" by π [2.0.0-beta2] Attributes normalization Fixed
The root cause is triggered SDC's ComponentValidator::validateProps() which is calling a dependency method which is executing json_encode() which is casting the attribute object into a string.
So, this issue is fixed with a SDC render element alteration by UI Patterns 2, but you are still getting it. Why?
Maybe because you are using
{% embed 'careerforce_skin:sdc-button' with { text: attributes.value|raw, variant: variant} %}
which is not triggering the SDC render element.In this order:
1. Because you are not passing
attributes
, you can start by adding theonly
keyword. Non tested proposal:{% embed 'careerforce_skin:sdc-button' with { text: attributes.value|raw, variant: variant} only %}
. See: https://twig.symfony.com/doc/3.x/tags/embed.html2. If you still have the issue or if you want to pass attributes to the component, make it explicit and convert to array. Non tested proposal:
{% embed 'careerforce_skin:sdc-button' with { attributes: attributes.toArray(), text: attributes.value|raw, variant: variant} only %}
3. If you still have the issue, replace Twig
embed
andblock
by acomponent()
function. Non tested proposal:{{ component( 'careerforce_skin:sdc-button', { text: attributes.value|raw, variant: variant }, { children: children } ) }}
Is it helping?
- πΊπΈUnited States sea2709 Texas
Thanks @pdureau,
It's helping! This code works for my case on beta2, with and without only!
{% embed 'careerforce_skin:sdc-button' with { attributes: attributes.toArray(), text: attributes.value|raw, variant: variant} only %}
Thank you for your help! I guess I need some time to digest your response, I'm a little bit exhausted at this moment, but I'm glad that it works :-)
- πΊπΈUnited States smustgrave
So I'm reopening this one as I'm noticing this when using patterns from a view
Using ui_suite_uswds 4.0.x branch
ui_patterns latest beta.
For ease I duplicated the admin content view and removed the admin part from the new url so it uses the front end theme.
ui_pattern-devel must be uninstalled.I now get a fatal error
The error I believe is because the #value key is an attribute object now.
- π«π·France pdureau Paris
Let's target the next beta
However, I am still not reproducing the issue.
- ui_suite_uswds 4.0.x branch >> OK, i am at
commit 544dfaa4704bf2b3dca5faeb794277777264dee1 (HEAD -> 4.0.x, origin/HEAD, origin/4.0.x)
- duplicated the admin content view and removed the admin part from the new url so it uses the front end theme. >> OK, I have
duplicate_of_content
view with/content
page display - ui_pattern-devel must be uninstalled >> OK,
ui_pattern_devel
is not installed
Other information about my environment:
- Drupal version : 11.0.4
- PHP version : 8.3.12
- DB driver : sqlite
- Drush version : 13.2.0.0
- Web server: PHP Built-in web server
- ui_suite_uswds 4.0.x branch >> OK, i am at
- πΊπΈUnited States smustgrave
Will try and gather additional steps but it's reproducible for me 100% of the time.
Though I believe the bug lies with core or views
- πΊπΈUnited States smustgrave
Fresh install
Drupal 11.0.5
Drush 13
Php 8.3
Ui suite uswds 4.0.x
Ui patterns beta3Install all needed files
Leave ui patterns devel offEnable theme, using CDN to pull USWDS library in
Go to admin/structure/views/view/content
Duplicate the page
Change URL from admin/content/node to content/nodeNeed to have at least 1 piece of content
Go to the page and see the errors.
- π«π·France just_like_good_vibes PARIS
hello,
i am debugging your problem,
first thing i found, in fileform-element-label.html.twig
,{%- set attributes = attributes.setAttribute('title', title) -%}
the title is provoking a bug on my instance. if you replace "title" by "title|render", it works.
Second thing i found, in file
views-view-table.html.twig
,
line 140{% set prepared_columns = prepared_columns|merge([ pattern('table_cell', { 'attributes': column.attributes.addClass(column_classes), 'content': { '#markup': column_content }, 'active': active }) ]) %} {% endfor %}
the attributes injected are containing (at twig render time), an invalida value at key "headers".
add.removeAttribute('headers')
at line 142, after.addClass(column_classes)
and it will work. - πΊπΈUnited States sea2709 Texas
Not sure if it's helpful. In my case, I noticed that the component SDC-button I created hasn't been processed by the function "processAttributesProp" in ComponentElementAlter.php , while the other components have. I only see only button component encounters this issue. In my case, I don't think it's because of views, will share more information when I figure out something!
- π«π·France pdureau Paris
We will:
- Merge
LinksPropType::normalizeAttributes()
inAttributePropType::normalize()
- Call
AttributePropType::normalize()
fromLinksPropType::normalize()
- Add to
AttributePropType::normalize()
some logic about attribute value being list and not associative array - Add to
AttributePropType::normalize()
some logic about renderable interface & stringable interface inspired bySlotPropType::convertObject()
(if possible, implement this inStringPropType:normalize()
and call it)
- Merge
- Merge request !250Issue #3474822 by pdureau, sea2709, smustgrave, just_like_good_vibes: Normalize attributes values β (Merged) created by pdureau
- π«π·France pdureau Paris
So:
DONE in commit b32351950f6:
- Merge
LinksPropType::normalizeAttributes()
inAttributePropType::normalize()
>> - Call
AttributePropType::normalize()
fromLinksPropType::normalize()
DONE in commit 4ed020f26eda:
- Add to
AttributePropType::normalize()
some logic about attribute value being list and not associative array - Add to
AttributePropType::normalize()
some logic about renderable interface & stringable interface inspired bySlotPropType::convertObject()
So, I hope we addressing the 2 issues met by Steven from this ticket:
- the error because of the 3 levels attributes object structure (coming from Views I guess), it will be normalized according to Drupal attribute object normalization OR as a JSON value
- the error because of a render array as attribute value, it will be normalize also be normalized as a JSON value (
(JSON encoding is only for extreme use case, most iof the normalization do'nt rely on this workaround)
About Dang Tran feedback:
Not sure if it's helpful. In my case, I noticed that the component SDC-button I created hasn't been processed by the function "processAttributesProp" in ComponentElementAlter.php to convert the attributes object type '\Drupal\Core\Template\Attribute' into an array, while the other components have. I only see only button component encounters this issue. In my case, I don't think it's because of views, will share more information when I figure out something!
Interesting, maybe the logic of ComponentElementAlter::processAttributesProp() can also move to
AttributePropType::normalize()
.Anyway, I don't know what is happening with those
{% embed %}
thingy. Maybe we will need to revamp this hacky part of the SDC API next year, moving some logic from the TwigNodeVisitor to the Render Element. - Merge
- π«π·France just_like_good_vibes PARIS
super nice job ! i like the treatment attribute is receiving, because we know it will receives a lot of weird data over time,
mainly calls from twig with variables having values not trivial.
i just have a few remarks to help finish the attribute normalization/sanitization.when you normalize a list of values in
normalizeList
, only the case of an array is covered.
i would add maybe two cases :
- important : a is_object test inside this function to callnormalizeObject
- less important : when the value inside a list is an array, imagine this is render array. the caller intuitively would like it to be rendered. this may never happens :) why not try to trigger a rendering ?sometimes
json_encode
may produce unexpected results (memory error or ?), for example if there are objects inside the values we are trying to json_encode. This is maybe too much good attention and intentions to the persons which are adding bad values inside attributes.Why censuring the code to call "render" inside the
normalizeMapping
function ? - π«π·France pdureau Paris
Why censuring the code to call "render" inside the normalizeMapping function ?
Because I don't know how to test it in
AttributesPropTypeNormalizationTest
:)Sometimes json_encode may produce unexpected results (memory error or ?), for example if there are objects inside the values we are trying to json_encode. This is maybe too much good attention and intentions to the persons which are adding bad values inside attributes.
Yes, I am nice guy here :) I add a depth limit?
json_encode(mixed $value, int $flags = 0, int $depth = 512): string|false
when you normalize a list of values in normalizeList, only the case of an array is covered.
i would add maybe two cases :
- important : a is_object test inside this function to call normalizeObjectGreat idea.
- less important : when the value inside a list is an array, imagine this is render array. the caller intuitively would like it to be rendered. this may never happens :) why not try to trigger a rendering ?
So, related to my issue with
AttributesPropTypeNormalizationTest
. I don't know how to mock a service. - πΊπΈUnited States sea2709 Texas
Looks like the error is still presented on my local. I'll have sometime tomorrow, I'll dig into it!
- π«π·France pdureau Paris
Sometimes json_encode may produce unexpected results (memory error or ?), for example if there are objects inside the values we are trying to json_encode. This is maybe too much good attention and intentions to the persons which are adding bad values inside attributes.
β Depth limit added.
when you normalize a list of values in normalizeList, only the case of an array is covered.
i would add maybe two cases :
- important : a is_object test inside this function to call normalizeObjectβ Test added.
Why censuring the code to call "render" inside the normalizeMapping function ?
- less important : when the value inside a list is an array, imagine this is render array. the caller intuitively would like it to be rendered. this may never happens :) why not try to trigger a rendering ?
Because I don't know how to test it in
AttributesPropTypeNormalizationTest
:) - πΊπΈUnited States sea2709 Texas
I spent some time to debug the issue, and was able to reproduce this bug on a fresh D11 install.
Drupal 11
UI Patterns 2.0.x-dev
Uninstall UI Patterns Devel off
UI Suite DaisyUI 4.0.0-alpha2I updated the template file
web/themes/contrib/ui_suite_daisyui/templates/menu/menu--account.html.twig
as{% for item in items %} {{ include('ui_suite_daisyui:button', { label: item.title, url: item.url.toString() }, with_context = false) }} {% endfor %}
I see that when I render a component in a twig template file, that component doesn't go through the #pre_render process, so attributes prop isn't processed. As a result, the component validation is failed since the attribute prop is a string, but in the schema, attribute prop is an object with the prop type as
ui-patterns://attributes
- πΊπΈUnited States smustgrave
So I switch to this branch on 4.0.x branch of USWDS same scenario in #15 and no fatal error!
-
just_like_good_vibes β
committed 94f5d3d1 on 2.0.x authored by
pdureau β
Issue #3474822 by pdureau, sea2709, smustgrave, just_like_good_vibes:...
-
just_like_good_vibes β
committed 94f5d3d1 on 2.0.x authored by
pdureau β
- πΊπΈUnited States sea2709 Texas
Looks like if I use include function in twig file, I still run into a fatal error. I saw your comment on https://www.drupal.org/project/ui_patterns/issues/3481860 π¬ Components require attributes prop defined Active about using component function instead of include and embed twig function?
- π«π·France pdureau Paris
Twig's
include
&embed
are not currently a good way to embed components, because they don't trigger the SDC render element. Passing through the render element is an important par of the rendering pipeline.So, we have 2 possibilities:
- right now, using the UI Patterns 2.x specific
component(string $component_id, array $slots = [], array $props = [])
function - later, enjoying a fix in SDC Core implementation in order to make
include
&embed
trigger the render element. We will first experiment this solution in UI Patterns 2.x ( π [2.0.0-alpha3] Replace component() function by native Twig mechanisms? Active ) and we plan to move the fix to Core: π Trigger SDC render element when using Twig include or embed Active
- right now, using the UI Patterns 2.x specific
- πΊπΈUnited States sea2709 Texas
Thanks @pdureau for the updates.
Look forward to errors free when using functions from SDC core! In the meantime, I will use component function :-)