logo

Extra Block Types (EBT) - Nueva experiencia con Layout Builder❗

Extra Block Types (EBT): tipos de bloques con estilo y personalizables: Presentaciones de diapositivas, Pestañas, Tarjetas, Acordeones y muchos más. Configuraciones integradas para fondo, DOM Box y plugins de JavaScript. Experimenta hoy el futuro de la construcción de diseños.

Módulos de demostración EBT Descargar módulos EBT

❗Extra Paragraph Types (EPT) - Nueva experiencia con Paragraphs

Extra Paragraph Types (EPT): conjunto de módulos basado en párrafos de forma análoga.

Módulos de demostración EPT Descargar módulos EPT

Scroll

Estructura básica de un módulo Drupal

20/06/2025, by Ivan

Parte II de la guía práctica para crear módulos básicos en Drupal 8
De .info a tests, solo lo esencial

Estructura básica

loremipsum.info.yml

name: Lorem ipsum
type: module
description: 'Generador Lorem ipsum para Drupal'
package: Development
core: 8.x
configure: loremipsum.form

Los archivos de info ahora están formateados como YML, y hay una diferencia entre módulos y temas que debe entenderse a través de la declaración de tipo. La declaración configure apunta a una ruta (más sobre esto más adelante), pero aparte de eso, no hay más. De hecho, este es el único archivo que necesitarás para tu módulo. Después de guardar esto (en la carpeta root/modules) puedes habilitar tu módulo en /admin/modules sin romper tu sitio. Pero como verás más adelante, esto no es suficiente.

loremipsum.module

<?php

use Drupal\Core\Routing\RouteMatchInterface;

/**
 * Implementa hook_help().
 */
function loremipsum_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'help.page.loremipsum':
      return t('
        <h2>Generador Lorem ipsum para Drupal.</h2>
        <h3>Instrucciones</h3>
        <p>Lorem ipsum dolor sit amet... <strong>¡Es broma!</strong></p>
        <p>Descomprime en la carpeta <em>modules</em> (actualmente en la raíz de tu instalación de Drupal 8) y habilita en <strong>/admin/modules</strong>.</p>
        <p>Luego, visita <strong>/admin/config/development/loremipsum</strong> y escribe tu propio conjunto de frases para construir texto generado aleatoriamente (o usa el Lorem ipsum por defecto).</p>
        <p>Finalmente, visita <strong>www.example.com/loremipsum/generate/P/S</strong> donde:</p>
        <ul>
          <li><em>P</em> es el número de <em>párrafos</em></li>
          <li><em>S</em> es el máximo número de <em>oraciones</em></li>
        </ul>
        <p>También hay un bloque generador donde puedes elegir cuántos párrafos y frases y hará el resto.</p>
        <p>Si lo necesitas, también hay un permiso específico llamado <em>generate lorem ipsum</em>.</p>
        <h3>Atención</h3>
        <p>La mayoría de los bugs han sido corregidos, se han cerrado los huecos, y se han añadido funciones. Pero este módulo sigue en desarrollo. Por favor reporta errores y sugerencias, ¿vale?</p>
      ');
  }
}

Es buena práctica colocar aquí al menos la llamada a hook_help(). También observa la declaración use, que apunta a la clase RouteMatchInterface. Esto principalmente porque hook_menu() ya no existe.

... Y a medida que avanzas notarás que el archivo .module también se usa para almacenar información de temas. Así que mantenlo en mente.

loremipsum.install

<?php

/**
 * @file
 * Funciones de instalación para el módulo Lorem ipsum.
 */

use Drupal\user\RoleInterface;

/**
 * Implementa hook_install().
 */
function loremipsum_install() {
  user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array(
    'generate lorem ipsum' => TRUE,
  ));
}

Aquí usamos otra clase: RoleInterface. Básicamente, este archivo le dice a Drupal: "tan pronto como este módulo esté habilitado, encuentra el permiso para generar lorem ipsum y actívalo".

¿Pero dónde se define ese permiso?

loremipsum.permissions.yml

generate lorem ipsum:
  title: 'Generar Lorem ipsum'

Como puedes ver, es mucho más simple que implementar hook_permission(). La sintaxis completa está en la documentación de PermissionHandler.

loremipsum.routing.yml

