Hướng dẫn display Entity Reference Fallbacks trong Drupal 8

Hướng dẫn display Entity Reference Fallbacks trong Drupal 8

When we add a default value to a media reference field, it actually attaches that entity to each new article created. This creates a couple of problems:

  1. We can’t control the display of the field based on its value because it will always have a value. 
  2. If we were to change the default value in the future, it would only affect newly created articles (previously published articles would still have the old value).

The Solution

Because we don’t necessarily want to store a value in the database for each article, and this only affects the display of the article in certain view modes, we opted for a custom Entity Reference Field Formatter. Here’s how we did it.

Hướng dẫn display Entity Reference Fallbacks trong Drupal 8

Create our Field Formatter

Since we are using an entity reference field, we will extend from the EntityReferenceEntityFormatter class.

<?php

namespace Drupal\my_module\Plugin\Field\FieldFormatter;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\Plugin\Field\FieldFormatter\EntityReferenceEntityFormatter;
use Drupal\Core\Form\FormStateInterface;

/**
 * Plugin implementation of 'entity_reference_entity_view_fallback' formatter.
 *
 * @FieldFormatter(
 *   id = "entity_reference_entity_view_fallback",
 *   label = @Translation("Rendered entity with fallback"),
 *   field_types = {
 *     "entity_reference"
 *   }
 * )
 */
class EntityReferenceEntityFallbackFormatter extends EntityReferenceEntityFormatter {

}

Create a Configuration Form with Options

Because we want to be able to control the settings in configuration, we will have to build a settings form for the Field Formatter. Here, we have defined settings for the entity type to use, and the ID of the fallback entity.

/**
 * {@inheritdoc}
 */
public static function defaultSettings() {
  return [
    'entity_type' => 'media',
    'fallback_id' => NULL,
  ] + parent::defaultSettings();
}

/**
 * {@inheritdoc}
 */
public function settingsForm(array $form, FormStateInterface $form_state) {
  $elements = parent::settingsForm($form, $form_state);

  // The type of entity to display.
  $elements['entity_type'] = [
    '#type' => 'textfield',
    '#title' => $this->t('Entity Type'),
    '#default_value' => $this->getSetting('entity_type'),
    '#required' => TRUE,
  ];

  // The ID of the entity to display.
  $elements['fallback_id'] = [
    '#type' => 'textfield',
    '#title' => $this->t('Fallback ID'),
    '#default_value' => $this->getSetting('fallback_id'),
    '#required' => TRUE,
  ];

  return $elements;
}

Update the Display of the Field

The only thing left to do is handle the display of the field when using this formatter. Here we check to see if the field is empty, and if it is, we render the fall back entity (defined in our settings form) instead.

/**
 * {@inheritdoc}
 */
public function viewElements(FieldItemListInterface $items, $langcode) {
  $elements = parent::viewElements($items, $langcode);
  $view_mode = $this->getSetting('view_mode');

  // Check if the field is empty.
  if (empty($elements)) {
    // TODO: Protect against infinite recursion.
    $controller = \Drupal::entityManager()->getStorage($this->getSetting('entity_type'));

    // Get the fallback entity.
    $entity = $controller->load($this->getSetting('fallback_id'));

    // If a fallback value is set, display it.
    if (!empty($entity)) {
      $view_builder = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId());
      $elements[] = $view_builder->view($entity, $view_mode, $entity->language()->getId());
    }
  }

  return $elements;
}

The Full Code:

<?php

namespace Drupal\my_module\Plugin\Field\FieldFormatter;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\Plugin\Field\FieldFormatter\EntityReferenceEntityFormatter;
use Drupal\Core\Form\FormStateInterface;

/**
 * Plugin implementation of 'entity_reference_entity_view_fallback' formatter.
 *
 * @FieldFormatter(
 *   id = "entity_reference_entity_view_fallback",
 *   label = @Translation("Rendered entity with fallback"),
 *   field_types = {
 *     "entity_reference"
 *   }
 * )
 */
class EntityReferenceEntityFallbackFormatter extends EntityReferenceEntityFormatter {

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return [
      'entity_type' => 'media',
      'fallback_id' => NULL,
    ] + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $elements = parent::settingsForm($form, $form_state);

    // The type of entity to display.
    $elements['entity_type'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Entity Type'),
      '#default_value' => $this->getSetting('entity_type'),
      '#required' => TRUE,
    ];

    // The ID of the entity to display.
    $elements['fallback_id'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Fallback ID'),
      '#default_value' => $this->getSetting('fallback_id'),
      '#required' => TRUE,
    ];

    return $elements;
  }

  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    $elements = parent::viewElements($items, $langcode);
    $view_mode = $this->getSetting('view_mode');

    // Check if the field is empty.
    if (empty($elements)) {
      // TODO: Protect against infinite recursion.
      $controller = \Drupal::entityManager()->getStorage($this->getSetting('entity_type'));

      // Get the fallback entity.
      $entity = $controller->load($this->getSetting('fallback_id'));

      // If a fallback value is set, display it.
      if (!empty($entity)) {
        $view_builder = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId());
        $elements[] = $view_builder->view($entity, $view_mode, $entity->language()->getId());
      }
    }

    return $elements;
  }

}
Bạn thấy bài viết này như thế nào?: 
Average: 9.5 (2 votes)
Ảnh của Tommy Tran

Tommy owner Express Magazine

Drupal Developer having 9+ year experience, implementation and having strong knowledge of technical specifications, workflow development. Ability to perform effectively and efficiently in team and individually. Always enthusiastic and interseted to study new technologies

  • Skype ID: tthanhthuy

Bình luận (0)

 

Add Comment

Filtered HTML

  • Các địa chỉ web và email sẽ tự động được chuyển sang dạng liên kết.
  • Các thẻ HTML được chấp nhận: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Tự động ngắt dòng và đoạn văn.

Plain text

  • No HTML tags allowed.
  • Các địa chỉ web và email sẽ tự động được chuyển sang dạng liên kết.
  • Tự động ngắt dòng và đoạn văn.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.

Advertisement

 

jobsora

Dich vu khu trung tphcm

Dich vu diet chuot tphcm

Dich vu diet con trung

Quảng Cáo Bài Viết

 
CNTT Việt Nam 2011 - Nông dân được ‘lên mây’

CNTT Việt Nam 2011 - Nông dân được ‘lên mây’

Năm 2011 đã trôi qua khá trầm lắng trên thị trường CNTT Việt Nam. Bối cảnh kinh tế khó khăn đã để lại dấu ấn sâu sắc trong bức tranh toàn cảnh.

Tập tành Working With Domain Access Module in Drupal 7.x

Tập tành Working With Domain Access Module in Drupal 7.x

Installation steps: 1. Download and install the Domain Access module using this link

Cải thiện performance trong Drupal 8 nhờ New Quicklink module

Cải thiện performance trong Drupal 8 nhờ New Quicklink module

First, links in the user’s viewport are detected. These are links that the user might want to visit next. When the browser goes idle, the content from the links begins to be saved in the cache

Công ty diệt chuột T&C

 

Diet con trung