The path element was added in
#2321745: Add #type => 'path' that accepts path but optionally stores URL object or route name and parameters β
. It will, by default, convert the value to an array representing a route:
// core/lib/Drupal/Core/Render/Element/PathElement.php: 75-81
if ($element['#convert_path'] == self::CONVERT_ROUTE) {
$form_state->setValueForElement($element, [
'route_name' => $url->getRouteName(),
'route_parameters' => $url->getRouteParameters(),
]);
return;
}
There is no handling in place to convert it back to a path when rendering the element. Supplying such an array as #default_value
will yield "Array to string conversion" notices.
The only current core usage of the path element is in the Contact Form edit form, where conversion is disabled, so the stored value is a string. The existing test PathElementFormTest.php is a kernel test which doesn't attempt to render the element.
Steps to reproduce
- Make a form that uses a path element with route conversion, e.g. applying
pathelement-2348279-debug.diff
which modifies the Contact Form to this end
- Supply a valid path, e.g. `/node/1` and save the form
- Load the form with the saved value
- Expected: The element contains the entered value,
/node/1
- Actual: There is an error message with an "Array to string conversion" notice, and the element contains garbage
Suggestion
The PathElement could override Textfield::preRenderTextfield()
to convert it back to a path:
public static function preRenderTextfield($element) {
if ($element['#convert_path'] == static::CONVERT_ROUTE) {
$element['#value'] = Url::fromRoute($element['#value']['route_name'], $element['#value']['route_parameters'])->toString();
}
return parent::preRenderTextfield($element);
}
Otherwise you have to do the same conversion in the form instead.
Url conversion
In the case of '#convert_path' => PathElement::CONVERT_URL
, modifying the Contact Form edit form as above is not sufficient to test the case. It will choke with an UnsupportedDataTypeConfigException
when trying to save a Url object to config.