Render the value of #type => 'path' form elements

Created on 1 October 2014, about 10 years ago
Updated 18 February 2023, almost 2 years ago

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

  1. 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
  2. Supply a valid path, e.g. `/node/1` and save the form
  3. 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.

πŸ› Bug report
Status

Needs work

Version

10.1 ✨

Component
FormΒ  β†’

Last updated 1 day ago

Created by

πŸ‡ΈπŸ‡ͺSweden Arla

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    public static function preRenderTextfield($element) {

    Should this be typehinted?

    Can we remove the change to drupalci.yml

    #52 will need to be addressed also, possible follow up?

  • πŸ‡©πŸ‡ͺGermany lrwebks Porta Westfalica

    We're having another strange behavior around the path element using '#convert_path' => PathElement::CONVERT_NONE, the value of $element['#value'] is always the #default value and not the actual value when submitting the form. I also checked this within public static function validateMatchedPath(&$element, FormStateInterface $form_state, &$complete_form) in PathElement.php

    Can someone confirm this and is this related? Thanks!

  • πŸ‡©πŸ‡ͺGermany lrwebks Porta Westfalica

    Case dismissed as we have found the reason that is actually not related to this at all. Thanks anyway!

Production build 0.71.5 2024