Problem/Motivation
When Entity Form Controllers were introduced, it came with the concept of a "default" form, where you could just call entity_get_form($entity)
, with no specified operation.
This has led to reuse of entity forms for both add and edit, with odd and inconsistent hacks spread through them (like $entity->isNew()
) to differentiate between them.
Proposed resolution
Encourage use of separate form controllers that share a base class.
In the meantime, just duplicate the form declaration in the annotation to reuse the single class for each operation:
diff --git a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php
index 5a288c8..1bfcd02 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php
@@ -24,7 +24,8 @@
* "access" = "Drupal\user\RoleAccessController",
* "list" = "Drupal\user\RoleListController",
* "form" = {
- * "default" = "Drupal\user\RoleFormController"
+ * "add" = "Drupal\user\RoleFormController",
+ * "edit" = "Drupal\user\RoleFormController"
* }
* },
* config_prefix = "user.role",
Remaining tasks
N/A
User interface changes
N/A
API changes
$operation is no longer optional when calling entity_get_form() et al.
Related Issues
Comment | File | Size | Author |
---|---|---|---|
#54 | entity-2006348-54-with-api-change.patch | 53.2 KB | tim.plunkett |
#54 | entity-2006348-54-no-api-change.patch | 48.97 KB | tim.plunkett |
Comments
Comment #1
tim.plunkettFirst pass. Will likely need to be rerolled as conversions go in, but worth getting some feedback.
Comment #3
tim.plunkett#1: entity-form-default-2006348-1.patch queued for re-testing.
Comment #6
tim.plunkett#1: entity-form-default-2006348-1.patch queued for re-testing.
Comment #8
tim.plunkettMissed a couple tweaks.
Comment #10
tim.plunkettThe taxonomy test I deleted was BS. It didn't actually assert anything and is broken in HEAD. It's also not how the menu system works.
It is, however, how the route system works, so it's a moot point.
This should be done now.
Comment #11
tim.plunkettOkay, I went back and looked into that test more. It never actually asserted anything, as I said. But its fix was removed by the entity_form conversion for no apparent reason.
Here's the correct fix, as it was in #1359710: taxonomy_menu passes invalid arguments into taxonomy_form_term() but with an array.
Interdiff is against #8.
Comment #12
fagoI think this is a good improvement and makes $operation to work inline with the usual edit|add|delete, .. use - however, we miss implementation of deletion forms here as well. Maybe we could do that as a follow-up?
Comment #13
tim.plunkettOpened #2011018: Reconcile entity forms and confirm forms for that.
Comment #14
plachDespite being the one that introduced the default operation, I'm definitely +1 on this :)
Comment #15
andypost#11: entity-form-2006348-11.patch queued for re-testing.
Comment #17
tim.plunkettReroll because some routes were converted, interdiff pretty much impossible.
#1987668: Convert config_test module to routes
#1992428: Convert Roles management to a Controller
Comment #19
tim.plunkettSee #1995620: [policy, no patch] Document how to handle routes for MENU_DEFAULT_LOCAL_TASK.
Comment #21
tim.plunkettOkay I just realized I'm going in circles with #2010290: Editing a config entity from a listing page results in a 'page not found' and fixing the same damn bugs. So I'm just waiting on that.
Comment #22
andypost#21 is in, let's get this in now
Comment #23
amateescu CreditAttribution: amateescu commentedCan we please take #2014821: Introduce form modes UI and their configuration entity into consideration before rushing this in?
Comment #24
tim.plunkettRerolled for the getForm().
I'm not ignoring that issue, I just don't see how this gets in the way.
I'm reasonably sure for every entity type with a form, it has one with the operation of 'edit'.
Why not make that the default?
Comment #25
amateescu CreditAttribution: amateescu commentedBecause "reasonably sure" != "enforced policy/requirement"? :)
Comment #26
tim.plunkettThen let's enforce it. Or provide 'edit' => EntityFormController as a default.
Whatever it takes to not have this in routes:
_entity_form: node.default
And this in the form class:
$this->operation == 'default'
Because that means nothing.
Comment #27
amateescu CreditAttribution: amateescu commentedAnother option would be to make the 'default_operation' property introduced by translation_entity.module an official property of the entity annotation, and default it to 'edit' instead of 'default'. We can either do it here (what I'd prefer) or open a new issue for it.
Comment #29
tim.plunkettFixed custom block.
I like the idea of default_operation, I had no idea this undocumented one-off property existed!...
I'd prefer to do that in a follow-up, I'll open one. It needs to be added to EntityType and whatnot, and this patch is big enough.
Comment #30
tim.plunkettOpened #2022873: Turn default_operation into an actual thing per #27.
Comment #31
tim.plunkettReroll.
Comment #32
dawehnerI like the fact that we remove some magic, which doesn't really actually help as you want to have a custom form controller anyway.
Comment #33
tim.plunkettNow that #2014821: Introduce form modes UI and their configuration entity is in, this is postponed on #2022873: Turn default_operation into an actual thing.
Comment #34
amateescu CreditAttribution: amateescu commentedThis is my idea on how to marry the 'default' form mode/form display with the default form operation. Basically, I'm bringing #2022873: Turn default_operation into an actual thing into scope here because it's kinda late to have dependent issues.
Comment #36
amateescu CreditAttribution: amateescu commentedNow with less broken logic.
Comment #38
tim.plunkettKeeping up with conversions.
I think the additions in the last two interdiffs are great, but the original patch is mine so I can't RTBC.
Comment #39
dawehnerIs there a follow up already to move this function as well to some kind of object?
Comment #40
tim.plunkettRerolled.
I don't know of any follow-ups for that.
Comment #41
alexpottI'm assigning to catch since he has expressed a feeling that this change is not necessary...
Also this needs a reroll...
Comment #42
tim.plunkettStraight reroll, no changes
Comment #44
tim.plunkettDidn't fetch enough.
Comment #45
catchYeah I'm not sure the API change is necessary, can we clean up the existing forms doing double duty without it?
Comment #46
tim.plunkettHere is it without the API change.
Comment #47
tstoecklerI think it in this case it makes sense to do the API change, as otherwise contrib will be lazy and not care about about $operation at all. There's two implications of that:
1. Contrib simply doing all forms (e.g. add and edit) in one controller and putting conditions such as $entity->isNew() there. This is not optimal, but I don't consider this particularly problematic. It's a small amount of code smell and it's contained to the specific module.
2. Contrib modules that interact with entity forms might have the expectation that a 'default' $operation always exist and thus break modules that follow best practices. This point is arguable, as core modules already follow this best practice (assuming this patch goes in), but nevertheless this point is why I would advocate making the API change.
Comment #48
yched CreditAttribution: yched commentedJust wondering : if we remove the notion of a "default" form mode, what's the impact on the "create new field" UI ?
Does it mean newly created fields do not appear in any forms until the admin explicitly visits the "Manage form" tabs and configures the field he just created ?
That would be a net UX regression.
On the display side, the fact that we have a "default" view mode (and that all view modes by default fall back to this "default" mode unless explicitly stated) is important UX wise : a newly added field is automatically displayed in the "default" view mode using the default formatter.
In other words : newly added fields automatically appear in "full" mode, and stay hidden in "teaser", without the admin needing to visit "Manage Display" - aka "just works".
Comment #49
tstoecklerThe problem that we have is that there is no way to sort the fields. It used to be that the default view mode just took over the sorting from the "Manage fields" page. But that is now sorted alphabetically since the introduction of form modes UI. So how should such a default form mode be populated?
Comment #50
yched CreditAttribution: yched commentedOn the "display" side, new fields are automatically added at the bottom (highest weight +1) of the "default" view mode.
That's just how EntityDisplay->setComponent() works if no 'weight' is specified.
Comment #51
tim.plunkett@yched:
This is how we solved that problem.
Comment #52
amateescu CreditAttribution: amateescu commentedYes, I have the kept the 'default' form mode. It's just the default operation that we're dropping here. I agree that it makes this relationship a lot harder to understand though..
Comment #53
yched CreditAttribution: yched commentedOh, OK, makes perfect sense :-)
Thanks !
Comment #54
tim.plunkettThe only reason this was not 100% finished before API freeze was so #2014821: Introduce form modes UI and their configuration entity could go in.
This took a couple attempts to reroll, but I had chosen to prioritize other issues that were truly API freeze sensitive.
Therefore, I really would like to see the original patch get in. I think its rather important, and the original author of the default fallback also wants it gone (#14).
So I've reuploaded both the full patch, and the watered down version. I leave it to the committers.
Comment #55
amateescu CreditAttribution: amateescu commentedYes, I guess I can take the blame for that :/ Imo, the interdiff from #46 doesn't really make sense, because it's still allowing contrib to be sloppy, as @tstoeckler points out in the next comment.
So, given that both the original author of the 'default' controller concept, entity api and field api maintainers agree that this is a good change that will actually help contrib, I would also really like to see the full patch in.
Comment #56
dawehnerTo be honest, I don't understand why it magically switches to 'default' no matter what is defined on the entity type, even there is quite some documentation.
There are some places like COnfigTest => ConfigTestInterface which could make the patch a bit smaller but nevermind.
Comment #61
stevectorIt looks like the entity system has changed greatly since this thread started. There is a still an odd split between entities using "default" as form operation and entities using "add" and "edit" instead.
Independent of which names are used I would like custom form modes added by the UI to reuse existing classes. Right now calling a form mode added through the UI throws an error. See #2511720: Allow form modes to use default operation if a form operation is not explicitly set
Comment #62
andypostso summary needs update and evaluation
@Tim, #54 shows that there's BC-compatible fix!
Also default operation changes a form name for entities so that affects contrib that uses node form alters at least
Comment #63
tim.plunkettThat code is 2.5 years old, I don't have the time or inclination to resurrect it.
I think we should just won't fix this now.
Comment #66
kristiaanvandeneyndeI may be interested in getting this moving again, but for now I'll try to fix the (personally) most glaring offender: #2848120: Short term fix: Make ContentTranslationController recognize 'add' and 'edit' form handlers.
Comment #68
woprrr CreditAttribution: woprrr as a volunteer and at NeoLynk commentedI think this change can be usefull !!! Actually we have re-designed FormModeManager to permit to enhance all entities routes to use natively form-modes. I'm free to help this to be tested/continued as soon as possible.