Problem/Motivation

Current field-api have provided hook_field_widget_form_alter and hook_field_widget_WIDGET_TYPE_form_alter, that allow modules to alter the field widget form element. However the field is wrapped by a "container" in WidgetBase::form function. And there has no hook alter to override the "container" attributes.

Proposed resolution

Introduce an alter hook in WidgetBase::form. This will provide other modules the option to hook into the building of an field widget form.

User interface changes

None

API changes

A new hook is introduced

Remaining tasks

- Add API documentations for hook_field_widget_form_container_alter and hook_field_widget_WIDGET_TYPE_form_container_alter into core/modules/field/field.api.php

Comments

jian he created an issue. See original summary.

jian he’s picture

Issue tags: +ChongQing Sprint
jian he’s picture

Status: Active » Needs review
StatusFileSize
new1.15 KB
jungle’s picture

Issue summary: View changes
Status: Needs review » Needs work
jungle’s picture

Issue summary: View changes

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dahousecat’s picture

Why does this need work? Patch in #3 works great for me.

msankhala’s picture

Issue tags: +Needs tests

I think we also need to add the test for this.

p4trizio’s picture

StatusFileSize
new4.14 KB

Patch based on #3, including documentation in field.api.php

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

ceonizm’s picture

Hello,

Patch #10 works fine for me

jian he’s picture

Issue tags: -ChongQing Sprint

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

chr.fritsch’s picture

After #2940201: hook_field_widget_form_alter() can no longer affect the whole widget for multi-value fields was committed, #2942097: Deprecate hook_field_widget_form_alter() in favor of hook_field_widget_multiple_form_alter() was proposed, but never happened so far.

So I think to prevent some hook mess, we should deprecate hook_field_widget_form_alter and hook_field_widget_multiple_form_alter in this patch.

chr.fritsch’s picture

I discussed this with @alexpott and we would like to propose the following plan:

1. Introduce hook_field_widget_complete_form_alter

This new hook makes it possible to alter the whole field widget form at the very end.

2. Deprecate hook_field_widget_multiple_form_alter

This hook is then not needed anymore and having it additionally would just be confusing. Also all use-cases catched by hook_field_widget_multiple_form_alter, can be realized with hook_field_widget_multiple_form_alter as well.

3. Rename hook_field_widget_form_alter

To prevent further confusion, we should rename hook_field_widget_form_alter to hook_field_widget_single_element_form_alter, by deprecating hook_field_widget_form_alter and introducing hook_field_widget_single_element_form_alter instead. We think hook_field_widget_single_element_form_alter is still useful because it allows you to just alter a single thing.

Also #2942097: Deprecate hook_field_widget_form_alter() in favor of hook_field_widget_multiple_form_alter() should be closed as “Wont’t fix”.

Thoughts?

amateescu’s picture

Sounds like a great plan to me! I'm not 100% sure about renaming hook_field_widget_form_alter to hook_field_widget_single_element_form_alter, but I guess I can live with it :)

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

chr.fritsch’s picture

Status: Needs work » Needs review
StatusFileSize
new26.28 KB

I probably missed some places, but I want to know how much tests are failing.

