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

 
Khi nào module media được làm trên Drupal 8

Khi nào module media được làm trên Drupal 8

With Drupal 8 around the corner a lot of people started asking me when will media be ready

Bing

Tính năng mới của Bing cho phép tìm ảnh trên Facebook

Công cụ tìm kiếm Bing được bổ sung một cách mới để có thể tìm một hình ảnh hoặc album trong hàng nghìn ảnh/album mà bạn bè của người dùng đã đăng trên Facebook. Tính năng này có khả năng thu hút nhiều người dùng Facebook đến với Bing.

Firefox 9.0 Beta 4 lướt web nhanh và mượt hơn

Firefox 9.0 Beta 4 lướt web nhanh và mượt hơn

Nhịp điệu mỗi tuần ra một bản Beta mới của Firefox vẫn được Mozilla duy trì. Tương tự những lần trước, Firefox 9.0 Beta 4 cũng cải thiện về tốc độ xử lý JavaScript và giảm chiếm dụng bộ nhớ đôi chút.

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

 

Diet con trung