loremipsum.generate:
  path: '/loremipsum/generate/{paragraphs}/{phrases}'
  defaults:
    _controller: '\Drupal\loremipsum\Controller\LoremIpsumController::generate'
  requirements:
    _permission: 'generate lorem ipsum'

loremipsum.form:
  path: '/admin/config/development/loremipsum'
  defaults:
    _form: '\Drupal\loremipsum\Form\LoremIpsumForm'
    _title: 'Configuración de Lorem ipsum'
  requirements:
    _permission: 'administer site configuration'

El archivo de rutas reemplaza la llamada a hook_menu(). Cada entrada (sin sangría) indica una ruta, con líneas indentadas que detallan configuraciones específicas.

La ruta loremipsum.generate apunta a una página que acepta dos argumentos entre {}; corresponde a un controlador (más adelante hablaremos de esto), mientras que loremipsum.form apunta a un formulario (de configuración) con un título.

Ambas rutas requieren permisos, pero puedes reemplazarlos por _access: 'TRUE' para acceso ilimitado.

loremipsum.services.yml

Permite declarar un servicio personalizado.

loremipsum.links.menu.yml

loremipsum.form:
  title: 'Configuración de Lorem Ipsum'
  description: 'Configura los ajustes para el módulo Lorem Ipsum.'
  route_name: loremipsum.form
  parent: 'system.admin_config_development'

Mientras que el archivo de rutas crea la página en /admin/config/development/loremipsum, estas definiciones son necesarias para añadir la página al menú de administración.

loremipsum.links.task.yml

Definiciones para crear tareas locales (pestañas) adicionales para una ruta determinada.

loremipsum.links.action.yml

Definiciones para crear acciones locales (botones) adicionales para una ruta determinada.

loremipsum.links.contextual.yml

Definiciones para crear acciones contextuales adicionales para un elemento de interfaz de usuario personalizado.

loremipsum.libraries.yml

Se usa para declarar dependencias de bibliotecas CSS y Javascript. Más información en la sección correspondiente.

README.md

Descomprime en la carpeta *modules* (actualmente en la raíz de tu instalación de Drupal 8) y habilita en `/admin/modules`.

Luego visita `/admin/config/development/loremipsum` y escribe tu propio conjunto
de frases para generar texto aleatorio (o usa el Lorem ipsum por defecto).

Finalmente, visita `www.example.com/loremipsum/generate/P/S`, donde:
- * P * es la cantidad de *párrafos*
- * S * es el máximo número de *oraciones*

También hay un bloque generador donde puedes elegir cuántos párrafos y
frases quieres, y hará el resto.

Si lo necesitas, también hay un permiso especial *generate lorem ipsum*.

Atención

La mayoría de errores han sido corregidos, huecos tapados, y funciones añadidas. Pero este módulo sigue en desarrollo. Por favor, reporta bugs y sugerencias, ¿vale?

Sí, ahora los archivos README se escriben en formato Markdown. Bastante genial, si me preguntas.

Ahora vamos a adentrarnos en las carpetas para estudiar con más detalle algunos aspectos específicos.

LICENSE.TXT

No incluyas un archivo LICENSE.txt (o similar). El script de empaquetado lo añadirá.

/config/install/loremipsum.settings.yml

loremipsum:
   page_title: 'Lorem ipsum'
   source_text: "Lorem ipsum dolor sit amet, consitteur adipisci elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua". En la vista en twist dice esse cillum dolore eu fugiat nulla pariatur. \ nExcepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est labour."

En este archivo se almacenan las configuraciones por defecto que se asignan a los campos correspondientes a través del siguiente archivo:

loremipsum:
  page_title: 'Lorem ipsum'
  source_text: "Lorem ipsum dolor sit amet, consectetur adipisci elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \nUt enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \nDuis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \nExcepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

En este archivo se almacenan las configuraciones por defecto que se asignan a los campos correspondientes a través del siguiente archivo:

/config/schema/loremipsum.schema.yml

loremipsum.settings:
  type: config_object
  label: 'Configuración de Lorem Ipsum'
  mapping:
    loremipsum:
      type: mapping
      mapping:
        page_title:
          type: text
          label: 'Título de la página generador Lorem ipsum:'
        source_text:
          type: text
          label: 'Texto fuente para la generación de lorem ipsum:'
