1

I've created a custom entity in a custom module and one of the fields on this entity is an entity reference field to a Paragraphs typed entity. The field is created just fine and i can even 'add' a new instance of the custom entity, however when i try to edit the entity the paragraph reference field fails, giving me an error. I get a different error depending on the widget that is selected for the paragraph entity reference field.

If i use an inline entity form based widget I get a Drupal message that This entity (paragraph:37) cannot be reference. in a Drupal message.

If I use a paragraph stable or legacy widget type, I get the error directly in the edit field area without needing to save first that says, You are not allowed to add any of the Paragraphs types.

I am the site admin user and have verified full rights to everything in the permissions tab.

System Versions:

  • Drupal 10.3.6
  • Paragraphs 8.x-1.18

To Recreate the Error

Create a Paragraph Type to reference

  • Make sure Paragraphs module is installed, I'm using
  • Create new Paragraph Type called test_plain
  • Add a basic plain text field to the test_plain paragraph type

Create Custom Entity and Module

I used the devel module's drush generate entity:content to make a base scaffolding for a new content entity.

  • From command line use drush generate entity:content
  • answer questions being sure to adding translatable and revisionable
    • Module machine name: cont_ent_test
    • Module name [Cont ent test]:
    • Entity type label [Cont ent test]:
    • Entity type ID [cont_ent_test]:
    • Entity class [ContEntTest]:
    • Entity base path [/cont-ent-test]:
    • Make the entity type fieldable? [Yes]:
    • Make the entity type revisionable? [No]: Yes
    • Make the entity type translatable? [No]: Yes
    • The entity type has bundle? [No]:
    • Create canonical page? [Yes]:
    • Create entity template? [Yes]:
    • Create CRUD permissions? [No]:
    • Add "label" base field? [Yes]:
    • Add "status" base field? [Yes]:
    • Add "created" base field? [Yes]:
    • Add "changed" base field? [Yes]:
    • Add "author" base field? [Yes]:
    • Add "description" base field? [Yes]: No
    • Create REST configuration for the entity? [No]:

Update the cont_ent_test Entity With Paragraph Entity Reference Field

Finally we add the paragraph entity reference field to the new custom entity.

// We get the available paragraph entities and make sure we have a `test_plain` entity $paragraph_types = \Drupal::service('entity_type.bundle.info')->getBundleInfo('paragraph'); foreach ($paragraph_types as $id => $type_info) { $field_id = 'test_plain'; if ($id == $field_id) { $fields['test_plains'] = BaseFieldDefinition::create('entity_reference_revisions') ->setLabel(t('Test Plain')) ->setRequired(FALSE) ->setRevisionable(TRUE) ->setTranslatable(TRUE) ->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED) ->setSetting('target_type', 'paragraph') ->setSetting('handler', 'default:paragraph') ->setSetting('handler_settings', [ 'target_bundles' => [$field_id], ]) ->setDisplayOptions('form', [ 'type' => 'inline_entity_form_complex', // 'settings' => [ // 'form_mode' => 'default', // Use default form mode for paragraphs // 'label_singular' => t(ucwords(str_replace('_', ' ', $field_id))), // 'label_plural' => t(ucwords(str_replace('_', ' ', $field_id)).'s'), // 'override_labels' => TRUE, // ], 'weight' => 30, ]) // ->setDisplayOptions('view', [ // 'type' => 'entity_reference_revisions', // 'label' => 'above', // 'weight' => 30, // ]) ->setDisplayConfigurable('form', TRUE) ->setDisplayConfigurable('view', TRUE) ; } } // END - foreach(paragraph type entity) 

Add/Edit Instance of New Cont Ent Test Entity

Install the new module which will be in the '@to do Add Package' section of the Extend page. Go to Content -> Cont Ent Test the click Add button to create a new instance. Add a Test Plain paragraph in the nested field, and save the instance. Custom Entity Add Form


After saving we can go back and try to edit form.

Custom Entity Edit Form


Without changing anything if we try to save from the edit form we get an error.

Error Upon Saving Edit Form - complex ief widget


If I use a Paragraph type widget then I get this error directly in the paragraph field

Custom Entity Edit form - Paragraphs widget

The user is the full site admin to everything. For completeness, here is the ContEntTestInterface, which is what is created by the drush generate.

\\ src\ContEntTestInterface.php declare(strict_types=1); namespace Drupal\cont_ent_test; use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityChangedInterface; use Drupal\user\EntityOwnerInterface; /** * Provides an interface defining a cont ent test entity type. */ interface ContEntTestInterface extends ContentEntityInterface, EntityOwnerInterface, EntityChangedInterface { } 

