it-swarm.com.de

So zeigen Sie ein Pseudofeld in einer Ansicht an

Ich habe ein Pseudofeld mit diesem Code erstellt:

/**
 * Implements hook_entity_extra_field_info().
 */
function MYMODULE_entity_extra_field_info() {

  $extra['node']['my_bundle']['display']['my_pseudo_field'] = [
    'label'       => t('Pseudo Label'),
    'description' => t('Pseudo description'),
    'weight'      => 100,
    'visible'     => TRUE,
  ];

  return $extra;
}

/**
 * Implements hook_ENTITY_TYPE_view().
 */
function MYMODULE_node_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode, $langcode = 'fr') {

  if ($display->getComponent('my_pseudo_field')) {

    $build['my_pseudo_field'] = [
      '#markup' => 'This is my pseudo content',
    ];
  }
}

Alles funktioniert gut, außer dass ich es nicht in einer Ansicht hinzufügen konnte.

4
Baud

Mit Hilfe von 4k4 könnte ich mein Problem lösen ... Ich werde zunächst meinen ersten Versuch erklären, der in einigen Fällen eine gute Lösung sein könnte, und dann erklären/zeigen, wie ich schließlich lande.

Zuerst habe ich mein berechnetes Feld in hook_entity_base_field_info_alter [Beachten Sie, dass dies diesmal kein Pseudofeld ist]

function my_module_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
    if ($entity_type->id() === "node") {
      ...field is created here... will show you how to after
    }
}

Zweitens müssen wir eine Klasse (die die Berechnung durchführt) für das berechnete Feld erstellen (wird Ihnen danach angezeigt).

Drittens können wir dieses Feld in einer Ansicht anzeigen, indem wir einfach hook_views_data_alter Implementieren. Das ist das Schöne an dieser Lösung: Die Ansichtsintegration erfolgt sehr schnell. Hier erfahren Sie, wie der Hook implementiert wird

function my_module_views_data_alter(array &$data) {
  $data['node']['my_computed_field'] = [
    'title' => t('My computed field'),
    'field' => [
      'id' => 'field',
      'default_formatter' => 'string',
      'field_name' => 'my_computed_field',
    ],
  ];
}

Was in meinem Fall nicht gut war, ist die Tatsache, dass mein berechnetes Feld in allen Bundles erscheint (auch wenn ich setTargetBundle('my_bundle') wie unten gezeigt verwende).

Daher habe ich meine Berechnung des berechneten Feldprozesses ein wenig geändert:

1-Erstellen Sie das berechnete Feld in hook_entity_bundle_field_info_alter ... nicht in _entity_base_field_info_alter (Wie Sie sehen können, handelt es sich um ein Float-Feld ... Sie könnten eine Zeichenfolge verwenden )

function my_module_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle)
{
    if ($entity_type->id() == 'node' && $bundle == 'my_bundle' ) {
        $fields['my_computed_field'] = BaseFieldDefinition::create('float')
        ->setName('my_computed_field')
        ->setLabel(t('Nombre de litres total'))
        ->setComputed(TRUE)
        ->setTargetEntityTypeId('node')
        ->setTargetBundle('my_bundle')
        ->setClass('\Drupal\my_module\MyComputedFieldItemList')
        ->setDisplayOptions('view', [
            'type' => 'float',
            'weight' => 0,
        ])
        ->setDisplayConfigurable('view', TRUE);
    }

}

Hinweis: Wenn jemand den Zweck von ->setTargetBundle('my_bundle') kennt, würde ich gerne etwas darüber lesen, wenn ich es hinzufüge, ohne zu wissen, ob es obligatorisch/nützlich ist.

2-Extend FieldItemList (MyComputedFieldItemList) [Verwenden Sie denselben Namen wie in ->setClass('\Drupal\my_module\MyComputedFieldItemList')]

Der Hauptpunkt hier ist die geschützte Funktion computeValue, die $ node verwendet, um den Wert zu berechnen.

<?php
namespace Drupal\my_module;

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

/**
 * Item list for a computed field that displays the total liter for a soup.
 *
 */
class MyComputedFieldItemList extends FieldItemList
{

    /**
     *
     * {@inheritdoc}
     */
    use ComputedItemListTrait;

    protected function computeValue()
    {
        $node = $this->getEntity();
        if (! $node->isNew()) {
            $this->list[0] = $this->createItem(0, my_module_function_to_compute($node));
        }
    }
}

Zu diesem Zeitpunkt haben Sie ein berechnetes Feld, das Sie in "my_bundle" anzeigen können ... Gehen wir zur Ansichtsintegration

3-Ändern Sie hook_views_data_alter, Um Ansichten mitzuteilen, dass Sie ein neues berechnetes Feld mit einem Knoten verknüpft haben. Der Hauptpunkt hier ist die ID my_computed_field

function my_module_views_data_alter(&$data)
{
    $data['node']['my_computed_field'] = array(
        'title' => t('My computed result'),
        'group' => t('Content'),
        'field' => array(
            'title' => t('My computed result'),
            'help' => t('bla bla.'),
            'id' => 'my_computed_field',
        ),
    );
}

4-Dank 4k4 habe ich verstanden, dass Sie eine Plugin-Klasse erstellen müssen, die eine render -Funktion hat, um das Ergebnis in der Ansicht anzuzeigen. Die zweite wichtige Sache hier ist die Annotation @ViewsField("my_computed_field"), die mit der ID in Schritt 3 übereinstimmen muss

<?php
/**
 * @file
 * Definition of Drupal\my_module\Plugin\views\field\ComputeField
 */

namespace Drupal\my_module\Plugin\views\field;

use Drupal\views\Plugin\views\field\FieldPluginBase;
use Drupal\views\ResultRow;

/**
 * Field handler to flag the node type.
 *
 * @ingroup views_field_handlers
 *
 * @ViewsField("my_computed_field")
 */
class ComputeField extends FieldPluginBase {

    /**
     * @{inheritdoc}
     */
    public function query() {
        // Leave empty to avoid a query on this field.
    }

    /**
     * @{inheritdoc}
     */
    public function render(ResultRow $values) {
        $node = $values->_entity;
        if ($node->bundle() == 'my_bundle') {
            return my_module_function_to_compute($node);
        }
    }
}

Jetzt läuft alles gut:

  • Das Feld kann in jedem Anzeigemodus angezeigt werden (oder nicht) und Sie können die Einstellungen in der Benutzeroberfläche wie jedes normale Feld ändern
  • Das Feld könnte in eine Knotenansicht eingefügt werden
  • Es gibt eine Funktion my_module_function_to_compute($node), die Sie in Ihr Modul einfügen können. Diese Funktion berechnet das Ergebnis Ihres Feldes mit der Entität als Argument (Knoten hier).

Eins fehlt: Die Sortierung (in der Ansicht) funktioniert nicht ... Ich muss mich damit befassen

4
Baud