Problem/Motivation
Field API provides the concepts of Field, Widgets, and Formatters types. With the ongoing conversion of the Field API as plugins, those are becoming vertically extensible. It's going to become relatively easy to build a Field type that derives from another Field type (an obvious example of which is Image Field vs. File Field in core).
The Field API would benefit from being horizontally extensible as well. In Entity Reference in Drupal 7 we introduced the concept of "Behaviors": you can extend the Entity Reference field type with multiple additional behaviors. Example of which:
- Behaves as a Hierarchical Tree
- Allow prepopulating entity reference fields
- Maintain the {taxonomy_index} table
In essence, the behavior provides a nice encapsulation and an UI for interacting with a Field type and the lifecycle of the data it stores. Everything that currently implements hook_field_attach_*()
could be a candidate to become a Field Behavior.
Proposed resolution
Implement the concept of "Field Behavior" plugins. Those plugins can be attached to a field or instance either via its definition or via the Field UI, and participate to many events in the lifecycle of a field and/or instance.
In detail, a "Field Behavior" plugin satisfies the following:
- A behavior plugin can be field-level, instance-level or both.
- One or more behavior plugin can be enabled on each Field.
- One or more behavior plugin can be enabled on each Field instance.
- A behavior plugin participates in the Field and instance settings form provided by the Field UI.
- A behavior plugin can alter the Field schema.
- A behavior plugin can alter the Field property information.
- A behavior plugin can participate in the Field data lifecycle (load, is empty, validate, presave, insert, update, delete)
- A behavior plugin can participate in the Entity data lifecycle of entities its field is attached to (load, presave, insert, update, delete)
- A behavior plugin can decide if it can be applied to a particular field or field instance.
User interface changes
The Field and Field instance settings form will have an additional section for behaviors. The current UI in Entity Reference can be used as a blueprint, but will require usability review.
API changes
This will not introduce any API change. The following additions:
- The "Field Behavior" plugin type
Comment | File | Size | Author |
---|---|---|---|
#9 | behaviors-1803064-9.patch | 14.85 KB | amitaibu |
Comments
Comment #1
andypostBy the first look tree.module seems over-engineering and I think it's not a good example. Also all ER modules are very fragile and seems has low attention from maintainers - all of them are alpha and has a lot of unresolved issues.
Also we already have a kind of behaviors in core (a js) so it could lead to another confusion like #1803630: Rename entity bundles to avoid confusion
EDIT core now ships with a Decorator plugins which makes more sense from UX
Comment #2
moshe weitzman CreditAttribution: moshe weitzman commentedDo we port formatters and widgets to be behaviors? I'm not quite sure how those fit in. Those are currently nice, understandable concepts IMO.
Comment #3
Damien Tournoud CreditAttribution: Damien Tournoud commentedNo, I think we want formatter-level and widget-level behaviors too, so that you can alter / extend formatters and widgets the same way.
Comment #4
amitaibuI think maybe we can take it one step further and actually remove hook_field_attach_*() in favor of behavior plugins?
OG and Entity-reference pre populate are properly --or so I hope :) -- maintained, and they both rely on the "Behaviors". I have also updated the example links in the issue summary.
How about "field-behavior"?
Comment #5
fmizzell CreditAttribution: fmizzell commentedIn eck, we also have behaviors for what used to be called properties (now they are also called fields). Could that be part of this issue, since we are trying to unify field api and non-filed-api fields?
Comment #6
mitchell CreditAttribution: mitchell commentedObservations:
Comment #7
amitaibuI'm going to have a stab at this.
Comment #8
amitaibuWork is done in yched's sandbox, in branch
behaviors-1803064
Comment #9
amitaibuWIP, but having progress. No UI yet. Brave ones can test:
$field['settings']['behaviors']['field_test']['status'] = TRUE;
to a select-list field.I've added a todo about should we keep for example in _field_filter_items() calling the dummy-hook (i.e. a single function), or should we move everything to behaviors. (And to answer myself, at least for the beginning we should keep the older dummy-hooks).
Comment #10
andypostAs ER in - is this feature for D8?
Comment #11
amitaibuUn-assigning until I get more than 2-3 hours sleep a night ;)
@amateescu, any chance your going to work on it? The community, OG and ER-prepopulate would be grateful ;)
Comment #12
amateescu CreditAttribution: amateescu commentedQuite possible, but only after #1969728: Implement Field API "field types" as TypedData Plugins.
Comment #12.0
amateescu CreditAttribution: amateescu commentedUpdate example links.
Comment #13
mccrodp CreditAttribution: mccrodp as a volunteer commentedI made a minimal start on #2615320: [entityreference_prepopulate] Entityreference prepopulate and ran into this issue relating to entity reference behavior plugins.
@amitaibu / anyone else: what is the status of this re: entity reference behavior plugins and does it block a entityreference_prepopulate release for example?
Comment #14
amitaibu> and does it block a entityreference_prepopulate release for example?
It probably will require some re-thinking on how to do it, since indeed behavior plugins don't exist in D8. Not sure myself yet what would be the best approach..
Comment #16
geek-merlinThis would be great! Rock on!
Minor:
Leftover from entityreference.
Also.
Comment #17
joelpittetI wonder how this related to what @andypost said in #1 about Decorators being in core. That pattern seems like it may be a good fit here in my off the cuff reaction.
Comment #18
webchickJust moving a feature to 8.3.x. (Weird the scripts didn't auto-do this.)
Comment #19
andypostDecorator is only available pattern for fields now, I think *behaviors* will bring huge overhead to performance so better to beware calling entity-hooks for "field-extensions" - better to "decorate" field or widget/formatter.
Comment #20
amitaibu@andypost can you point me to an example for such a pattern. My goal is to have a understanding on how to port Entityreference-prepopulate module to D8
Comment #21
geek-merlinI'm also very interested in this. I can confirm that a good horizontal extensibility like entityreference provided is a *huge* win for field behavior contrib modules.
@amitaibu, @andipost: So the idea is to swap out the field handler against a loosely coupled one that delegates most methods simply to the original handler (and in the case of multiple behaviors we'll get a delegation chain) like outlined here.
What i did *not yet* grok is, where is the swapping-out-and-decorationg of the field handler happening?
(Note-to-self: Check if the decorate-and-delegate boilerplate code might live in a reusable trait.)