Creando pseudo-campos con el modulo Extra Field

4 minutos

Los Pseudo-campos(Extra fields) son campos de visualización que puedes crear por código y son administrables desde la página de gestión de presentación de las entidades.

Por qué usar el modulo Extra Field?

Actualmente para crear un Pseudo-campo necesitamos usar 2 hooks:

  • hook_entity_extra_field_info:
    Para definir el nombre de tus campos y a que entidades aplican.
  • hook_ENTITY_TYPE_view:
    Para mostrar los campos que definiste con el hook anterior.

La verdad el proceso es bastante sencillo, como con muchos hooks, pero justamente una de las razones por las que Drupal ha ido migrando este tipo de Hooks a Events o Plugins es porque cuando ya necesitas crear muchos campos todo queda en tu archivo .module haciendo tu código menos legible.

Aquí es donde el módulo Extra Field entra en acción definiendo un tipo de Plug-in que te permite crear pseudo campos de una manera más organizada y si además instalas el módulo Extra Field Plus puedes definir opciones para tus campos, te lo mostraré con un ejemplo.

¿Qué vamos a hacer?

Para mostrarte como podemos usar este módulo voy a crear un campo Título/Label para el tipo de entidad nodo, ya te habrás dado cuenta de que el core de Drupal no viene con este campo en la presentación de contenido y aunque aparece cuando usas módulos como Layout Builder o Display Suite, para este caso lo vamos a crear nosotros para aprender un poco.

Aquí está el paso a paso.

  1. Instala el módulo Extra Field
  2. Vamos a /admin/structure/types/manage/article/display/teaser y comprobemos que no existe al campo llamado Label, para la presentación de resumen de los artículos.
  3. Creemos el módulo que va a contener nuestro código, lo llamaremos my_fields, así que vamos a crear una carpeta vacía con ese nombre dentro de modules/custom.
  4. Agreguemos el archivo my_fields.info.yml que quedará como te muestro a continuación
    name: 'My Fields'
    type: module
    description: 'Custom Display Fields'
    core: 8.x
    core_version_requirement: ^8 || ^9
    package: 'Custom'
    dependencies:
      - extra_field:extra_field
    

     

  5. Ahora vamos a crear el archivo que tendrá el código de nuestro campo, espero que al verlo puedas comprobar que es mucho más legible y mantenible de esta forma, este archivo debe estar ubicado en src/Plugin/ExtraField/Display/Label.php y contiene el siguiente código:
    <?php
    
    namespace Drupal\my_fields\Plugin\ExtraField\Display;
    
    use Drupal\Core\Entity\ContentEntityInterface;
    use Drupal\Core\StringTranslation\StringTranslationTrait;
    use Drupal\extra_field\Plugin\ExtraFieldDisplayFormattedBase;
    
    /**
     * Label Extra field with formatted output.
     *
     * @ExtraFieldDisplay(
     *   id = "entity_title",
     *   label = @Translation("Label"),
     *   bundles = {
     *     "node.*",
     *   },
     *   visible = false
     * )
     */
    class Label extends ExtraFieldDisplayFormattedBase {
    
      use StringTranslationTrait;
    
      /**
       * {@inheritdoc}
       */
      public function getLabel() {
        return $this->t('Label');
      }
    
      /**
       * {@inheritdoc}
       */
      public function getLabelDisplay() {
        return 'hidden';
      }
    
      /**
       * {@inheritdoc}
       */
      public function viewElements(ContentEntityInterface $entity) {
        $label = $entity->label();
    
        $element = [
          '#type' => 'html_tag',
          '#tag' => 'h2',
          '#value' => $label,
        ];
    
        return $element;
      }
    
    }
    

     

  6. La estructura de nuestro módulo debe quedar así:
    ExtraField module structure
  7. Limpiamos el caché del sitio.
  8. Si ahora vamos a /admin/structure/types/manage/article/display/teaser debes ver un nuevo campo disponible llamado Label
    Label Drupal Extra Field
  9. Si agregas ese campo a la presentación de tus contenidos aparecerá el título en un a etiqueta <h2>. y lo mejor es que puedes controlar desde la administración de tu sitio la posición del campo como lo haces con otros.

Analicemos el código del archivo Label.php

/**
 * Label Extra field with formatted output.
 *
 * @ExtraFieldDisplay(
 *   id = "entity_title", <- Nombre Maquina
 *   label = @Translation("Label"), <- Nombre con el que aparecerá en la UI de Drupal
 *   bundles = { <- Tipos de entidad en los que estará disponible.
 *     "node.*",
 *   },
 *   visible = false <- Visibilidad por defecto.
 * )
 */

Esta es la anotación de nuestro campo donde definimos su nombre máquina, nombre para la UI, tipos de entidades donde estará disponible, en este caso está disponible para todos los tipos de nodos, aunque también podríamos que sea solo para los artículos de la siguiente manera node.article en lugar de node.*, y por último definimos su visibilidad por defecto la que personalmente prefiero dejarla en false para que pueda por medio de la UI decidir es que casos quiero mostrarlo.

public function getLabel() {
  return $this->t('Label');
}
...
public function getLabelDisplay() {
  return 'hidden';
}

Con el método getLabel estamos definiendo la etiqueta de nuestro campo y con getLabelDisplay si la etiqueta es visible o no.

public function viewElements(ContentEntityInterface $entity) {
  $label = $entity->label();

  $element = [
    '#type' => 'html_tag',
    '#tag' => 'h2',
    '#value' => $label,
  ];

  return $element;
}

El método viewElements es el que más nos interesa, ya que es donde vamos a construir lo que queremos mostrar en nuestro campo, en este caso es una arreglo renderizable que muestra el título de la entidad/nodo como un encabezado tipo H2.

Conclusión

El módulo Extra Field nos permite estructurar mejor el código para nuestros campos personalizados y te puedes dar cuenta de que esto es mucho más mantenible que tratar de meter una vista o cualquier otro HTML directamente en los archivos de twig o con funciones tipo preprocess.

En un próximo artículo te mostraré como complementar este campo usando el módulo Extra Field Plus.

Jidrone Drupal Developer
J. Ivan Duarte
Drupal Senior Developer

Share