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.

  • 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. – 4k4 Jul 18 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 at 13:19
  • This is only an example. – 4k4 Jul 18 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 at 13:55
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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