Problem/Motivation
In UI Suite Bootstrap, in the table component, there is:
{% if caption %}
<caption>{{ caption }}</caption>
{% endif %}
The table presenter template is passing an empty string as the caption variable.
But in the component template I have an array with an empty #children.
In ui_patterns/src/Plugin/UiPatterns/PropType/SlotPropType.php, there are 2 problematic places :
if (is_string($value)) {
return ['#children' => Markup::create($value)];
}
After making the proposed change I obtain an empty array with #cache from:
protected static function cleanRenderArray(array $value): mixed {
if (empty($value)) {
// Element::isRenderArray() returns FALSE for empty arrays.
return ['#cache' => []];
}
Steps to reproduce
Using UI Suite Bootstrap, create a View using a table display.
Proposed resolution
if (is_string($value) && !empty($value)) {
return ['#children' => Markup::create($value)];
}
I don't know what to do about the other place where there is a problem.
Remaining tasks
Comments
Comment #2
pdureau commentedComment #3
smovs commentedComment #5
smovs commentedHi @grimreaper
I have added a check for a non-empty value according to your proposal.
But I'm still confused about this false positive when checking slots.
E.g. I set the caption in the table with wysiwig source with an empty textarea.
In this case, the table contains an empty caption tag because wysiwig source creates an array with text format settings.
It would be cleaned by self::cleanRenderArray(), but didn't
I am not sure if it is related to the false positive that you mentioned. Probably I went the wrong way.
Comment #6
grimreaperHi @smovs,
The problem occurs for example when using the table component with the views table presenter template.
If you are using a component "manually" or with site building it is ok.
But with a presenter template, like written in the issue summary, you can get an empty string as slot value and in this case the problem occurs.
So, to test you can create a view using the table display (not component display using the table component).
Comment #7
pdureau commentedComment #8
smovs commentedHi @grimreaper
Sorry for the delay.
What I found.
From my point of view, rendering works as expected in general, because:
When we check if
$valueis empty and set it['#cache' => []], we create a non-empty array. It means we redefine the variable from non-array to array in this case. SeeSlotPropType::normalizeIn Twig template, when we check
{% if caption %}is always true because in this case, we pass a non-empty array.I am not fully understanding the purpose of the forced setting
['#cache' => []]each time.I added screenshots for better understanding
Comment #9
pdureau commentedComment #10
grimreaperHi @smovs,
Yes, and that's the purpose of this issue, we should be able to keep a simple if statement in Twig and having check as expected. We don't want an empty caption to appear.
That's what needs to be challenged.
Note: I can't reassign the issue to you.
Comment #11
smovs commented@grimreaper
Thank you for the clarification. I will take a look on this weekend
Comment #12
pdureau commentedComment #13
smovs commentedHi team!
Please review my changes to fix the issue with false positive when checking empty slots.
Comment #14
pdureau commentedComment #15
grimreaperThanks @smovs !
Tested on the encountered case of empty caption in views table: OK
@pdureau, should we let Christian or Mikael merge?
Comment #16
pdureau commentedComment #17
just_like_good_vibeshello,
sorry trimming here is not appropriate :)
we need to cope with this edge case in a better way.
Comment #18
just_like_good_vibesComment #19
pdureau commentedi agree there is something to do: a string resolving as a false boolean (so, empty) must become a renderable resolving as a false array (so, empty)
However, we have already stated than SDC validator is sometimes confused by an empty slot: https://git.drupalcode.org/project/ui_patterns/-/blob/2.0.x/src/Element/...
So maybe it is a 2 steps fix: first fix at SDC level, then do something like that (naive, not tested, proposal):
Comment #20
pdureau commentedComment #21
smovs commentedHi all!
@pdureau
Your approach in #19 has an edge case with the string
"0". We need additional checking for it.empty("0")returnTRUESee here stackoverflow
Comment #22
just_like_good_vibesComment #23
smovs commentedComment #24
smovs commentedHi team!
I've updated the condition for the string normalization to replace trimming with empty().
Please review
Comment #25
pdureau commentedthanks @smovs
Comment #26
just_like_good_vibesComment #27
pdureau commentedComment #28
just_like_good_vibeshello, sorry to come late on that one, but testing for '0' seems not appropriate neither.
it doesn't make sense on the PHP side. any other thoughts, like pdureau?
Comment #29
smovs commentedI will try to figure out how to find a better approach
Comment #30
smovs commentedHi guys! I changed my approach to checking NULL values in normalize. Please review.
Comment #31
pdureau commentedIs a normalization tests enough? We may need an other specific test here.
Also, just thinking aloud, but the removal of
['#cache' => []]may be harmful. My memories are blurrry but we may have added that to prevent an empty render array to be processed as a list instead of a mapping in Twig.Let's discusss