Need some help with your project? Contact me

Creating pseudo-fields in Drupal 8

In this article we are going to look at how we can create and use pseudo-fields in Drupal 8.

What are pseudo-fields?

Pseudo-fields are simple display fields that you can control from the display settings of a particular entity type. An example of such a field is the core Links field on the node or comment entities.

Why are they useful?

Pseudo-fields are great if you have some content or data that you need to render together with that of a particular entity. And since you don't want to be hacky and hardcode all of this inside a template or preprocessor, you can use pseudo-fields to expose some control over this to the UI. This means that you can use the core drag-and-drop functionality to control their visibility and position relative to regular entity fields.

Pseudo-fields are a great way to display data that is tightly coupled to the entities but is not part of them or their fields.

So how do they work?

There are 2 main steps we need to take in order to create a pseudo-field. First, we need to implement hook_entity_extra_field_info() which is similar to Drupal 7.

/**
 * Implements hook_entity_extra_field_info().
 */
function my_module_entity_extra_field_info() {
  $extra = array();

  foreach (NodeType::loadMultiple() as $bundle) {
    $extra['node'][$bundle->Id()]['display']['my_own_pseudo_field'] = array(
      'label' => t('My own field'),
      'description' => t('This is my own pseudo-field'),
      'weight' => 100,
      'visible' => TRUE,
    );
  }

  return $extra;
}

We mustn't forget to use the NodeType class at the top of the file:

use Drupal\node\Entity\NodeType;

With this implementation we are creating one pseudo-field called My own field that will show up on the display settings of all the node bundles. After clearing the cache, you can already see it if you go to the display settings of any node bundle you have.

drupal 8 pseudo fields

The second step is making this field actually render something when the node is being viewed. For this we need to implement hook_entity_view() or any of its variants:

/**
 * Implements hook_ENTITY_TYPE_view().
 */
function my_module_node_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode, $langcode) {
  if ($display->getComponent('my_own_pseudo_field')) {
      $build['my_own_pseudo_field'] = [
        '#type' => 'markup',
        '#markup' => 'This is my custom content', 
    ];
  }
}

And again, let's use the necessary classes at the top:

use \Drupal\Core\Entity\EntityInterface;
use \Drupal\Core\Entity\Display\EntityViewDisplayInterface;

Above we went with the hook_ENTITY_TYPE_view() variant that applies to the node entity. Inside, we are being passed an EntityViewDisplayInterface display object which we can use to check whether or not our own component (the one we defined earlier) exists in this display. If it does, we add our custom data to the $build render array that is passed by reference. This check allows the user interface to determine the visibility of this component on each view mode, as well as the weight (position relative to the other components which can be either entity fields or other such pseudo-fields).

And that's about it. You can save, edit the display settings of your nodes, create view modes and specify exactly for which one and where this custom content should show up.

Hope this helps.

Comments

Good article! In the first paragraph under the section labeled 'How do they work?' you alluded to a Drupal 7 equivalent, but did not name it:

There are 2 main steps we need to take in order to create a pseudo-field. First, we need to implement hook_entity_extra_field_info() which is similar to Drupal 7.

I believe that you were referring to the Drupal 7 hook function hook_field_extra_fields()

Hey there,

Yes, I forgot to indeed. Thanks!

Great article!

Would it be possible to add a formatter?
I'm trying to make one but does not work with this type of fields.

Thanks!

There is no way to add a field formatter supported by Drupal 8.

Hi!

The "hook_entity_extra_field_info()" link above, in the "So how do they work?" paragraph, should link to the API page instead of this article I think.
(I could not paste the link here, because the spam filter on your site.)

So there I have a pseudo field.
But how to use it?
How give it some value .... ?

Hey, do you know if it is possible to add settings(like a field formatter settings) for a pseudo field?

There is no way to add a field formatter or setting for a pseudo field. The purpose of a field formatter is to get values from the db and produce a render array with it. Since a pseudo field do not store anything in the db, you have to build the render array directly from your hook_entity_view implementaion. However, you can manage a configuration related to this process and provide a form for it anywhere you want in a admin page, but there's no way to add it automatically in the field ui like field formatter settings does.

There an alternative way to achieve this, you can create a custom field type that actually do not store anything in db. Then you create a field formatter for it, so can manage settings here.

Can we have the option to show or hide the label of the field?

And the 5th param

 $language

in

hook_ENTITY_TYPE_view()

I think that is not more used, see the docs (note: I don't know why I can't write here the url)

To make it easy for developers to create a Pseudo field, I have made Extra Field module. Developers can create extra fields by only creating a single plugin. Example plugins are provided.

Danny, thanks for the inspiration.

Pseudo field vs Display Suite
What is the better in productivity, performance and speed?

Hi Danny,

I have created a pseudo field taking inspiration from your code. Now how can a create a simple checkbox setting while creating a node to show/hide pseudo field per node?

Thanks

I had done this before in D7, and was wondering how to accomplish it in D8. I was thinking it was going to be more complex, but pretty similar to D7. Thanks!

Great article and really great book!
How can this field be themed like a normal field using field.html.twig? I don't want to include too much HTML in the markup, and would like to have it themed like a normal one.

Add new comment

You must have Javascript enabled to use this form.