- πΊπΈUnited States tim.plunkett Philadelphia
Unfortunately this is a duplicate of #1300290: In drupal_render(), element_info is not merged recursively, preventing #type from serving its purpose β
RenderElements allow you to define "default" element properties through the getInfo()
method. Eventually when the element is rendered, each default propertiy is added to the render array only if it doesn't already exist.
However, this means that any of the callback properties (i.e. #process, #after_build, #validate, #element_validate, #pre_render, #post_render, #submit) defaults will be overwritten if a render array contains its own custom callback. Resulting in a loss of "default" functionality.
Take, for example, the entity_autocomplete render element from core. It has multiple #process and #pre_render callbacks defined in it's getInfo()
definition. It looks something like
[
// ... etc
'#process' => [
Drupal\Core\Entity\Element\EntityAutocomplete::processEntityAutocomplete,
Drupal\Core\Entity\Element\EntityAutocomplete::processAutocomplete,
Drupal\Core\Entity\Element\EntityAutocomplete::processAjaxForm,
Drupal\Core\Entity\Element\EntityAutocomplete::processPattern,
Drupal\Core\Entity\Element\EntityAutocomplete::processGroup,
],
'#pre_render' => [
Drupal\Core\Entity\Element\EntityAutocomplete::preRenderTextfield,
Drupal\Core\Entity\Element\EntityAutocomplete::preRenderGroup,
],
// ... etc
];
However if you create a render array of this type with your own #process and #pre_render hooks, they will overwrite the original defaults and your autocomplete widget won't work:
$element = [
'#type' => 'entity_autocomplete',
'#title' => 'Lookup Entities!',
'#target_type' => 'node',
'#selection_handler' => 'default:node',
'#selection_settings' => [
'target_bundles' => [
'page' => 'page',
],
'sort' => [
'field' => '_none',
],
'auto_create' => FALSE,
'auto_create_bundle' => '',
'match_operator' => 'CONTAINS',
],
// Remove these last two properties and the element will work
'#process' => [
// ... my custom process callbacks
],
'#pre_render' => [
// ... my custom process callbacks
],
];
Use Drupal\Component\Utility\NestedArray::mergeDeep()
to merge defaults instead. This will ensure that:
Testing, Tests, Approval
This may be seen as an API change, but IMO if there is code in core or contrib that uses this "feature" to disable or overwrite default behavior, that is to be considered hacking and abusing.
Closed: duplicate
9.5
Last updated
The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.
Not all content is available!
It's likely this issue predates Contrib.social: some issue and comment data are missing.
Unfortunately this is a duplicate of #1300290: In drupal_render(), element_info is not merged recursively, preventing #type from serving its purpose β