Field API deletes fields when the last instance is deleted. Field UI populates the "add existing field" dropdown only with fields with at least one instance. This makes it hard for modules to expose fields to a website, and build business-logic functionality tied to that field, without also locking at least one bundle into using (instantiating) that field. I just posted a D7 contrib module, ModuleField, for solving this. Is there any interest in this being added to Drupal core (directly to field.module and field_ui.module)?

Files: 
CommentFileSizeAuthor
#16 1426804-16.patch11.09 KBswentel
FAILED: [[SimpleTest]]: [PHP 5.4 MySQL] Unable to apply patch 1426804-16.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]
#16 interdiff.txt814 bytesswentel
#14 1426804-14.patch11.03 KBswentel
FAILED: [[SimpleTest]]: [MySQL] 54,482 pass(es), 0 fail(s), and 6 exception(s).
[ View ]
#14 interdiff.txt3.48 KBswentel
#12 default-field.png26.67 KBswentel
#12 1426804-12.patch10.87 KBswentel
FAILED: [[SimpleTest]]: [MySQL] 54,594 pass(es), 0 fail(s), and 11 exception(s).
[ View ]

Comments

This makes it hard for modules to expose fields to a website

This is true, but I am wondering if there is a purpose for exposing fields to a website beyond the already mentioned case of adding business-logic that is tied to a field.

If that is the case, #1803064: Horizontal extensibility of Fields: introduce the concept of behavior plugins would solve that problem, and it would make the logic reusable on any field of the type or types for which the behavior was designed, not just a specific field exposed by a module.

There might be other reason why this might be useful, but for reusable business logic attached to fields, the previously mentioned issue is a more flexible solution.

+1 — We could really use such functionality for #1751210: Convert URL alias form element into a field and field widget

The use-case is that Path module wants to provide a default "path" field, which should just exist by default, and which may be added to individual entity bundles. The field should not even be pruned/deleted when the last instance was removed.

Title:Provide a declarative API for modules to define fields without instancesProvide a declarative API for modules to define fields, not just field types

Well the thing is that fields and instances are very much about an imperative API. They have a CRUD cycle that we need to react to.
The fact that "pseudo fields", OTOH, currently come and go silently in hooks is something that we need to hack our way around in some places.

Besides,
- $field and $instance are moving to CMI config entities. I don't see us introducing an additional pattern for configuration items to enter the system by being exposed in 'hook_default_X' hooks ? (that pattern has just been removed in views, btw)
- #1852966: Rework entity display settings around EntityDisplay config entity splits the 'display' part of $instance out to a separate EntityDisplay config object - with its own declarative API. $instance['widget'] will follow the same path. So even with a declarative API on $field and $instance, you'll still need a separate imperative sequence to configure forms and displays. Unless we introduce hooks for exposing any kind of entity ?

The issue title makes it sound like "field types" and "fields" are almost the same thing - "what we do with one, why couldn't we do with the other ?". That's, er, totally not the case :-)

Title:Provide a declarative API for modules to define fields, not just field typesProvide a declarative API for modules to define fields without instances

Is this title better?

Title:Provide a declarative API for modules to define fields, not just field typesProvide a declarative API for modules to define fields without instances

Doh, I mistook this issue for "add fields and instances in hooks", and that was mostly what #3 replied to.
Sorry about that.

I'd need to look into http://drupal.org/project/modulefield more closely.
But, last time I had to deal with that, fields without instances were kind of a pain to deal with :-/

Hm. I'm not sure about the "declarative" part. At least I don't see why it would have to be declarative. Also not sure about the "without instances" part ;) Perhaps my interest is different to this issue's goal after all? Let me try to explain:

1) As a module developer, I want to be able to install a field with default settings when my module is installed, so the field can be attached to bundles, if desired.

2) As a module developer, I also want to be able to automatically install field instances of the field that I installed. Those instances may be customized and can be removed by the site admin later on, potentially even all, but (TBD) the field should still persist.

3) As a module developer of a very specific field type, I want to be able to define and supply default settings for every (new) instance of a field, or have some other way to (help to) ensure a consistent appearance of all field instances across entities/bundles. (Concrete example: the URL alias field.)

4) As a module developer, I'd also like to automatically attach a field to every new bundle that is created for a particular entity type. (Again, concrete example: Every new node/content type should automatically get the URL alias field by default - perhaps even all bundles ;))

So I'm definitely not interested in declaring/defining fields + instances via runtime code. :) I still see the regular field/instance CRUD happening, I just want/need better methods for performing these field type 1:n bundles operations on the API level, module installation, and installation profile level, as well as some special handling for these module-created fields/instances with regard to their lifecycle.

Did I misunderstand the goal of this issue?

