0

I want to build a custom formatter for a paragraphs field that renders some of the fields of the paragraph. However, I don't know how to access the single files of the paragraph field.

So far I've only written the skeleton of the formatter, but it doesn't do much, except that I can return a serialised string of all of the entire field, which does include the necessary information, but I only need three particular fields rendered themselves in a nice way (a term reference field with a label, a boolean field as "yes" or "no" and a text field. A Twig template is not an option for this.

The function looks like this:

public function viewElements(FieldItemListInterface $items, $langcode) {
  $element = [];

  foreach ($items as $delta => $item) {  
    // Desired fields: field_network_name, field_network_specific_site_code, field_network_verified

    $element[$delta] = [
      '#markup' => "Output: " . serialize($item)
    ];
  } 

  return $element;
}

I'd need to know how to elegantly access the fields inside $item.

5
  • 3
    Normally you would use the standard field formatter and configure a view mode displaying the particular fields. To get the field values try $item->entity->field_example->value, but this is not an elegant way, hard coding a paragraph structure which can change and break your code.
    – 4uk4
    Jul 18, 2019 at 13:12
  • At first, I tried the view mode approach, but it doesn't quite fit my requirements. I'm aware that hard-coding field names is problematic, but this is a custom module and the data model is fixed. Anyway, I just tried $item->entity->field_example->value, but it doesn't return anything. No error messages in the log either.
    – stopopol
    Jul 18, 2019 at 13:19
  • This is only an example.
    – 4uk4
    Jul 18, 2019 at 13:27
  • Your comment pointed me in the right direction and I looked at a few other modules and came up with this: render($item->entity->field_network_specific_site_code->value), which prints the label of this field nicely (also for multi values).
    – stopopol
    Jul 18, 2019 at 13:55
  • Have a look at the Drupal\entity_reference_revisions\Plugin\Field\FieldFormatter\EntityReferenceRevisionsEntityFormatter class. Extending it may be what you need.
    – hejazee
    Nov 13, 2020 at 23:47

1 Answer 1

0

Thanks to the comment above I was able to find a solution. This function allows to access three fields within a paragraph (term reference field, text field, boolean field).

public function viewElements(FieldItemListInterface $items, $langcode) {
$element = [];

  // Render each element as markup in case of multi-values.
  foreach ($items as $delta => $item) {

    // Desired fields: field_network_name (term reference), field_network_specific_site_code (text), field_network_verified (boolean);
    // this return the termID 
    $network_name_tid = render($item->entity->field_network_name->target_id);
    // this termID is used to load the term object
    $full_taxonomy_term_object = taxonomy_term_load($network_name_tid);
    // then you can get the name of the term, or any other information about the term
    $network_label = $full_taxonomy_term_object->getName();

    // getting the values for the text and boolean fields is more straightforward
    $network_site_code = render($item->entity >field_network_specific_site_code->value);
    $network_site_verified = render($item->entity->field_network_verified->value);

    // in the end you put them together, have conditions and format them as you need
    $element[$delta] = [
      '#markup' => $network_label . $network_site_verified . $network_site_code
    ];
  } 

  return $element;
}

However, the problems of hard-coding something like this persist. Even though this can be tackled by having the right failsaves in place.

Edit: You don't need the "render" either. Addtionally, the "render" causes a notice in the system logs. I also stumbled upon this useful cheat sheet: https://www.metaltoad.com/blog/drupal-8-entity-api-cheat-sheet

Not the answer you're looking for? Browse other questions tagged or ask your own question.