Entity forms are structured with field widgets nested under langcode keys:
$form['body']['fr'] = ...
$form['field_image']['und'] = ...
Those langcode subkeys are basically useless now, and do not determine in which langode the submitted values are stored: WidgetBase::extractFormValues() assigns values into the $items object that gets passed to it, how the form is structured doesn't change a thing.
- We should get rid of those langcode subkeys in the $form structure, we're not editing entities in multiple languages in the same form, core entity form controllers edit an entity in one single language. Within that language, some fields are translatable and some are not, that's it. It doesn't make a difference for the form structure.
- Even if some contrib module wanted to do "side editing in two languages in one form", it's then its responsibility to structure those forms accordingly.
At any rate, it's not the job of *widgets* to spit form $elements nested below a langcode subkey, as they do currently (see the end of WidgetBase::form()). Widgets generate "what it takes to edit this field", that's it. Multilingual structure, *if needed*, should be added on top of the result of $widget::form() by the calling code.
To which @plach replied:
Totally +1 on removing the langcode level in the form widget structures, it has always been a major source of troubles. I agree that for advanced use cases the implementing module should build its form(s) by assembling form widgets or possibily entire entity forms with their respective languages, as suggested in
Having the langcodes structure $form / $form_state when they are not needed:
- means chances of inconsistencies and weird behavior
- makes it vastly painful to change the language assignment logic if we need to (see ). Language assignment is internal, it should stay internal.
- Renames $form[$field_name][$langcode] to $form[$field_name]['widget'] in entity forms.
(see #10 item 2 for why we still need a separate sub-element below $form[$field_name])
- Removes the $langcode param in field_form_(get|set)_state(). Those functions are used internally to structure the processing data that each field places into $form_state and avoid clashes. Just like for $form, we don't need $langcode to be part of the default structure of $form_state. The code that builds the form can provide the additional structure it needs, if it needs one.
- Change of structure in entity $forms:
code doing form_alter() on those needs to be updated (see forum_form_node_form_alter())
tests doing drupalPost() / drupalPostForm() with field values on entity forms need to be updated
- field_form_(get|set)_state() lose their $langcode param.
PASSED: [[SimpleTest]]: [MySQL] 59,242 pass(es). View
FAILED: [[SimpleTest]]: [MySQL] 59,171 pass(es), 2 fail(s), and 0 exception(s). View