I am trying to create a field type that is a bundle of two fields. An entity reference user field, and a plain text field.

Image attached for clarity.

enter image description here

The idea is that the user attached to a published piece of content may have a different name at the time of the publication (marriage, divorce, name change, whatever) and has to remain intact for historical reasons. I am still linking to the same user profile, its just the visible name that is different. The most up to date name lives in the user account, but thats irrelevant.

There may be certain cases where a contributing author won't exist as a user in Drupal at all, for a handful of reasons. In this case, I do not want to fill in the reference field, but still use the plain text field. The field formatter will be updated to detect the presence of a target id or not.

The end result being something like:

Attributions: Author One, Author Two, Author Three, Author Four

I can't seem to get it to save an input though unless it has a reference value. How can you do that?

Here is my widget code:

 * Plugin implementation of the 'authors_widget' widget.
 * @FieldWidget(
 *   id = "authors_widget",
 *   label = @Translation("Authors"),
 *   field_types = {
 *     "authors"
 *   }
 * )
class AuthorsWidget extends EntityReferenceAutocompleteWidget {

   * {@inheritdoc}
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element = parent::formElement($items, $delta, $element, $form, $form_state);

    $element['target_id']['#title_display'] = 'before';
    $element['target_id']['#title'] = 'User ID';
    $element['target_id']['#description'] = $this->t('The Drupal user id of the user to reference.');
    $element['target_id']['#weight'] = -50;

    $element['name'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Published Name'),
      '#description' => $this->t('Set the published name for this author at the time this content was published.'),
      '#default_value' => isset($items->get($delta)->getValue()['name']) ? $items->get($delta)->getValue()['name'] : NULL,

    return $element;


edit: Guess I should note that the reason for using the plaintext field here with no user id value is to preserve the listed order of the authors/contributors, which is important with the content we are dealing with.

  • Why aren't you using the Paragraphs module? – No Sssweat Mar 20 '19 at 14:11
  • Won't be an editable field in the end, it will be hidden. This information is being synced from a remote source. Normally I would composite field of fields from Paragraphs in other circumstances, but seems like overkill in this case. – Kevin Mar 20 '19 at 14:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.