Hướng dẫn tính toán exposing REST API in Drupal 8 mà không code

Hướng dẫn tính toán exposing REST API in Drupal 8 mà không code

In Drupal 8.5.0, the "processed" property of text fields is available in REST which means that REST apps can render the HTML output of a textarea without worrying about the filter formats.

In this post, I will show you how you can add your own processed fields to be output via the REST API.

The "processed" property mentioned above is what is known as a computed property on the textarea field.

>> Hướng dẫn thêm CSS Classes vào Blocks ở Drupal 8

>> Đưa region block vào trong node templates của Drupal 8

The ability to make the computed properties available for the REST API like this can be very helpful. For example, when the user inputs the raw value and Drupal performs some complex logical operations on it before showing the output.

Drupal fieldable entities can also have computed properties and those properties can also be exposed via REST. I used the following solution to expose the data of an entity field which takes raw data from the users and perform some complex calculations on it.

First of all, we need to write hook_entity_bundle_field_info to add the property and because it is a computed field we don't need to implement hook_entity_field_storage_info.

<?php

// my_module/my_module.module

/**
 * @file
 * Module file for my_module.
 */

use Drupal\my_module\FieldStorageDefinition;
use Drupal\my_module\Plugin\Field\MyComputedItemList

/**
 * Implements hook_entity_bundle_field_info().
 */
function my_module_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
  $fields = [];
  // Add a property only to nodes of the 'my_bundle' bundle.
  if ($entity_type->id() === 'node' && $bundle === 'my_bundle') {
    // It is not a basefield so we need a custom field storage definition see
    // https://www.drupal.org/project/drupal/issues/2346347#comment-12206126 
    $fields['my_computed_property'] = FieldStorageDefinition::create('string')
      ->setLabel(t('My computed property'))
      ->setDescription(t('This is my computed property.'))
      ->setComputed(TRUE)
      ->setClass(MyComputedItemList::class)
      ->setReadOnly(FALSE)
      ->setInternal(FALSE)
      ->setDisplayOptions('view', [
        'label' => 'hidden',
        'region' => 'hidden',
        'weight' => -5,
      ])
      ->setDisplayOptions('form', [
        'label' => 'hidden',
        'region' => 'hidden',
        'weight' => -5,
      ])
      ->setTargetEntityTypeId($entity_type->id())
      ->setTargetBundle($bundle)
      ->setName('my_computed_property')
      ->setDisplayConfigurable('form', FALSE)
      ->setDisplayConfigurable('view', FALSE);
  }
  return $fields;
}

Then we need the MyComputedItemListclass to perform some magic. This class will allow us to set the computed field value.

<?php

// my_module/src/Plugin/Field/MyComputedItemList.php

namespace Drupal\my_module\Plugin\Field;

use Drupal\Core\Field\FieldItemList;
use Drupal\Core\TypedData\ComputedItemListTrait;

/**
 * My computed item list class.
 */
class MyComputedItemList extends FieldItemList {

  use ComputedItemListTrait;

  /**
   * {@inheritdoc}
   */
  protected function computeValue() {
    $entity = $this->getEntity();
    if ($entity->getEntityTypeId() !== 'node' || $entity->bundle() !== 'my_bundle' || $entity->my_some_other_field->isEmpty()) {
      return;
    }
    $some_string = some_magic($entity->my_some_other_field);
    $this->list[0] = $this->createItem(0, $some_string);
  }


The field we add is not a base field so we can't use \Drupal\Core\Field\BaseFieldDefinition. There is an open core issue to address that https://www.drupal.org/project/drupal/issues/2346347 but in tests there is a workaround using a copy of \Drupal\entity_test\FieldStorageDefinition:

<?php

// my_module/src/FieldStorageDefinition.php

namespace Drupal\my_module;

use Drupal\Core\Field\BaseFieldDefinition;

/**
 * A custom field storage definition class.
 *
 * For convenience we extend from BaseFieldDefinition although this should not
 * implement FieldDefinitionInterface.
 *
 * @todo Provide and make use of a proper FieldStorageDefinition class instead:
 *   https://www.drupal.org/node/2280639.
 */
class FieldStorageDefinition extends BaseFieldDefinition {

  /**
   * {@inheritdoc}
   */
  public function isBaseField() {
    return FALSE;
  }

}

Last but not least we need to announce our property definition to the entity system so that it can keep track of it. As it is an existing bundle we can write an update hook. Otherwise, we'd need to implement hook_entity_bundle_create.

<?php

// my_module/my_module.install

/**
 * @file
 * Install file for my module.
 */

use Drupal\my_module\FieldStorageDefinition;
use Drupal\my_module\Plugin\Field\MyComputedItemList;

/**
 * Adds my computed property.
 */
function my_module_update_8001() {

  $fields['my_computed_property'] = FieldStorageDefinition::create('string')
    ->setLabel(t('My computed property'))
    ->setDescription(t('This is my computed property.'))
    ->setComputed(TRUE)
    ->setClass(MyComputedItemList::class)
    ->setReadOnly(FALSE)
    ->setInternal(FALSE)
    ->setDisplayOptions('view', [
      'label' => 'hidden',
      'region' => 'hidden',
      'weight' => -5,
    ])
    ->setDisplayOptions('form', [
      'label' => 'hidden',
      'region' => 'hidden',
      'weight' => -5,
    ])
    ->setTargetEntityTypeId('node')
    ->setTargetBundle('my_bundle')
    ->setName('my_computed_property')
    ->setDisplayConfigurable('form', FALSE)
    ->setDisplayConfigurable('view', FALSE);

  // Notify the storage about the new field.
  \Drupal::service('field_definition.listener')->onFieldDefinitionCreate($fields['my_computed_property']);
}

The beauty of this solution is that I don't have to write a custom serializer to normalize the output. Drupal Typed Data API is doing all the heavy lifting.

Bạn thấy bài viết này như thế nào?: 
Average: 4.5 (4 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.

Tìm kiếm bất động sản

 

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

 
HTC Titan Review: 1st Windows 7 Phone By HTC

HTC Titan Review: 1st Windows 7 Phone By HTC

The HTC titan it is one big smartphone. This huge phone is grabbing eyeballs as this newest Windows device proudly flaunts the 4.7″ screen making the display large and clear.

Hướng dẫn cài đặt LiteSpeed, PHP, MySQL và phpMyAdmin trên Ubuntu/Debian

Hướng dẫn cài đặt LiteSpeed, PHP, MySQL và phpMyAdmin trên Ubuntu/Debian

Bài viết sẽ hướng dẫn các bạn cài đặt LiteSpeed và MySQL cùng với việc xây dựng PHP tùy biến, và phpMyAdmin để quản lí database trên MySQL trên hệ điều hành họ Ubuntu/Debian một cách đầy đủ.

Apple thử nghiệm máy tính bảng màn hình nhỏ

Apple thử nghiệm máy tính bảng màn hình nhỏ

Tập đoàn Apple đang hợp tác với các nhà cung cấp linh kiện ở Châu Á để thử nghiệm môt loại máy tính bảng mới với màn hình nhỏ hơn trong nỗ lực tìm kiếm mở rộng dòng sản phẩm trong bối cảnh cạnh tranh khốc liệt...

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

 

Diet con trung