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

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.
3 + 0 =
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

 
Sử dụng Nginx và memcached để tăng tốc Apache trên Debian Lenny

Sử dụng Nginx và memcached để tăng tốc Apache trên Debian Lenny

Trong bài viết này, tôi giới thiệu cách thức cài đặt Nginx kết hợp với memcached trên Debian “lenny” 5.0 nhằm tăng hiệu năng

Cách vào Facebook, Facebook, Facebook Messenger, Facebook Timeline, Profile Facebook

Facebook đã “bốc hơi” mất 20 tỉ USD

Cổ phiếu Facebook đã giảm giá tới 18% khiến giá trị thị trường của mạng xã hội lớn nhất thế giới tiếp tục “bốc hơi” gần 20 tỉ USD.

Đằng sau việc giấu nợ xấu, khoe lãi khủng là gì?

Đằng sau việc giấu nợ xấu, khoe lãi khủng là gì?

Lãi “khủng” thực ra lại là “khối u ác tính” đang tích tụ trong cơ thể ngân hàng, chỉ chờ ngày bung ra thành những di căn không thể cứu chữa.

Tomdesgin.vn

 

Drupal Services