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: asaleotestf@gmail.com
  • 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 + 0 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.

Quảng cáo việc làm

 

Thích hợp các bạn nữ mảng thợ may làm việc tại nước NGA

Đơn hàng Tuyển dụng 100 Thợ may đi Nga(đợt 1 tháng 3.2021, đợt 2 tháng 5.2021). Lương thực lãnh 800 USD, bao ăn ở, vé máy bay và visa, phí xuất cảnh(1800 USD)trả khi đi làm có lương. Bạn có thể liên hệ CÔNG TY qua Phone/Zalo: (+84) 944 225 212. Công ty sẽ tư vấn cho bạn.

Xem chi tiết: >>> https://bit.ly/3o9NOfR

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

 
sinh thường

Được và mất giữa sinh thường và sinh mổ.

Sinh thường hay sinh mổ sẽ tốt hơn là nỗi băn khoăn của hầu hết các bà bầu. Hãy cùng so sánh những điều được và mất của hai phương pháp sinh con này nhé.

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.

Phím tắt và chức năng trong thanh công cụ Photoshop (Toolbar)

Phím tắt và chức năng trong thanh công cụ Photoshop (Toolbar)

Một công cụ trong thanh công cụ Photoshop có thể có nhiều công cụ nhỏ bên trong. Click chuột phải vào công cụ đó bạn sẽ thấy chữ cái hiển thị cho phím tắt của nó