0

I have multiple modules for custom content types (like "node_type_food" and "node_type_wine"), based on "node_type_example" in the drupal examples module.

I can install a content type like "node_type_food" without any problems but installing a second content type like "node_type_wine" with a common field (food & wine both have a field "field_text") results in this error:

Unable to install Content type wine, field.storage.node.field_text already exists in active configuration.

Without the field.storage.node.field_text.yml in config/install I can't install a content type when no other content type provides the field storage..

Unable to install Node type wine, field.field.node.wine.field_text has unmet dependencies.

Edit: Problem also descibed in comment on Install a module that creates a content type with fileds via YAML

1
  • Problem is solved by putting all config files in config/optional, why can't i only put the field.storage yml's in optional and leave the rest in install? Commented Oct 22, 2016 at 10:04

1 Answer 1

1

The Drupal's config management system which are you using to install configuration isn't really built for this. There are several ways to go about this. The main issue is that the config management system automatically create dependencies and such for you, which is a bit troublesome to manage.

Drupal doesn't have a concept of a shared field, it simple has a field store and field instance, but this isn't owned by a module.

So for solutions, there are some ways to go about this.

  1. Let one module own the field storages you want to want to share and let modules that share fields depend on the module. Note the field can be deleted eventhough it's in a modules install folder, as it's just configuration, unless you lock it. A variation of this would be to combine the modules, into a single module, so all config is install at the same time.
  2. Don't use shared fields - if the modules are independent, it makes sense that they shouldn't share configuration.
  3. Use code to install fields. This is similar to how you define fields for entities, only you need to use FieldConfig and FieldStorageConfig. Drupal have many test cases that does this, which you can use as a guide. Some example code looks like this:

    $this->fieldStorage = FieldStorageConfig::loadByName('entity_test', $field_name);
    if (!$this->fieldStorage) {
      $this->fieldStorage = FieldStorageConfig::create(array(
        'field_name' => $field_name,
        'entity_type' => 'entity_test',
        'type' => 'link',
      ));
      $this->fieldStorage->save();
    }
    
    $this->field = FieldConfig::create([
      'field_storage' => $this->fieldStorage,
      'bundle' => 'entity_test',
      'settings' => array(
        'title' => DRUPAL_DISABLED,
        'link_type' => LinkItemInterface::LINK_GENERIC,
      ),
    ]);
    $this->field->save();
    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.