alexpott’s picture

  1. +++ b/core/lib/Drupal/Core/Field/WidgetBase.php
    @@ -119,7 +119,7 @@ public function form(FieldItemListInterface $items, array &$form, FormStateInter
    +    \Drupal::moduleHandler()->alterDeprecated('Implement hook_field_widget_complete_form_alter or hook_field_widget_WIDGET_TYPE_complete_form_alter instead.', [
    

    I think this should be like a proper deprecation message. Saying which version the hook is deprecated in and which it will be removed in. And also point to the change record.

  2. +++ b/core/lib/Drupal/Core/Field/WidgetBase.php
    @@ -135,7 +135,7 @@ public function form(FieldItemListInterface $items, array &$form, FormStateInter
    +    $element = [
    

    $element is a interesting variable name - I think we should be verbose here and use $field_widget_complete_form

  3. +++ b/core/lib/Drupal/Core/Field/WidgetBase.php
    @@ -149,6 +149,17 @@ public function form(FieldItemListInterface $items, array &$form, FormStateInter
    +    \Drupal::moduleHandler()->alter(['field_widget_complete_form', 'field_widget_' . $this->getPluginId() . '_complete_form'], $element, $form_state, $context);
    

    I think the alter should field_widget_complete_PLUGIN_ID_form

  4. +++ b/core/lib/Drupal/Core/Field/WidgetBase.php
    @@ -350,7 +361,8 @@ protected function formSingleElement(FieldItemListInterface $items, $delta, arra
    -      \Drupal::moduleHandler()->alter(['field_widget_form', 'field_widget_' . $this->getPluginId() . '_form'], $element, $form_state, $context);
    

    It's good to be getting rid of this... imagine you have a plugin ID of complete or multivalue.

    I think though that we might have a problem if a site did have a plugin ID of complete. Not sure about the best way of fixing that. Also we have same problem if the ID is single_element... tricky.

  5. +++ b/core/lib/Drupal/Core/Field/WidgetBase.php
    @@ -350,7 +361,8 @@ protected function formSingleElement(FieldItemListInterface $items, $delta, arra
    +      \Drupal::moduleHandler()->alterDeprecated('Implement hook_field_widget_single_element_form_alter or hook_field_widget_WIDGET_TYPE_single_element_form_alter instead.', ['field_widget_form', 'field_widget_' . $this->getPluginId() . '_form'], $element, $form_state, $context);
    

    I think this should be like a proper deprecation message. Saying which version the hook is deprecated in and which it will be removed in. And also point to the change record.

  6. +++ b/core/lib/Drupal/Core/Field/WidgetBase.php
    @@ -350,7 +361,8 @@ protected function formSingleElement(FieldItemListInterface $items, $delta, arra
    +      \Drupal::moduleHandler()->alter(['field_widget_single_element_form', 'field_widget_' . $this->getPluginId() . '_single_element_form'], $element, $form_state, $context);
    

    I think the alter should be field_widget_single_element_PLUGIN_ID_form

  7. +++ b/core/modules/field/field.api.php
    @@ -184,6 +184,9 @@ function hook_field_widget_info_alter(array &$info) {
    + * @deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. Use
    + *   hook_field_widget_single_element_form_alter instead.
    + *
      * @see \Drupal\Core\Field\WidgetBaseInterface::form()
      * @see \Drupal\Core\Field\WidgetBase::formSingleElement()
      * @see hook_field_widget_WIDGET_TYPE_form_alter()
    
    @@ -219,6 +222,9 @@ function hook_field_widget_form_alter(&$element, \Drupal\Core\Form\FormStateInte
    + * @deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. Use
    + *   hook_field_widget_WIDGET_TYPE_single_element_form_alter instead.
    + *
      * @see \Drupal\Core\Field\WidgetBaseInterface::form()
      * @see \Drupal\Core\Field\WidgetBase::formSingleElement()
      * @see hook_field_widget_form_alter()
    

    Needs an @see to the CR too.

chr.fritsch’s picture

StatusFileSize
new20.09 KB
new25.01 KB

Thanks for the review, @alexpott.

I addressed almost all your points. Not sure what to do about the naming issue...

amateescu’s picture

Here's an initial review:

  1. +++ b/core/lib/Drupal/Core/Field/WidgetBase.php
    @@ -149,6 +149,17 @@ public function form(FieldItemListInterface $items, array &$form, FormStateInter
    +    // Allow module to alter the field widget form element.
    

    module -> modules :)

  2. +++ b/core/modules/field/field.api.php
    @@ -231,6 +239,141 @@ function hook_field_widget_WIDGET_TYPE_form_alter(&$element, \Drupal\Core\Form\F
     
    +
    +/**
    

    There's an extra empty line here.

  3. +++ b/core/modules/field/field.api.php
    @@ -231,6 +239,141 @@ function hook_field_widget_WIDGET_TYPE_form_alter(&$element, \Drupal\Core\Form\F
    + * @param $element
    ...
    + * @param $form_state
    ...
    + * @param $context
    ...
    + * @param $element
    ...
    + * @param $form_state
    ...
    + * @param $context
    

    We should add type hints for these arguments.

  4. +++ b/core/modules/field/field.api.php
    @@ -231,6 +239,141 @@ function hook_field_widget_WIDGET_TYPE_form_alter(&$element, \Drupal\Core\Form\F
    + * cannot alter the top level (parent element) for multi-value fields. In most
    + * cases, you should use hook_field_widget_complete_WIDGET_TYPE_form_alter()
    + * instead and loop over the elements.
    

    The existing hook that can only alter individual elements has worked fine in most cases for many years, so I don't think we should recommend that people use the new one instead.

    It's fine to mention it as an alternative, but not really as the "preferred" one.

  5. +++ b/core/modules/field/field.api.php
    @@ -231,6 +239,141 @@ function hook_field_widget_WIDGET_TYPE_form_alter(&$element, \Drupal\Core\Form\F
    +  // hook_field_widget_mymodule_autocomplete_form_alter() will only act on
    

    The hook example from the comment needs to be updated to match the new name.

  6. +++ b/core/modules/field/field.api.php
    @@ -231,6 +239,141 @@ function hook_field_widget_WIDGET_TYPE_form_alter(&$element, \Drupal\Core\Form\F
    + * Alter forms for field widgets container provided by other modules.
    ...
    + * Alter forms for field widgets container provided by other modules.
    

    'field widgets container' sounds a bit.. vague. I think that the "complete form" of a widget being wrapped in a container element is an implementation detail, so maybe we can come up with a better way to describe what users can alter with this hook :)

I'm still thinking through the naming issues...

chr.fritsch’s picture

StatusFileSize
new4.55 KB
new25.15 KB

Thanks for the review @amateescu

#24 1-3: Fixed
#24 4: I can change that, but it's the same text we had before on hook_field_widget_form_alter
#24 5-6: Fixed

chr.fritsch’s picture

I looked through http://grep.xnddx.ru and couldn't find an existing field type in contrib that is currently named "complete", "single_value" or "multivalue".

amateescu’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs tests

Reviewed the patch once more and it looks ready to go :)

adityasingh’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new25.15 KB
new11.15 KB

#25 Patch Failed to Apply.
Reroll the patch for 9.2.x, please review the patch.

adityasingh’s picture

StatusFileSize
new24.15 KB
new11.15 KB

Please ignore #28.

#25 'Patch Failed to Apply'.
Reroll the patch for 9.2.x, please review the patch.

chr.fritsch’s picture

StatusFileSize
new24.76 KB

#29 contained some unrelated changes in the dictionary.

I rerolled #25

chr.fritsch’s picture

StatusFileSize
new23.82 KB
new4.82 KB

Ok, fixed the coding style issues

volkerk’s picture

Status: Needs review » Reviewed & tested by the community

Looked at the diff between 2872162-25.patch and 2872162-31.patch. Changes were regarding assertions and cs.
Lgtm.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 81e2d9c and pushed to 9.2.x. Thanks!

  • alexpott committed 81e2d9c on 9.2.x
    Issue #2872162 by chr.fritsch, adityasingh, jian he, p4trizio, amateescu...
chr.fritsch’s picture

StatusFileSize
new21.61 KB

In case someone needs a patch that applies on D8.9. Here it is

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.