@sun 1 and 2 are going to work after the field api cmi conversion (tests in that patchare proving that in a way). 3 and 4 will need some coding, but hook_node_type_create/update should work find after node types are converted to config.

Did I misunderstand the goal of this issue?

I think the real goal here is to define 1 field without an instance that you can select automatically on field UI ? Unless I'm missing something too here ? Or does it even go further like: one field automatically creates the instance as well ? Again, I think that would also be solved again with field api on cmi - in a way. And otherwise, adding logic to field ui shouldn't be *that* hard I think.

- edit - 3 needs some custom coding as well

Title:Provide a declarative API for modules to define fields without instancesProvide an API for modules to define fields without instances

#6 captures the goals I originally had for this issue. Please retitle as you see fit. Good news on #7; does it make sense to postpone this on #1735118: Convert Field API to CMI?

The problem with fields without instances is that Field UI really lets you work with instances, and hides the standalone notion of fields completely. Users only have to manage their instances, they don't have to manage their fields, this is taken care of.
This matches most actual use cases and hides some complexity.

If we allow "fields without instances", then it means the UI needs to account for managing fields as well - like:
- if you delete the last instance, do you want to keep the field around ? (95% cases: no)
- how do you create/edit/delete a field that's not attached to an actual entity bundle ?
- can you delete a field while it still has instances ?
That's a lot more cases to deal with. And Field UI only attaches to "per bundle" pages - we don't have a convenient place for "cross entity types / cross bundles" notions in our IA.

Title:Provide an API for modules to define fields without instancesImprove API for module-created fields (with and without instances)
Category:feature» task

I think that there is one aspect that could potentially help to achieve a different behavior for such fields:

All custom/user-created fields are prefixed with 'field_', whereas module-created fields are not (e.g., 'body', 'path', etc).

Ultimately, I think what we're aiming for is a slight deviation of non-custom, module-created fields with regard to their lifecycle/behavior. AFAICS, the only indicator for that is the 'locked' property currently, but that has a special meaning — we likely want to introduce a new property, unless we're OK with strstr($field_name, 'field_') !== FALSE conditions.

I actually don't think that the needed changes would be very large...

- First and foremost, we'd have to give field_create_field() a meaning of its own. I was very surprised to find out that creating a field (without instance) has no effect at all except of creating a field config entry and that just creating a field is completely pointless currently. ;) Off-hand, I can't see how #1735118: Convert Field API to CMI would change or improve that situation, since it seems to be FieldOverview that explicitly filters out all fields that don't have an instance. Removing that filter would be the first task.

- Second, to achieve default instance settings (3), we might want to introduce exactly that for field definitions? I.e., allow fields to suggest a default widget, formatter, settings, and label and stuff? (not in metadata, just introduce a new, optional method, since this info is only needed when the field is instantiated already and when possibly creating an instance, and could very well involve dynamic/conditional logic)

Lastly, for point #6.4, I'm actually not sure whether we need to do anything — in case the Bundle CRUD API fires a hook upon creating a new bundle, then modules like Path module might be able to do what they want to do already?

Issue tags:+Field API

Tagging.

Also, CMI conversion is in, so we can start thinking about this again :)

@sun You're right indeed. Only shipping a field will not expose this in the UI and, as you mentioned, I think that could be a fairly small patch to begin with.

Status:Active» Needs review
StatusFileSize
new10.87 KB
FAILED: [[SimpleTest]]: [MySQL] 54,594 pass(es), 0 fail(s), and 11 exception(s).
[ View ]
new26.67 KB

So this works: you can now ship a field in config without instance and then select it in Field UI. #1963340: Change field UI so that adding a field is a separate task might become very handy now ;)

You can test it by enabling field_test_config

TBD: what if the last instance is deleted ? Keep with some special property ?

default-field.png

Status:Needs review» Needs work

The last submitted patch, 1426804-12.patch, failed testing.

Status:Needs work» Needs review
StatusFileSize
new3.48 KB
new11.03 KB
FAILED: [[SimpleTest]]: [MySQL] 54,482 pass(es), 0 fail(s), and 6 exception(s).
[ View ]

Fixing notices

Status:Needs review» Needs work

The last submitted patch, 1426804-14.patch, failed testing.

Status:Needs work» Needs review
StatusFileSize
new814 bytes
new11.09 KB
FAILED: [[SimpleTest]]: [PHP 5.4 MySQL] Unable to apply patch 1426804-16.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]

Should be green.

Removing focus

Issue tags:-Field API

Actually removing it ..

Issue tags:+Entity Field API

Field addition is going to be a separate task #1963340: Change field UI so that adding a field is a separate task

16: 1426804-16.patch queued for re-testing.

Status:Needs review» Needs work

The last submitted patch, 16: 1426804-16.patch, failed testing.