Content Type Entity Works

To verify the issue is not with the paragraph entity type, i also created a new Node type (ie content type) via the Drupal Admin interface and added the test_plain paragraph entity ref field to it via the admin UI Manage fields and it works fine. So there is something that enables the paragraphs and node entities to work together that my custom entity is missing, but I can't figure out what it is. The revisioning, translatable, and access seem to be the same from what I can tell.

6
  • I don't think an entity reference revisions field can be a base field. Base fields are primitive single value columns. An ERR field like paragraphs needs 2 columns, the id and the revision_id. Commented Oct 31, 2024 at 18:18
  • Is this a field level revision that is in addition to the entity being revisionable? The custom entity def is extended from RevisionableContentEntityBase. For the field type to try for paragraph entity ref i got from this stack answer, drupal.stackexchange.com/a/275551/104691, but that could be wrong. They mention something about the rev on edit, but it's not clear to me what they mean. That could be the same thing I'm seeing. What field class should I try that might be more compatible with a paragraph type? Commented Oct 31, 2024 at 18:51
  • ER (entity reference, e.g. terms, media, user,...) is a single value. Saving the host does not generate a new revision for the linked entity. The linked entity is a standalone unit. Paragraphs is an ERR (entity reference revision): These are strictly tied to their one single host, and saving the host will create a new revision for the linked paragraph too. Commented Oct 31, 2024 at 19:09
  • I guess I'm confused, I'm using entity_reference_revisions as the field type. Are you saying that the issue is that I'm doing this as part of a baseFieldDefnition() with a BaseFieldDefinition::create('entity_refrence_revisions') and that base fields can't handle this field type? Commented Oct 31, 2024 at 19:34
  • Yes, I think so (not tested though, more guessing to be honest) Commented Oct 31, 2024 at 19:35

1 Answer 1

1

Solution: Use Configurable Field Definition

Thanks to @Hudri's comments, I was able to resolve the entity reference error for a paragraph entity, by making the field on the custom entity a configurable field instead of using the baseFieldDefinition().

To make the test_plain paragraph reference field on the cont_ent_test entity we create a set of configuration files in the cont_ent_test\config\install\.

modules/custom/cont_ent_test/ ├── cont_ent_test.info.yml ├── cont_ent_test.module └── config/ └── install/ ├── field.storage.cont_ent_test.field_test_plains.yml ├── field.field.cont_ent_test.default.field_test_plains.yml ├── core.entity_form_display.cont_ent_test.default.default.yml └── core.entity_view_display.cont_ent_test.default.default.yml 

field.storage.cont_ent_test.field_test_plains.yml

Create the field storage configuration.

langcode: en status: true dependencies: module: - paragraphs id: field.storage.cont_ent_test.field_test_plains field_name: field_test_plains entity_type: cont_ent_test type: entity_reference_revisions settings: target_type: paragraph handler: default handler_settings: {} module: paragraphs locked: false cardinality: -1 translatable: true indexes: {} persist_with_no_fields: false custom_storage: false 

field.field.cont_ent_test.default.field_test_plains.yml

Define the an instance of this field on the custom cont_ent_test entity.

langcode: en status: true dependencies: module: - paragraphs content: - cont_ent_test id: field.field.cont_ent_test.cont_ent_test.field_test_plains field_name: field_test_plains entity_type: cont_ent_test bundle: cont_ent_test settings: {} module: paragraphs locked: false description: '' required: false translatable: true default_value: [] default_value_callback: '' field_type: entity_reference_revisions 

core.entity_form_display.cont_ent_test.default.default.yml

Configure the Form Display to a complex inline entity form widget

langcode: en status: true dependencies: config: - field.field.cont_ent_test.default.field_test_plains module: - cont_ent_test id: cont_ent_test.default.default targetEntityType: cont_ent_test bundle: default mode: default content: field_test_plains: type: inline_entity_form_complex settings: form_mode: default allow_new: true allow_existing: true match_operator: CONTAINS match_limit: 10 autocomplete_match: 'default' autocomplete_path: '' add_mode: 'default' edit_mode: 'default' cardinality: 1 override_labels: false labels_singular: 'Item' labels_plural: 'Items' third_party_settings: { } hidden: { } 

core.entity_view_display.cont_ent_test.default.default.yml

Configure the View Display Mode

langcode: en status: true dependencies: config: - field.field.cont_ent_test.default.field_test_plains module: - cont_ent_test id: cont_ent_test.default.default targetEntityType: cont_ent_test bundle: default mode: default content: field_test_plains: label: above type: entity_reference_label settings: { } third_party_settings: { } hidden: { } 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.