Plugin API (I) - Introducción a la creación de plugins en Drupal 8 y Drupal 9

Plugins

Photo by Xavi Cabrera on Unsplash

Durante mi experiencia profesional he podido comprobar la gran relevancia que tienen los plugins en el desarrollo de sites con Drupal 8 y Drupal 9. Con el objetivo de allanar un poco el camino (y siendo sincero, como método personal para adquirir y estructurar mentalmente todo lo que he podido ir recopilando) he decidido realizar una serie de artículos donde profundizar en este asunto.

Empecemos por el principio, la Plugin API es el conjunto de clases, interfaces, métodos y recursos disponibles para gestionar plugins que proporciona Drupal. ¿Pero que es un plugin?

Una forma de tener una visión general de lo que es un plugin, para así poder definirlo podría ser:

“Los plugins son piezas o componentes adicionales que proporcionan elementos reutilizables y extensibles que nos servirán para añadir una funcionalidad específica a nuestro site.”

Además los plugins que desarrollan una misma funcionalidad, se generan o instancian partiendo del mismo tipo de plugin.

¿Muy complejo verdad?

Para simplificar todo esto a mi me gusta imaginarme los plugins como piezas de un juego de contrucción. Imaginemos que tenemos un gran núcleo central (nuestro site Drupal inicial) al que le podemos incorporar estas piezas para contruir algo diferente. Del mismo modo tendremos piezas mas largas, otras mas anchas y con distintos colores; pues bien, imagina que los plugins que cubren una misma funcionalidad son piezas con las mismas características.

Por ejemplo, los bloques son un tipo de plugin, por tanto todos los plugins de tipo bloque los podemos imaginar como piezas de la misma longitud y anchura; solo los diferenciará su color.

(Seguimos) Los plugins se agrupan según tipos de plugins los cuales están gestionados por un “plugin manager service”. Este servicio utiliza un metodo de descubrimiento de plugin o “plugin discovery method” para descubrir los plugins de cada tipo en el sistema y como se crearán o instanciarán utilizando una “plugin factory”. Para el descubrimiento de plugins, el plugin manager cuenta con varias alternativas: Annotations, Hooks, Yaml o Statics.

Por lo general los tipos de plugins incluyen una clase base para facilitar la instanciación de plugins; por ejemplo, para un plugin de tipo bloque utilizaremos la clase BlockBase para que nuesto plugin extienda a partir de ella.

Los plugins que se basan en Annotations lo hacen para que a través de esta nomenclatura puedan ser registrados en el sistema y descubiertos por el plugin manager. Para obtener un poco más de información sobre Annotations y como funcionan te recomiendo que revises el artículo que publiqué sobre comandos Drush: https://riloto.github.io/drush-commands/ donde entro un poco más en detalle sobre su funcionamiento.

Creación de un Plugin

Como ejemplo de creación de plugins vamos a implementar un plugin de tipo bloque describiendo con detalle cada uno de sus elementos. Al igual que para muchos otros elementos necesitamos un módulo custom que nos sirva de base para incorporar el código de nuestro plugin.

Comenzaremos creado el fichero de nuestro plugin en la siguiente ruta: /src/Plugin/Block.

Para crear un plugin de tipo bloque debemos extender de la clase \Drupal\Core\Block\BlockBase que implementa la interfaz \Drupal\Core\Block\BlockPluginInterface.

namespace Drupal\my_module\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
 * Provides a Simple example block.
 *
 * @Block(
 *   id = "my_module_simple_block",
 *   admin_label = @Translation("My Simple Block")
 * )
 */

class SimpleBlock extends BlockBase {

  public function build() {
    return [
      '#markup' => '<span>' . $this->t('Hello everyone, I am a block') . '</span>'
    ];
  }
}

En nuestro plugin hemos utilizado Annotations para registrarlo en el sistema como un plugin de tipo bloque. Para ello utilizamos la directiva @Block como se aprecia en el bloque de comentarios (No, esos comentarios no se pueden borrar. Son obligatorios). La propiedad id es el identificador único de nuestro plugin; generalmente se utiliza el nombre del módulo como prefijo; y la propiedad admin_label será el texto que se utilizará en el listado de administración de bloques.

Para los plugins solo existe un método que tengamos que definir obligatoriamente, y este es build(). En este método tenemos que devolver el contenido que devolverá nuestro bloque mediante un render array. En nuestro ejemplo se trata del texto “Hello everyone, I am a block” dentro de una etiqueta HTML “span” y utilizando la función t() para hacer el texto traducible.

Este método se exige desde la interfaz y no cuenta con una implementación por defecto en la clase BlockBase.

Habilitación del bloque

Cuando nuestro módulo se encuentre instalado, ya podremos ver nuestro bloque dentro del listado de bloques en la administración de Drupal (/admin/structure/block).

Block List

En nuestro ejemplo lo hemos colocado en la región “Sidebar Second” por lo que se nos muestra como en la imagen siguiente:

My Plugin

Configuración por defecto

Podemos establecer una configuración por defecto para todos los plugins mediante el método defaultConfiguration(). El usuario podrá editar esta configuración accediendo a la opción Configurar.

Los valores que podemos añadir a esta configuración por defecto están definidas en buildConfigurationForm de la clase BlockBase. En nuestro caso consultaremos el de BlockBase ya que hemos implementado un plugin te tipo bloque; pero en caso de que fuese un tipo de plugin diferente debemos consultar el método correspondiente a la clase base de nuestro plugin.

Para nuestro ejemplo vamos a modificar la propiedad ‘label’ que permite especificar el título que se mostrará para el bloque. En caso de no tener definido un valor personalizado, se utilizará el valor que hemos definido al crear el bloque (Annotations).

Como inicialmente no lo modificamos, el título que se muestra por defecto es “My Simple Block” como le indicamos en el annotation “admin_label”. Ahora vamos a modificarlo por “My awesome block” y marcaremos la opción “Display title” (deshabilitada por defecto) para que nos muestre nuestro nuevo título.

public function defaultConfiguration() {
  return [
    'label' => 'My awesome block',
    'label_display' => FALSE,
  ];
}

Por lo que cuando accedamos a configurar nuestro bloque, el título por defecto será:

Default Configuration

IMPORTANTE!! - Como ya hemos colocado nuestro bloque anteriormente, al añadir el código para defaultConfiguration() no se modificará el título que ya tiene. Por tanto si deseamos ver que nuestra configuración por defecto funciona deberemos eliminar el bloque y colocarlo de nuevo.

Pero tambien podemos colocarlo en una nueva región y ver la diferencia con el título que teníamos anteriormente. De modo, que vamos a escoger esta última opción que bajo mi punto de vista es mas esclarecedora.

Blocks Difference

EXTRA

Antes de comenzar con esta serie de artículos sobre plugins escribí hace tiempo este otro artículo: https://riloto.github.io/custom-fields/ donde se describe con detalle la creación de campos custom en Drupal 8.

Por supuesto esto se realiza implementando un Plugin con FieldType, FieldFormatter y FieldWidget; de modo que bien podría considerarse como el segundo artículo de la serie donde analizar un nuevo ejemplo de tipo de plugin.

Quizá te interese:

Written on October 13, 2021