I wrote a custom module recently where I needed to programmatically attach a field; similar to how a Body field is added to content types.
If you create a content type, via the “Content types” page, a Body field is automatically added to the content type. If you don’t need the field just delete it, but the default functionality is to have it added.
I needed this same functionality in my custom module; when an entity is created a field is programmatically attached to it.
So I reverse engineered how the Body field gets added to content types. In the Node module, the Body field is exported as field.storage.node.body.yml
and the field is attached using the node_add_body_field
function.
I implemented my custom module in a similar fashion and everything worked until all the entity bundles with the custom field were deleted. When a new entity type was created you’d get a fatal error saying the custom field, which was programmatically attached, doesn’t exist.
So what happened?
Change Configuration Yaml
Drupal by default will delete a field if it’s no longer used. Now the fix for this is pretty simple.
Open the field storage yaml for a specific field, look for “field.storage.ENTITY.FIELD.yml”.
Simply set persist_with_no_fields
to TRUE
in the yaml file. For example, persist_with_no_fields: true
.
Let’s take the Body field as an example. If you open up the field storage yaml file, field.storage.node.body.yml, you’ll see that the persist_with_no_fields option is set to TRUE. By default Drupal will set it to FALSE.
Don’t Forget to Import the Configuration Change
Once you’ve modified the yaml file don’t forget to import the configuration change. If you want to learn more about configuration manage in Drupal 8, check out page “Managing your site’s configuration“.
Summary
I do understand this is a fairly niche problem. But if you want fields to persist then set this option to TRUE and you’re good to go.
Super niche problem, but pretty interesting nonetheless! Great find.
Thanks.