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 Tran 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
  • Phone/Zalo: (+84) 944 225 212
  • WhatsApp: (+84) 944 225 212
  • Line Messenger: (+84) 944 225 212
  • Email: [email protected]
  • Telegram Messenger: https:/t.me/tommytran0401

Bình luận (0)

 

Add Comment

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.
2 + 9 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.

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

 
Giá bán của ZTE Grand S bị rò rỉ trước thềm triển lãm CES 2013

Giá bán của ZTE Grand S bị rò rỉ trước thềm triển lãm CES 2013

Bên cạnh Nubia Z5, ZTE dự kiến sẽ công bố thêm thành viên Grand S có màn hình 5 inch với độ phân giải 1080p tại triển lãm CES 2013 diễn ra vào đầu năm sau.

Internet Việt Nam bị ảnh hưởng bởi sự cố đứt cáp AAG

Internet Việt Nam bị ảnh hưởng bởi sự cố đứt cáp AAG

Vào lúc 1 giờ 21 sáng ngày 13/8, tuyến cáp biển AAG đã xảy ra sự cố đứt tuyến cáp tại phân đoạn Vũng Tàu - Hồng Kông làm ảnh hưởng đến các nhà cung cấp dịch vụ Internet đang sử dụng AAG như VNPT, Viettel hay FPT Telecom.

Design Drupal site: www.visitcornwall.com

Design Drupal site: www.visitcornwall.com

Cornwall is the jewel in the crown of the British tourist industry, thanks to its rugged landscape and beautiful sunny beaches. In excess of five million visitors can’t be wrong!

BLOG POSTS

 

Wordpress Freelancer

 

Wordpress Freelancer