By james, 7 December, 2023
Door 7 showing the extra field logo

Welcome back to the Drupal Advent Calendar, and we’re rounding out the first week with the help of Rodrigo Aguilera (rodrigoaguilera), who’s telling us about the Extra Field module.

My choice for the Drupal advent calendar is Extra field because it is a not-so-popular module that helps me in many projects. It falls into a category that I call “Developer little helpers” since it doesn’t provide any immediate interface or functionality but it makes my life a little bit easier.

I like to keep the different representations of entities in display modes and keep the configurability that Drupal offers by reordering, hiding, and changing the settings of the fields belonging to that entity. This is when the module comes into play, creating some sort of virtual fields that can be completed with PHP code, and are written in a standalone plugin – a simple PHP class with some annotation. With the module in place, little pieces of code can be created that output some markup, that can later be dragged and dropped into the right position. You can choose the view modes in which to display the extra field. Many entities and bundles can also share the same extra fields.

You might ask why not add a new field and then write a formatter and/or a widget for it?

Since the extra field can be considered a computed field there is no need to store anything on the database. Also there are no restrictions on what pieces of the entity you are going to use to generate the extra field or how many times.

For example, you can have some logic that displays the number of entities referenced by two different fields (merging the two fields together), or the number of references that exist to the entity that is being displayed, (especially if you want to avoid views for any reason, such as performance). The module provides some nice examples to get you started. The possibilities are endless.

In the following example there is an extra field that displays the shortened URL of a node by making an HTTP call to the tinyurl service, allowing the short URL to be displayed below the title, without the need to explicitly store it in the content:

<?php
namespace Drupal\tinyurl\Plugin\ExtraField\Display;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Url;
use Drupal\extra_field\Plugin\ExtraFieldDisplayBase;
/**
 * Example Extra field Display.
 *
 * @ExtraFieldDisplay(
 * id = "tinyurl",
 * label = @Translation("Tinyurl"),
 * description = @Translation("Display a the shortened url for the node"),
 * bundles = {
 * "node.news",
 * }
 * )
 */
class Tinyurl extends ExtraFieldDisplayBase {
  /**
   * {@inheritdoc}
   */
  public function view(ContentEntityInterface $entity) : array {
    $nodeUrl = $entity->toUrl(options: ['absolute' => TRUE])->toString();
    $shortUrl = file_get_contents('https://tinyurl.com/api-create.php?url=' . $nodeUrl);
    return [
      '#type' => 'link',
      '#title' => $shortUrl,
      '#url' => Url::fromUri($shortUrl),
    ];
  }
}

Place this file inside a module in the following path (from the root of the module)

src/Plugin/ExtraField/Display/Tinyurl.php

This extra field will only appear on the “Manage display” tab for the content type news due to the plugin annotation.

Screenshot showing the manage display settings
Extra Field provides the Tinyurl field in the fields display settings

Saving the arrangement displays the extra field showing the shortened URL just below the title, as displayed below.

Screenshot showing the completed news page
The tinyurl link is displayed below the title

The latest version of the module also incorporates the ability to add extra fields to form modes. Similarly to view modes, I like to separate the different ways an entity can be edited into different form modes. Drupal doesn’t leverage this concept much other than with the user entity when it is being edited and when a user is registering for the first time, but I invite you to investigate about form modes and use them if you are not familiar with them yet. Extra field can add snippets to the form that, for example, can display an extended help on how to make edits on certain entities or fields. This way hook_form_alter() can be avoided and even shared among entities, bundles and/or form modes.

Another advantage I see when writing extra field plugins is that you keep the logic encapsulated in a PHP class to keep the code tidy. It also supports service injection so adding tests to the custom logic is a smooth experience.

One important part to mention is to always keep cacheability in mind when displaying additional information as you might do with an extra field. Drupal needs to be informed of the cache details of new pieces of that data in a page: How often does it need to be refreshed? Is it data belonging to other Drupal entities? This is known as cacheability metadata. Is always good to have a look at the docs to have clear idea of how and when to fill this metadata.

As an improvement for the module I want to contribute this Christmas season to update its code generators to the latest version (V3) of the specification since that is the version used by Drush 12 and older specifications are abandoned already. I use code generators quite a lot and I miss being able to create an extra field when I’m using Drush 12.

Photo of Rodrigo AguileraRodrigo Aguilera is a seasoned Drupal architect and backend developer hailing from the city of Madrid, Spain. His professional journey is deeply intertwined with the evolving landscape of PHP and Drupal, and he is particularly intrigued by the initiatives underway, including the likes of Composer, real browser testing, reproducible builds, and automation. Beyond the realm of coding, he is fueled by a passion for urban cycling and an avid appreciation for live music. 

Comments

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.