Problem/Motivation
Some background: I have placed a ctools block, for a field based on a custom field type, which works almost as expected. The custom field type is extended from the text_long
field type in Core. Ordinarily, if the field is empty, then the block will not render. My understanding is that is the correct and desired behavior in general. I have not been able to successfully reproduce the below problem outside of this instance of my custom field type:
What's happening is that when the field is empty, despite the isEmpty()
method, as defined in the field type definition, returning TRUE
, the ctools block provides an empty field when building the block, which results in a block rendered without any content in it. The expectation is that the block wouldn't render at all since the field is empty. For the purposes of block rendering, an element is considered empty by the renderer if the element is either empty, or only contains the #cache
index. The build()
method in EntityField.php
adds a field
index to the element without checking whether the field is empty or not.
Proposed resolution
Add a conditional to check if the field is empty, before adding the field
index to the $build
variable, that way the renderer will consider the element empty if the field is empty, and continue to render content as usual if the field is not empty.
Remaining tasks
Needs review.
User interface changes
None.
API changes
None.
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#8 | interdiff-2804165-4-8.txt | 10.42 KB | phenaproxima |
#8 | 2804165-8.patch | 11.96 KB | phenaproxima |
#2 | add-empty-field-check-2804165-2.patch | 807 bytes | mroycroft |
#4 | interdiff-2804165-2-4.txt | 2.33 KB | hctom |
#4 | missing_check_for_empty-2804165-4.patch | 2.05 KB | hctom |
Comments
Comment #2
mroycroft CreditAttribution: mroycroft at Workday, Inc. commentedComment #3
mroycroft CreditAttribution: mroycroft at Workday, Inc. commentedComment #4
hctomI am experiencing a related issue with "empty" fields, which require a quite different solution:
Currently the
EntityField::blockAccess()
method only grants access to an entity field block, if the field has a value (by checking$entity->{$this->fieldName}->getValue()
). Unfortunately this returnsFALSE
in the case you have an image field that provides a default image, if no image is uploaded. The problem is here that the default image is added on the formatter level, so the field itself is considered empty, while it would output the default image.So my proposed solution is to render the field and check if there are actual renderable children by using
Element::children($build)
. If so, access to the block is granted. Otherwise access is forbidden and so the block won't even be rendered.See my attached patch for the solution.
Comment #5
mroycroft CreditAttribution: mroycroft at Workday, Inc. commentedThis seems like a more sensible approach to fix this issue. Code changes look fine, I haven't had time to manually test it.
Comment #6
japerryComment #7
DamienMcKennaPunting this to beta2.
Comment #8
phenaproximaW00t! I updated @hctom's patch in #4 with a test against an image field, plus a bit of refactoring. Sorry for the big interdiff; I moved ctools_block's functional test into PHPUnit.
Comment #10
EclipseGc CreditAttribution: EclipseGc commentedlooks good to me.