block.settings.loremipsum_block:
  type: block_settings
  label: 'Bloque Lorem ipsum'
  mapping:
    loremipsum_block_settings:
      type: text
      label: 'Configuración del bloque Lorem ipsum'

El archivo de esquema se usa incluso si no defines una tabla personalizada para tu módulo — aquí puedes ver los valores por defecto asignados a los campos del formulario de configuración.

Al desarrollar este código encontré que rellenar los campos "out of the box" fue una de las tareas más difíciles. Pero por suerte hay un módulo para eso: Inspector de Configuración para Drupal 8, que te ayudará a depurar las configuraciones por defecto.

Además, el archivo de esquema YML es muy útil en muchos aspectos.

/src/Controller/LoremIpsumController.php

<?php

namespace Drupal\loremipsum\Controller;

// Cambios siguiendo https://www.drupal.org/node/2457593
// Ver https://www.drupal.org/node/2549395 para métodos obsoletos
// use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Html;
// usar Html en lugar de SafeMarkup

/**
 * Rutinas de controlador para páginas Lorem ipsum.
 */
class LoremIpsumController {

  /**
   * Construye texto Lorem ipsum con argumentos.
   * Esta función está mapeada a la ruta
   * 'loremipsum/generate/{paragraphs}/{phrases}'.
   * 
   * @param string $paragraphs
   *   La cantidad de párrafos que se necesitan generar.
   * @param string $phrases
   *   La cantidad máxima de frases que se pueden generar dentro de un párrafo.
   */
  public function generate($paragraphs, $phrases) {

Hemos llegado al núcleo de este módulo, la clase con un único método que genera el texto relleno. Como ves, el método generado dentro de la clase LoremIpsumController corresponde a la entrada en el archivo de rutas YML:

04_3

En el recuadro blanco está el código del archivo: loremipsum.routing.yml y el fondo del archivo con el que trabajamos.

Ahora continuamos, el siguiente fragmento de código obtiene la configuración del módulo y la guarda para uso posterior:

    // Configuración por defecto.
    $config = \Drupal::config('loremipsum.settings');
    // Título de página y texto fuente.
    $page_title = $config->get('loremipsum.page_title');
    $source_text = $config->get('loremipsum.source_text');

Los parámetros mencionados arriba (loremipsum.page_title y loremipsum.source_text) provienen del archivo de configuración YAML:

05_3

Luego dividimos las frases del $source_text en un arreglo:

$repertory = explode(PHP_EOL, $source_text);

Y usamos este arreglo para construir párrafos de texto:

    $element['#source_text'] = array();

    // Generar X párrafos con hasta Y frases cada uno.
    for ($i = 1; $i <= $paragraphs; $i++) {
      $this_paragraph = '';
      // Cuando decimos "hasta Y frases", no podemos significar "de 1 a Y".
      // Así que vamos desde la mitad hacia arriba.
      $random_phrases = mt_rand(round($phrases / 2), $phrases);
      // Además no repetir la última frase.
      $last_number = 0;
      $next_number = 0;
      for ($j = 1; $j <= $random_phrases; $j++) {
        do {
          $next_number = floor(mt_rand(0, count($repertory) - 1));
        } while ($next_number === $last_number && count($repertory) > 1);
        $this_paragraph .= $repertory[$next_number] . ' ';
        $last_number = $next_number;
      }
      //$element['#source_text'][] = SafeMarkup::checkPlain($this_paragraph);
        $element['#source_text'][] = Html::escape($this_paragraph);

    }

Nota que ['#source_text'] es un arreglo de renderizado pasado a la plantilla, y que cada elemento en ese arreglo pasa por Html::escape() para seguridad.

Finalmente, damos a nuestro arreglo de renderizado un título, asignamos una función tema y lo retornamos:

    //$element['#title'] = SafeMarkup::checkPlain($page_title);
    $element['#title'] = Html::escape($page_title);
     
    // Función tema.
    $element['#theme'] = 'loremipsum';
    
    return $element;
  }

}

Pero antes de pasar esta variable a nuestra plantilla, necesitamos procesarla.

Próximo paso;

Tematizar el módulo.

Siguiente;

Agregar formulario de configuración.

Definir un bloque para este módulo.

Escribir pruebas para este módulo.

Source URL:

Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.