programacion

Entity Api | Trabajando con entidades en Drupal 9

Video de Youtube
URL de Video remoto
Texto

Al trabajar con entidades, en nuestros módulos personalizados, podremos realizar todo tipo de comprobaciones, para asegurarnos de obtener los cambios o respuestas que esperamos según su tipo o relación.

 

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

     Esta vez nos toca abordar el tema de Cómo trabajar con la API de entidades en Drupal 9 o (Entity API). Como mencionamos en el capítulo anterior sobre Tipos de entidad en Drupal 9, a partir de Drupal 8 se recomienda que escribamos funciones y métodos con interfaces en lugar de clases.

     ¿Que son las Interfaces?

     Según la documentación oficial de PHP, en la programación orientada a objetos (OOP), las interfaces de objetos permiten crear código con el cual especificar qué métodos deben ser implementados por una clase, sin tener que definir cómo estos métodos son manipulados.

     Las interfaces se definen de la misma manera que una clase, aunque reemplazando la palabra reservada class por la palabra reservada interface y sin que ninguno de sus métodos tenga su contenido definido.

     Todos los métodos declarados en una interfaz deben ser públicos, ya que ésta es la naturaleza de una interfaz.

     Para implementar una interfaz, se utiliza el operador implements. Todos los métodos en una interfaz deben ser implementados dentro de la clase; el no cumplir con esta regla resultará en un error fatal. Las clases pueden implementar más de una interfaz si se deseara, separándolas cada una por una coma.

Entidades Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

     En Drupal, para las entidades genéricas utilizaremos los métodos y propiedades de EntityInterface como en hook_entity_insert(EntityInterface $entity) y para trabajar con nodos específicos, utilizaremos los métodos y propiedades de NodeInterface como en hook_node_insert(NodeInterface $node).

Entidades Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

Entidades Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Los métodos que cubren la mayoría de nuestras necesidades, cuando trabajamos con entidades genéricas son:

  • Entity::create()
     
  • Entity::load()
     
  • Entity::save()
     
  • Entity::id()
     
  • Entity::bundle()
     
  • Entity::isNew()
     
  • Entity::label()

    Comprobación de entidades (Check):

         Al trabajar con entidades, en nuestros módulos personalizados, podremos realizar todo tipo de comprobaciones, para asegurarnos de obtener los cambios o respuestas que esperamos según su tipo o relación.

         A continuación los ejemplos más frecuentes, en las operaciones de comprobación con entidades:

// Asegúrese de que un objeto sea una entidad.
if ($entity instanceof \Drupal\Core\Entity\EntityInterface) {
}

// Asegúrate de que sea una entidad de contenido.
if ($entity instanceof \Drupal\Core\Entity\ContentEntityInterface) {
}
// o también:
if ($entity->getEntityType()->getGroup() == 'content') {
}

// Obtener el tipo de entidad o el ID del tipo de entidad.
$entity->getEntityType();
$entity->getEntityTypeId();

// Asegúrate de que sea un nodo.
if ($entity instanceof \Drupal\node\NodeInterface) {
}

// El uso de entityType () funciona mejor cuando el tipo de entidad necesario es dinámico.
$needed_type = 'node';
if ($entity->getEntityTypeId() == $needed_type) {
}

     Obtener información de una entidad / métodos de entidad:

     Existe varios métodos genéricos disponibles para obtener información de una entidad, como el ID, el paquete, el ID de revisión, etc. Consulte la documentación de EntityInterface para obtener más detalles.

// Obtiene el ID de la entidad.
$entity->id();

// Obtiene el paquete.
$entity->bundle();

// Comprueba si la entidad es nueva.
$entity->isNew();

// Obtén la etiqueta de una entidad. Reemplazo de entity_label().
$entity->label();

// Obtener el objeto URL de una entidad.
$entity->toUrl();

// Obtener ruta interna, alias de ruta si existe, para una entidad.
$entity->toUrl()->toString();

// Cree un duplicado que se pueda guardar como una nueva entidad.
$duplicate = $entity->createDuplicate();

     Creación de entidades:

// Es recomendable que utilicemos el Entity Manager para crear entidades.
$node = \Drupal::entityTypeManager()->getStorage('node')->create(['type' => 'article', 'title' => 'Another node']);


// Podemos usar el método estático create () si conocemos la clase de entidad.
$node = Node::create([
  'type' => 'article',
  'title' => 'The node title',
]);

     Los valores predeterminados de configuración de la anotación de tipo de campo solo se agregan para las claves de nivel superior que faltan; no se realiza una fusión profunda.

     Evita usar el método estático Entity::create() en código orientado a objetos. En su lugar, use la inyección de dependencia para inyectar el administrador de tipos de entidad y crear la entidad con $this->entityTypeManager->getStorage($entity_type)->create(). Esto asegura que el código esté desacoplado correctamente y se pueda probar unitario.

     Si quieres saber más sobre la Inyección de Dependencias, te lo cuento en este artículo: Cómo crear un servicio personalizado en Drupal 9

     Para lograr la visibilidad dentro de un IDE, también puede asignar la interfaz de almacenamiento de la entidad a una propiedad. Por ejemplo, $this->nodeStorage = $this->entityTypeManager->getStorage('node'); Para crear una entidad, puede usar $this->nodeStorage->create().

     Carga de entidades (Load):

// Usando el controlador de almacenamiento (recomendado).
$entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load(1);

// Usa el método estático
$node = Node::load(1);

// Carga varias entidades, también existe como entity_load_multiple().
$entities = \Drupal::entityTypeManager()->getStorage($entity_type)->loadMultiple([1, 2, 3]);

// Cargar entidades por sus valores de propiedad.
$entities = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties(['type' => 'article']);

     Para actualizar una entidad, cárguela y luego guárdela con sus cambios.

         Evite usar el método estático Entity::load() en código orientado a objetos. En su lugar, use la inyección de dependencia para inyectar el administrador de tipos de entidad y cargar la entidad con $this->entityTypeManager->getStorage($entity_type)->load($entity_id). Esto asegura que el código esté desacoplado correctamente y se pueda probar unitario.

          Si quieres saber más sobre la Inyección de Dependencias, te lo cuento en este artículo: Cómo crear un servicio personalizado en Drupal 9

     Guardar los cambios en la entidad (Save):

// Para guardar los cambios en una entidad.
$entity->save();

     Eso funciona tanto para entidades nuevas como existentes, la propia entidad realiza un seguimiento de si es nueva o no. De forma predeterminada, para las entidades de contenido, eso depende de si tiene un ID o no. Para guardar una entidad que tiene un ID como una entidad nueva (por ejemplo, al importar algo), se puede aplicar la marca isNew.

// Lo siguiente intentará insertar un nuevo nodo con el ID 5, esto fallará si ese nodo ya existe.
$node->nid->value = 5;
$node->enforceIsNew(TRUE);
$node->save();

     Eliminar entidades (Delete):

// Eliminar una sola entidad.
$entity = \Drupal::entityTypeManager()->getStorage('node')->load(1);
$entity->delete();

// Elimina varias entidades a la vez.
\Drupal::entityTypeManager()->getStorage($entity_type)->delete([$id1 => $entity1, $id2 => $entity2]);

    Consultando entidades (Query):

$entity = \Drupal::entityTypeManager()->getStorage('node');
$query = $entity->getQuery();
    
$ids = $query->condition('status', 1)
 ->condition('type', 'article')#type = ID de paquete (nombre de la máquina)
 #->sort('created', 'ASC') #ordenada
 #->pager(15) #límite de 15 artículos
 ->execute();

// Cargar carga de artículo único o múltiple($id)
$articles = $entity->loadMultiple($ids);

     Control de acceso a entidades (Access control):

     El método access() se puede utilizar para comprobar quién puede hacer qué con una entidad. El método admite diferentes operaciones, las operaciones estándar son ver, actualizar, eliminar y crear, crear es algo especial, ver más abajo.

     Las comprobaciones de acceso se envían al controlador de acceso.

// Verifique el acceso a la vista de una entidad.
// De forma predeterminada, se verifica el acceso del usuario que ha iniciado sesión actualmente..
if ($entity->access('view')) {

}

// Compruebe si un usuario determinado puede eliminar una entidad.
if ($entity->access('delete', $account)) {

}

     Al marcar el acceso de creación, generalmente no hay una entidad todavía. Crear uno solo para comprobar si alguien podría crearlo es una operación costosa. Por lo tanto, la creación de acceso para aquellos debe verificarse directamente en el controlador de acceso.

\Drupal::entityTypeManager()->getAccessControlHandler('node')->createAccess('article');

     Si ya existe una entidad, $entity->access('create') también funciona, que solo reenvía al método  createAccess(), de la misma manera que otras operaciones reenvían al método access () en el controlador de acceso.

     NOTA: Algunas guías en línea usan \Drupal::entityManager(), pero está obsoleto en 8.x y se eliminará en 9.x. Entonces puede usar \Drupal::entityTypeManager() en lugar de \Drupal::entityManager().

Fuente: https://www.drupal.org/docs/drupal-apis/entity-api/working-with-the-entity-api#s-delete

Bloque personalizado | Creación programáticamente en Drupal 9

Video de Youtube
URL de Video remoto
Texto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

QUÉ ES UN BLOQUE Y CÓMO FUNCIONAN

     Hoy te quiero hablar sobre los bloques en Drupal, que no son más que regiones, en las que puedes incluir prácticamente cualquier tipo de contenido, imágenes, texto simple o añadir campos editables por el usuario y que luego podrán mostrarse en cualquier área y página de tu web, además de ofrecerte la opción para controlar quiénes podrán ver su contenido, configurando los permisos de usuario.

     Por defecto, una instalación de Drupal viene dividida en varias zonas con "Bloques" en su interior, el nombre y la cantidad de dichos bloques podrían variar, en función del "Theme" o tema que tengas instalado en tu proyecto. 

     Para que entiendas el concepto de Bloques, imagina que tu web es como una casa, con sus respectivas habitaciones, y que el mobiliario o la decoración que puedes añadir, quitar o modificar en cualquier de ellas es el bloque.

     Para administrar los bloques, tendrás que ir a la url "/admin/structure/block", allí encontrarás el listado de todos los bloques activados con las diferentes zonas de tu proyecto.

Custom Module Drupal  | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony

     Desde esta pantalla, tendrás la oportunidad de añadir cualquier otro bloque en la zona que desees, haciendo clic en el botón "Colocar Bloque" y seleccionando posteriormente cualquiera de los que se mostrará en el listado que te aparecerá a continuación. 

Custom Module Drupal  | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony

     Además de añadir, también podrás desactivar, recolocar o remover menús, vistas personalizadas del tipo bloque, información del sitio, etc. o si lo necesitaras, utilizar instancias del mismo bloque en zonas diferentes de tu web.

Custom Module Drupal  | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony

BIBLIOTECA DE BLOQUES PERSONALIZADOS

     Otra de las opciones disponibles al trabajar con bloques, es la Biblioteca de bloques personalizados, donde podrás crear un modelo de bloque, para reutilizarlo como base siempre que te haga falta. 

     Un ejemplo práctico, sería que tuvieras en tu web un tipo de bloque personalizado al que llamaras, por ejemplo "Banner Publicitario", con la opción de añadir, editar o eliminar dentro de él, diferentes imágenes anunciando ofertas o descuentos, en varias partes de la web, sin tener que construir cada vez un bloque nuevo.

     Los bloques personalizados se guardan en la pestaña "Biblioteca de bloques personalizados", y desde este apartado puedes modificar el modelo principal, por ejemplo añadiendo un botón que se llame "precio especial", y que automáticamente estará disponible para todo el resto de bloques que usan este modelo como base.

Custom Module Drupal  | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony

CÓMO CREAR UN BLOQUE PROGRAMÁTICAMENTE EN DRUPAL 9

PRERREQUISITOS:

     PASO 1 CREAR MÓDULO PERSONALIZADO:

          Lo primero que debemos hacer para crear un bloque, usando nuestro propio módulo, es añadir una carpeta con el nombre del módulo, dentro de la carpeta "modules/custom", con el objetivo de tener separados los módulos contribuidos de Drupal, que son los que descargamos desde la Página Oficial, y que si utilizamos Composer, se guardarán automáticamente en la ubicación "modules/contrib"

Custom Module Drupal  | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony

          Una vez hayamos creado la carpeta con el nombre de nuestro módulo, lo siguiente será añadir el archivo que utiliza Drupal para identificar cualquier módulo, el nombre de este archivo deberá coincidir con el nombre de nuestra carpeta y terminar con la extensión ".info.yml", en nuestro caso, nuestro archivo se llamará drupal_block.info.yml.

          Puedes crear el archivo y copiar el siguiente código dentro para continuar con el ejercicio.

name: Drupal Block
description: 'Create custom block'
package: drupaladicto

type: module
core_version_requirement: ^8.8.0 || ^9.0

          Puedes comprobar que todo funciona correctamente, si activas el módulo en la url "/admin/modules/". Aunque no hará más nada que confirmarte con un mensaje en la parte superior de la pantalla, indicándote que se ha activado correctamente.

Custom Module Drupal  | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony

     Ahora desinstala el módulo nuevamente, antes de continuar con las siguientes modificaciones para evitar errores.

     PASO 2 CREACIÓN DEL BLOQUE PERSONALIZADO:

          Para lograr que nuestro módulo personalizado genere un Bloque, una vez lo hayamos terminado, tendremos que crear varios archivos. 

          Crearemos tres carpetas: "src""Plugin" y "Block", estas deberán estar una dentro de la otra, respetando los estándares de estructura para que Drupal reconozca su contenido y funcione correctamente.

Custom Module Drupal  | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony

          A continuación, crearemos el archivo php con la clase responsable de construir nuestro módulo, es recomendable que el nombre de tu clase corresponda con el de tu módulo, utilizando Mayúsculas en el caso de que lo formen varias palabras. Por lo tanto, para nuestro ejemplo, la clase se llamará DrupalBlock.php y tendrá dentro el siguiente contenido:

<?php

namespace  Drupal\drupal_block\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
 * @Block(
 *   id = "Drupal Block",
 *   admin_label = @translation("Drupal Block"),
 *   category = @translation("Drupal Block"),
 * )
 */


class DrupalBlock extends BlockBase{

  /**
   * {@inheritdoc }
   */

  public function build(){
    return [
      '#markup' => $this->getFrases(),
      '#cache' => [
        'max-age' => 0,
      ]
    ];
  }
   private function getFrases(){
    $frase = [
      'Hola, que tal',
      'Otras vez por aquí?',
      'Nos vemos pronto!!!'
    ];
    return $frase[array_rand($frase)];
   }
}

     Explicación: 

          En la primera parte del código, tenemos el namespace, que permite a Drupal encontrar la ubicación de nuestro módulo para leer su contenido. A continuación, invocamos a la clase BlockBase, porque será necesaria para genera nuestro bloque, ya que heredaremos de ésta algunas funcionalidades, utilizando la palabra extends, que utilizaremos dentro de nuestra clase.

<?php

namespace  Drupal\drupal_block\Plugin\Block;

use Drupal\Core\Block\BlockBase;

 

     La siguiente fracción del código, corresponde a lo que se conoce como Annotations, puedes visitar la Página oficial de Drupal para saber más sobre ellas. En resumen, aunque su formato es similar al de los comentarios de Php, su función va mucho más allás, permitiendo pasar varios parámetros necesarios para que Drupal interprete, en este caso, que se trata de un Bloque personalizado y muestre varias informaciones relacionadas, que podremos ver una vez esté activado el módulo, dentro de la pantalla de Administración de Bloques.

/**
 * @Block(
 *   id = "Drupal Block",
 *   admin_label = @translation("Drupal Block"),
 *   category = @translation("Drupal Block"),
 * )
 */

     La última parte que nos falta, es el contenido en sí, de nuestra clase. En esencia, lo que estamos haciendo es, construir el bloque, utilizando el método build(){ }, que nos devolverá un arreglo o array, con un elemento html que envolverá una frase, además al refrescar el navegador, dicha frase también cambiará aleatoriamente, ya que hemos utilizado el array_rand() de php para conseguirlo.

class DrupalBlock extends BlockBase{

  /**
   * {@inheritdoc }
   */

  public function build(){
    return [
      '#markup' => $this->getFrases(),
      '#cache' => [
        'max-age' => 0,
      ]
    ];
  }
   private function getFrases(){
    $frase = [
      'Hola, que tal',
      'Otras vez por aquí?',
      'Nos vemos pronto!!!'
    ];
    return $frase[array_rand($frase)];
   }
}

Si quieres más información sobre los bloques personalizados, puedes visitar la página oficial de Drupal

Drush , introducción y comandos más útiles

Video de Youtube
URL de Video remoto
Texto

     Para todos los que trabajamos, en el desarrollo de páginas web utilizando Drupal, es muy importante que nos mantengamos informados, sobre las últimas actualizaciones, tanto a nivel de las funcionalidades o parches de seguridad, del propio CMS, como de las herramientas relacionadas con éste, por ejemplo, el gestor de paquetes Composer, recomendado para todos los proyectos, a partir de Drupal 8 y que hace poco, lanzó una nueva versión ( Cómo instalar Composer 2 en Ubuntu 20.04 ) o superior o la consola Drush.

     Con el propósito de facilitar tus tareas de desarrollo, hoy quiero hablarte sobre, La interfaz de línea de comandos (en inglés, command-line interfaceCLI), que se utiliza en Drupal, conocida como Drush, para que puedas sacarle el mayor provecho posible y obtener mejores resultados.

   INSTALACIÓN DE DRUSH CON COMPOSER

        Hace varios años, se recomendaba que al trabajar con Drush y Drupal, realizáramos una instalación global, con la que pudiéramos efectuar toda clase de operaciones, sin importar la versión de nuestro proyecto; pero a partir de Drupal 8, se comenzó a proponer instalaciones individuales, para evitar errores producidos por incompatibilidades, ya fuera entre versiones de php, o del núcleo de Drupal.

        Actualmente, para instalar Drush en cualquier proyecto de Drupal 8 o superior, utilizaremos el gestor de paquetes Composer, y al igual que con otros módulos de Drupal, dejaremos en él la responsabilidad de descargar todos los archivos necesarios para su funcionamiento, para ello escribiremos desde la carpeta raíz de nuestra instlación, el siguiente comando:

composer require drush/drush

     De inmediato se iniciará el proceso de descarga de la versión más actual y estable, que esté disponible sobre esta herramienta de comandos, en el momento en que escribo este artículo, es la versión 10.5.0

Drush Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

     DRUSH LAUNCHER

         Con el Drush Launcher podrás ejecutar comandos de Drush en todos tus proyectos, sin la necesidad de escribir la ruta completa ej: "/vendor/bin/drush cr". Exiten varias formas para descargar e instalarlo, puedes revisar la documentación en Repositorio Drush Launcher

     5 COMANDOS DRUSH QUE DEBERÍAS CONOCER

     GENERAR UN MÓDULO

       Drush te genera automáticamente y de manera configurable, toda la estructura de archivos necesaria para crear un módulo. (Funcionalidad de la antigua Drupal Console)

drush generate module

Drush Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

Drush Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

     RECUPERAR ACCESO ADMIN

     En algunos casos, es posible que perdamos el acceso del usuario admin, al realizar algún traspaso de entornos o no haber guardado los datos de acceso en un lugar fácil de encontrar. Para estos casos, el siguiente comando te da la posiblidad de acceder como administrador para que puedas cambiar la clave de acceso por una nueva.

drush:uli 

     Forma de uso: Copia en el navegador el enlace generado, a partir de "/user" y pégalo en el navegador a continuación del dominio de tu página. Al presionar enter accederás directamente a la página de configuración del usuario administrador para que puedas cambiar la clave de acceso sin necesidad de acordarte de la anterior.

Drush Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

     VER LA TABLA DE ERRORES SIN ABRIR DRUPAL

     Como ya sabrás, Drupal ofrece la posibilidad de verificar, todos los errores que registra a nivel de base de datos, ya que los guarda en una tabla llamada Watchdog, con Drush podrás acceder a estos datos, sin la necesidad de entrar a la interfaz de usuario usando el siguiente comando:

drush wd-show

     Al ejecutarlo, verás inmediatamente en consola, todos los datos que haya guardado Drupal dentro de esta tabla, facilitándote el análisis de posibles errores más rápidamente.

Drush Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

     VER LOS MÓDULOS Y/O TEMAS ACTIVADOS

     En algunos proyectos, sobretodo cuando se trata de instalaciones muy grandes, necesitamos tener una idea rápida de los módulos o temas que se encuentran activados en un momento determinado. Este comando nos mostrará en pantalla, un listado completo de todos los módulos y temas, con la correspodiente información acerca su versión y de si están o no activados.

drush pml

Drush Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

     EXPORTAR BASE DE DATOS COMPLETA

     Cuando estamos haciendo el traspaso de entornos, es posible que necesitemos exportar toda la base de datos para dicho traspaso, con este comando, podremos generar rápidamente un backup que se guardará a la altura de nuestra carpeta raíz del proyecto:

drush sql:dump --result-file=../mi_backup.sql

Drush Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

     BORRAR BASE DE DATOS EXISTENTE:

drush sql-drop

     IMPORTAR UNA COPIA DE LA BASE DE DATOS:

drush sql-cli < ~/my-sql-dump-file-name.sql

Volcará la base de datos y la comprimirá, colocándola en el directorio predeterminado de drush bajo una marca de tiempo

drush sql-dump --gzip --result-file

Volcará la base de datos en el archivo especificado antes de comprimirlo con gzip

drush sql-dump --gzip --result-file=/path/to/file.sql

Fijar un tema por defecto para tu instalación de Drupal, ejemplo el theme Bartik

drush config-set system.theme default bartik

     Puedes aprende más sobre el uso y los comando de drush, visitando su drushcommands o www.drush.org/latest/

Tablas | Creación programáticamente en Drupal 9

Video de Youtube
URL de Video remoto
Texto

     A veces, cuando trabajamos en proyectos web utilizando Drupal, nos encontraremos con la necesidad de añadir en un solo módulo, todos los elementos que vamos a utilizar, ya sea porque se trate de un proyecto existente al que vamos a agregar una nueva funcionalidad, o por que este desarrollo pueda implementarse en varios proyectos a la vez, compartiéndolo con otros miembros del equipo de trabajo o de una comunidad de desarrolladores.

     Ya hemos explicado Cómo crear un módulo en Drupal 9 y además ya tienes los conocimientos necesarios para saber Cómo crear formularios programáticamente en Drupal 9, por lo tanto, el próximo paso, antes de desarrollar módulos más complejos, sería descubrir la forma de añadir tablas en tu base de datos, para que puedas controlar los elementos que instalarás relacionados con tu módulo.

     Por esta razón, hoy nos enfocaremos en la implementación de los requerimientos necesarios para crear, programáticamente, una o varias tablas, dependiendo de la necesidad que tengas para tu proyecto, utilizando el hook_schema(), dentro del archivo install en nuestro proyecto Drupal 9. 

Requisitos:

Cómo crear tablas programáticamente en Drupal 9

    Hoy aprenderemos a utilizar el archivo "MIMODULO.install" dentro de nuestro módulo personalizado. Si ponemos atención en la manera de implementarlo dentro de nuestros proyectos, tendremos el conocimiento suficiente para crear módulos más complejos, que nos permitirán la creación de contenidos directamente dentro de la base de datos de Drupal.

     Un ejemplo práctico, que explicaremos en otro artículo y su respectivo video, sería un módulo que al instalarse, además de crear una tabla, con la configuración necesaria para guardar la información sobre los participantes a un curso, nos añadiera un formulario de inscripción, conectado a esta tabla, con el cual los usuarios pudieran rellenarla directamente.

       Paso 1 Creación de tu módulo:

          Lo primero que deberías saber es cómo crear un módulo personalizado. Esencialmente para este ejemplo, lo que necesitarás será una carpeta con el nombre de tu módulo y dentro el archivo con el nombre del módulo y la extensión, eje.: "mimodulo.info.yml"

name: Mi tabla
description: 'Crea una tabla'
package: drupaladicto

type: module
core_version_requirement: ^8.8.0 || ^9.0

     Paso  2 Creación del archivo .install:

     En el archivo "MIMODULO.install", es donde tendremos que indicarle a Drupal la configuración para que pueda crear nuestra tabla, para ello utilizaremos el "hook_schema()", que se encargará de interpretar los datos y creará dicha tabla.

/**
 * Implment hook_schema()
 */
function mi_tabla_schema() {

  $schema['mitabla'] = array(
    'description' => 'Guarda los datos de los participantes',
    'fields' => array(
      'pid' => array(
        'type' => 'serial',
        'not null' => TRUE,
        'description' => 'Primary Key: Identificador único del participante.',
      ),
      'uid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => "Creador de usuarios {users}.uid",
      ),
      'nombre' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
        'description' => 'Nombre del participante.',
      ),
      'apellido' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
        'description' => 'Apellido del participante.',
      ),
      'edad' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
        'description' => 'Edad del participante.',
      ),
    ),
    'primary key' => array('pid'),
    'indexes' => array(
      'nombre' => array('nombre'),
      'apellido' => array('apellido'),
      'edad' => array('edad'),
    ),
  );
  return $schema;
}

     Explicación:

          En la primera parte del hook_schema(), estamos definiendo el nombre de la tabla dentro de un array global, que es nuestro esquema $schema['mi_tabla'] = [ ], dentro de este array general, tendremos dos elementos fundamentales, que son el campo con la descripción de la tabla y a continuación otro array general, llamado "'fields' => array()", que será donde iremos añadiendo todos los campos, con sus respectivos atributos, como tipo de campo, si es nulo, si tendrá valor por defecto, etc.

$schema['mitabla'] = array(
  'description' => 'Guarda los datos de los participantes',
  'fields' => array(
    'pid' => array(
      'type' => 'serial',
      'not null' => TRUE,
      'description' => 'Primary Key: Identificadro único del participante.',
    ),
    'uid' => array(
      'type' => 'int',
      'not null' => TRUE,
      'default' => 0,
      'description' => "Creator user's {users}.uid",
    ),
    'nombre' => array(

     Luego de definir todos los campos, encontraremos en la parte inferior del "hook_schema()", el lugar donde definiremos la clave primaria de nuestra tabla, acompañada de los índices.

),
'primary key' => array('pid'),
'indexes' => array(
  'nombre' => array('nombre'),
  'apellido' => array('apellido'),
  'edad' => array('edad'),
),

     Por último, y no menos importante, está el retorno del esquema, que es quien permitirá verdaderamente que Drupal pueda ejecutar toda la información que hemos añadido en el mismo.

  );
  return $schema;
}

     Opcional Creación de datos por defecto:

          Para nuestro ejemplo, además de implementar el hook_schema() y generar nuestra tabla, hemos decidido añadir además, algunos datos por defecto, que se colocarán en sus respectivos campos, al momento de instalar nuestro módulo.

         Para realizar esta operación, hemos implementado el "hook_install()" target="_blank", que se ejecutará una vez se haya ejecutado el hook_schema() y esté generada nuestra tabla.

/**
 *  hook_install()
 */
function mi_tabla_install() {
  $values = [
    [
      'nombre' => 'Pepito',
      'apellido' => 'Pérez',
      'edad' => 30,
      'uid' => 1,
    ],
    [
      'nombre' => 'Ana',
      'apellido' => 'Medina',
      'edad' => 28,
      'uid' => 1,
    ],
  ];
  $database = \Drupal::database();
  $query = $database->insert('mitabla')->fields(['nombre', 'apellido', 'edad', 'uid']);
  foreach ($values as $participante) {
    $query->values($participante);
  }
  $query->execute();

}

     Explicación:

     En la primera parte de este "hook_install()", estamos pasándole a drupal los valores que se añadirán a los campos de nuestra tabla, dentro del array "$values = [ ] ", debes asegurarte que cada campo corresponde, con los que haz definido en dentro del $schema[ ].

$values = [
  [
    'nombre' => 'Pepito',
    'apellido' => 'Pérez',
    'edad' => 30,
    'uid' => 1,
  ],
  [
    'nombre' => 'Ana',
    'apellido' => 'Medina',
    'edad' => 28,
    'uid' => 1,
  ],
];

     En la siguiente parte, utilizando el servicio "\Drupal::database();", realizamos una consulta a la base de datos y mediante un insert, añadimos a la tabla, los campos correspondientes dentro del array fields, luego recorremos todos valores, utilizando el foreach y por último, ejecutamos la consulta.

$database = \Drupal::database();
$query = $database->insert('mitabla')->fields(['nombre', 'apellido', 'edad', 'uid']);
foreach ($values as $participante) {
  $query->values($participante);
}
$query->execute();

Módulo personalizado en Drupal 9 (Parte 3)

Video de Youtube
URL de Video remoto
Texto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

Cómo crear un módulo en Drupal 9 (3ra Parte)

Para completar nuestro pequeño tutorial sobre Cómo crear un módulo en Drupal 9, sólo nos falta saber cómo añadir un enlace desde el menú principal para que los usuarios puedan navegar hasta el contenido de nuestro módulo e interactuar con él.

Por último veremos cómo configurar permisos para restringir el acceso y así podremos decidir, qué tipo de usuarios podrán ver, editar o administrar el contenido relacionado con nuestro módulo.

Antes de continuar, te recomiendo que leas Cómo crear un módulo en Drupal 9, para que puedas realizar el proceso paso a paso y entender en qué consiste y de esta manera, a medida que avances, acumularás la experiencia y conocimientos necesarios, que te ayudarán en el desarrollo de módulos y funcionalidades más avanzadas para tus proyectos en Drupal 9.

 

Si ya lo tienes, vamos a empezar...

En esta ocasión, vamos a añadir un enlace, en el menú principal de la web, que apuntará a la página del controlador con la cual estuvimos trabajando en el anterior artículo, si todavía no lo haz leído, aquí lo tienes Cómo crear un módulo en Drupal 9 (2da Parte), si ya lo haz hecho, recordarás que la url de la que hablamos, es la que pusimos dentro del mi_modulo.routing.yml, en el apartado de "path", en mi caso esta url de la página es "/mypage", pero tú puedes poner la que quieras.

Ahora, nos toca crear un nuevo archivo, al que llamaremos mi_modulo.links.menu.yml y dentro colocaremos el siguiente contenido, recuerda respetar los espacios y no utilices el tabulador; en su lugar, utiliza la barra espaciadora y deja dos espacios, en los casos necesarios, contando a partir del margen izquierdo.

mi_modulo.mynewpage:
  title: 'My Page'
  description: 'Page Created with MyModule'
  route_name: mymodule.mypage
  weight: 10
  menu_name: main

A continuación te explico cada parte del archivo para que puedas entenderlo y hacer los cambios necesarios y adaptarlos a tu propio módulo:

mi_modulo.mynewpage:

En esta primera línea, hemos utilizado el nombre de nuestro módulo, esto se recomienda para evitar conflictos con otros módulos existentes, y luego está el nombre con que el que idenficaremos este comportamiento .mynewpage: , presta mucha atención en los detalles, en la primera línea no hemos dejado ningún espacio a la izquierda y tenemos los dos puntos al final.

  title: 'My Page'
  description: 'Page Created with MyModule'

Las dos líneas siguientes, simplemente indican el nombre que aparecerá en el botón del menú y un texto descriptivo, que se mostrará al colocarnos encima de dicho botón. Haz visto que a partir de aquí, siempre mantenemos dos espacios con respecto al margen izquierdo de la página. Si por error, sobra o falta un espacio, el archivo no funcionará.

  route_name: mymodule.mypage

Seguro que en esta línea, hay algo que te suena haber visto anteriormente, si es así, felicidades por prestar atención a los detalles, me refiero al nombre de la ruta, el que definimos en la primera línea del archivo mi_modulo.routing.yml, con ello indicamos a Drupal, que al hacer clic en el elemento del menú correspondiente, deberá buscar esta ruta y mostrar los contenidos definidos en dicho archivo.

  weight: 10
  menu_name: main

Para finalizar, indicamos la posición del enlace con respecto a otros elementos del menú utilizando el "weight" o peso; los elementos del menú cuentan a partir de la posición Cero y tendrán valores positivos o negativos, correspondientes a si estarán debajo o encima del elemento cuyo "weight" o peso equivale a Cero.

En la última línea, indicamos el Menú Padre "main", para nuestro enlace, como dijimos al principio, en este caso, el botón para este módulo personalizado, estará dentro del menú principal.

Ahora vamos a echar un vistazo a los permisos del módulo

Una de las ventajas que ofrece el desarrollo de webs utilizando CMS o gestores como Drupal, es la capacidad para gestionar usuarios y restringir sus accesos, según creamos conveniente.

Para añadir permisos específicos en nuestro módulo personalizado, tendremos que crear un archivo, al que, en este ejemplo, llamaremos mi_modulo.permissions.yml y lo siguiente que haremos es añadir estas líneas: 

view mymodule:
  title: 'Ver contenido'
  description: 'El usuario puede ver el contenido relacionado con el módulo'
access mymodule:
  title: 'Acceder a contenido restringido'
  description: 'El usuario con este permiso podrá ver contenido restringido'
administer mymodule:
  title: 'Administrar el módulo'
  description: 'Sólo los administradores podrán modificar la configuración del módulo'
  restrict access: TRUE

Si ya conoces el apartado de Drupal, donde puedes gestionar los permisos para los usuarios, o sea la url que te lleva será algo como "http://drupal9composer.localhost/admin/people/permissions", una vez creado este nuevo archivo, al vaciar las cachés, podrás comprobar que los nuevos permisos se han añadido al listado y que estarán para activarlos según el rol que desees.

Custom Module Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

Un último apunte, para que tus permisos tengan efecto deberás modificar la última línea del mi_modulo.rounting.yml y cambiar el "access content", por el nombre del permiso que desees aplicar, ejemplo (access mymodule), te dejo una imagen para que lo veas mejor.

Custom Module Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

Espero haberte ayudado a comprender un poco más sobre Drupal y que puedas crear o trabajar en grandes proyectos donde poner a prueba tus conocimientos, experiencias y ganas de superación.

¡Hasta la próxima y buena suerte!

 

Módulo personalizado en Drupal 9 (Parte 2)

Video de Youtube
URL de Video remoto
Texto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

Cómo crear un módulo en Drupal 9 (2da Parte)

Siguiendo con el desarrollo de nuestro módulo personalizado, hoy trataré de explicarte qué es el controlador o Contoller, para qué nos sirve y cómo podemos añadirlo a nuestro módulo personalizado.

Si todavía no haz creado tu módulo personalizado, antes de continuar leyendo, te recomiendo que primero leas Cómo crear un módulo en Drupal 9 (1era Parte), sigue los pasos y cuando tengas el módulo funcionando, vuelve aquí para que puedas seguir ampliándolo y entendiendo el proceso de desarrollo.

Una de las estructuras o formas de desarrollo para toda clase de aplicaciones y que además emplean los más conocidos frameworks que existen en el mercado, es el (MVC), o separación del código según sus funcionalidades en "Modelo Vista y Controlador", que esencialmente divide el total del código de la siguiente forma:

  • La parte correspondiente a la base de datos es para el (Modelo)
     
  • La parte correspondiente a mostrar los datos es para (Vista)  
     
  • La parte que sirve para conectar MODELO+ VISTA es para (Controlador o Controller)

Ahora bien, ¿Cómo aplicaremos esto dentro de nuestro módulo personalizado?, en Drupal y para nuestro ejemplo en particular, el controlador nos servirá para crear una página y posteriormente poder acceder a ella desde una url. 

Para añadir un Controlador o Controller, se debe respetar una estructura específica de archivos y del código a implementar, así que, vamos allá:

Paso 1:

Abre la carpeta de tu módulo personalizado que haz creado previamente siguiendo el anterior artículo y a continuación crearás una carpeta llamada src y dentro de ella otra carpeta a la que llamarás Controller.

Fíjate bien, en que la primera carpeta tiene el nombre en minúsculas y la segunda, que es dónde estará nuestra clase Controlador o Controller, deberá iniciar por mayúscula.

Paso 2:

Dentro de la carpeta Controller, ahora vas a añadir un archivo php, que será nuestra clase Controlador a la que llamaremos MyModuloController.php

Custom Module Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

Paso 3:

Dentro del archivo MyModuloController.php, asegúrate de que tengas la etiqueta de apertura de <?php para que funcione, no nos hará falta cerrar la etiqueta en el caso de crear esta clase de archivos para Drupal.

Paso 4:

Añade el siguiente código a tu controlador y guarda el archivo. (Trata de escribirlo y no copiarlo para que se te grave en al memoria más fácilmente)

Ahora te explico qué es lo que tenemos aquí dentro paso a paso para que puedas aprenderlo:

En la primera parte, tenemos los comentarios, que en php se escriben entre /*** COMENTARIO AQUI ***/, y que para seguir una cierta estructura en el desarrollo, se emplea tal y como lo vez.

El @file le permite a Drupal identificar que se trata de un archivo, es recomendable añadirlo siempre en tus desarrollos para módulos personalizados.

Y a continuación, lo que estamos diciendo es que dentro de este archivo, se implementará la clase Controller de Drupal.

/**
 * @file
 * Implement MyModuleController
 */

Las versiones más recientes de php utilizan lo que se conoce como namespace con lo que se evita conflictos por el uso de clases duplicadas y la ubicación específica para la clase que deseamos utilizar en nuestros desarrollos.

namespace Drupal\mymodule\Controller;

Con esta línea en particular, estamos diciéndole a Drupal, dónde podrá encontrar nuestra clase Controller, indicándole que la busque dentro de nuestro módulo y a continuación, dentro de la carpeta llamada Controller.

La siguiente línea, es para indicar que vamos a utilizar una de las clases incluidas en la instalación de Drupal, que el algunos casos, también podría ser de Symfony, ya que Drupal 8 y 9 están basado en este Framework.

Cada vez que tengamos que utilizar una clase, primero necesitamos indicar que la utilizaremos escriendo una línea como la que hemos puesto nosotros en este caso.

use Drupal\Core\Controller\ControllerBase;

La clase ControllerBase nos servirá para emplear sus métodos y otras características definidas en ella, mediante la herencia de objetos en php para que el proceso se ejecute, añadiremos a la declaración de nuestra clase MyModuleController, la palabra  extends y así es como el código que escribamos en el Controller funcionará según lo esperado.


class MyModuleController extends ControllerBase {

 

}

Ahora que ya hemos llegado hasta aquí, sólo nos queda incluir el código restante dentro de nuestra clase, que lo único que hará es devolvernos un texto estático, al escribir en el navegador la url que le asignaremos con otro archivo, que aún no hemos creado y que se llamará mi_modulo.routing.yml

public function mypage(){
  return array(
    '#type' => 'markup',
    '#markup' => t('Este es el contenido de la página de MyModule'),
  );
}

Paso 5:

Para que podamos acceder a nuestra nueva página (mypage), tendremos que crear, al mismo nivel que el archivo "mi_modulo.info.yml", otro archivo al que llamaremos mi_modulo.routing.yml y dentro escribiermos la siguientes líneas, debes vigilar que se mantengan los espacios, no uses la teclas TAB, usa la barra espaciadora y controla siempre la estructura de dos en dos en cada zona indicada o tu código no funcionará:

mymodule.mypage:
  path: '/mypage'
  defaults:
    _title: 'Tïtulo de mi página para el módulo'
    _controller: '\Drupal\mymodule\Controller\MyModuleController::mypage'
  requirements:
    _permission: 'access content'

Vamos a explicar lo que tenemos dentro del archivo mi_modulo.routing.yml:

En la primera línea, y sin ningún espacio, hemos escrito el nombre del módulo, se recomienda para evitar conflictos con otros módulos que se llamen igual, luego hemos puesto un punto y a continuación el nombre que identifica nuestra ruta. 

mymodule.mypage:

En la segunda línea, con hemos dado dos veces a la barra espaciadora y luego hemos escrito lo que será la url para acceder a nuestra página.

  path: '/mypage'

En las siguientes líneas, primero estamos definiendo el título que aparecerá en la parte superior de la página y al que Drupal le asigna por defecto la etiqueta html <h1></h1>, y luego estamos indicando la ruta dónde Drupal deberá buscar el contenido de nuestra página, para ello, hemos definido entre comillas, la ruta completa comenzando con la barra inclinada seguida de Drupal hasta llegar al nombre de nuestra clase y finalmente, como nuestra página es un método, para que funcione hemos puesto los cuatro puntos.

defaults:
  _title: 'Tïtulo de mi página para el módulo'
  _controller: '\Drupal\mymodule\Controller\MyModuleController::mypage'

     Y ya hemos llegado al final del archivo, donde hemos definido que todo el que tenga permisos para ver el contenido publicado en nuestra web, también podrá acceder para ver esta página si pone la url en el navegador.

requirements:
  _permission: 'access content'

     ¡Ya está!, ahora que ya has realizado todos los cambios, creado los archivos y has seguido el consejo de no copiar y pegar, sino escribir todo el código, porque quieres llegar a entender y programar con responsabilidad, lo siguiente que tienes que hacer es, una vez hayas guardado los cambios, borrar las cachés y en el navegador escribir la url que hemos definido previamente, en la parte donde dice "path:",  es decir, escibe en el navegador  http://drupal9composer.localhost/mypage

Custom Module Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

Si al Vaciar cachés y escribir la url en el navegador ves esta página, ¡Felicidades!, porque ya has aprendido a crear una página utilizando la clase Controller en un módulo personalizado.

El archivo para definir las rutas y ubicación del controlador del módulo personalizado, tendrá la extensión: .routing.yml

Módulo personalizado en Drupal 9 (Parte 1)

Video de Youtube
URL de Video remoto
Texto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

Cómo crear un módulo en Drupal 9 (1era Parte)

Drupal es un potente CMS o gestor de contenidos, que entre otras características, nos permite escalar cualquier proyecto para llegar a cumplir con innumerables requerimientos de nuestros clientes.

Para mantener un control durante la aplicación de cualquier mejora y a su vez facilitar la implementación de nuevas funcionalidades y del mantenimiento en cualquier proyecto; es recomendable encapsular dichas funcionalidades dentro de módulos, también conocidos como plugins, cuya activación y testeo nos dará la oportunidad de identificar más fácilmente las posibles causas en caso de ocurrir algún error en nuestra web.

Por eso a continuación te voy a guiar paso a paso en la construcción de un módulo, con el cual podrás modificar el formulario de comentarios que viene por defecto en cualquier instalación de Drupal 8 o 9 para que te sirva como referencia y puedas partir de esta base en el desarrollo de todos los módulos que hagan falta en tu proyecto.

Requisitos y recomendaciones

Es recomendable usar Composer para que puedas instalar todos los módulos con sus respectivas dependencias.(Ver video)

Deberás descargar y activar el módulo Devel para que puedas imprimir variables y otras opciones muy útiles

Te recomiendo descargar activar el módulo Admin Toolbar para facilitarte la navegación en Drupal

Te recomiendo descargar drush para que puedas ejecutar comandos directamente en consola que te ayudarán a ir más rápido en muchas de las operaciones que realizarás durante tu desarrollo. Para descargar drush, colócate en la carpeta raíz de tu drupal 9 y si ya has instalado composer ejecuta el siguiente comando: "C:\xampp\htdocs\midrupal9>composer require drush/drush", una vez descargado drush sólo tendrás que ejecutar "C:\xampp\htdocs\midrupal9>vendor/bin/drush COMANDO"

Si ya tenemos todo, comencemos a crear nuestro módulo:

Paso 1:

Crea una carpeta con el nombre de tu módulo en la siguiente ruta: '/sites/modules/custom/mi_modulo".

Es recomendable que todos los módulos que desarrolles estén dentro de la carpeta CUSTOM para que tu código esté más organizado. Al utilizar composer cada vez que instales un nuevo módulo de Drupal, Composer colocará estos módulos dentro de una carpeta llamada contrib, por eso, los que desarrolles tú deberían estar dentro de la carpeta "custom"

Paso 2:

Dentro de la carpeta de tu módulo, deberán estar al menos dos archivos para que funcione correctamente "mi_modulo.info.yml" y "mi_modulo.module", así que ahora vas a crear primero el archivo "mi_modulo.info.yml" y dentro vas a colocar los siguientes datos. Es importante que respetes los espacios en cada línea o no funcionará.

name: Mi modulo
description: 'Modifica el botón en el formulario de contacto de los comentarios'
package: mismodulos

type: module
core_version_requirement: ^8 || ^9

Paso 3:

Dentro de la carpeta de tu módulo, crea el archivo "mi_modulo.info.yml" y no hace falta que pongas nada más por ahora, sólo guárdalo.

¡FELICIDADES!, ya has creado tu primer módulo, ahora sólo tienes que activarlo para comprobar que no hay ningún error antes de continuar.

Para activar tu módulo podrás hacerlo usando drush "vendor/bin/drush en mi_modulo -y" o desde la interfaz llendo a "http://drupal9composer.localhost/admin/modules"

Custom Module Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

Paso 4:

Ahora nos toca trabajar con el archivo "mi_modulo.module", así que ábrelo y vamos a añadir la primera parte del código; antes de empezar recuerda que debes tener activado el módulo Devel para que funcione lo que estamos buscando, necesitamos imprimir el nombre del formulario que vamos a modificar, para ello, después de activar el módulo Devel, podemos escribir el siguiente código dentro del "mi_modulo.module":

<?php

/**
 * @file
 * Implement hook_form_alter().
 */

function mymodule_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id){
  ksm($form_id);

}

A continuación guarda los cambios y borra el caché de drupal. 

Para borrar el caché de Drupal tienes dos opciones:

     Opción 1:
     
Llendo a "http://drupal9composer.localhost/admin/config", luego seleccionar "Rendimiento", a continuación hacer clic en el botón "Vaciar todas las cachés"

Custom Module Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Opción 2:
     Si haz activado el módulo Admin Toolbar, verás el logo de Drupal en la parte superior izquierda; haciendo clic sobre el logo, verás el desplegable que te permitirá seleccionar Vaciar todas las cachés

Custom Module Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

Paso 5:
Para comprobar el cambio que acabamos de realizar, tendrás que crear un artículo de prueba, no importa el contenido y guardarlo. Y entonces podrás ver el (ID) o idenfificador de los formularios, esto te permitirá afectar sólo al formulario que tenga el identificador que quieras modificar.

Custom Module Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

Paso 6:

Ya que sabemos el ID o identificador del formulario, abriremos nuevamente el  "mi_modulo.module" y añadiremos el resto del código, guardamos y comprobamos el cambio en el formulario de los comentarios, Ahora el botón habrá cambiado por el texto que hemos puesto t('Comentar'), la "t" es para que sea un texto que podamos traducir (Recuerda Vaciar los cachés):
 

<?php

/**
 * @file
 * Implement hook_form_alter().
 */

function mymodule_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id){
  //ksm($form_id);
  if($form_id == 'comment_comment_form'){
    $form['actions']['submit']['#value'] = t('Comentar');
  }
}

Si vuelves a ver el artículo que habías creado, podrás comprobar que todo funciona correctamente.

Custom Module Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

A partir de Drupal 8, los módulos personalizados deberán colocarse en la ubicación: "/sites/modules/custom/mi_modulo"

Symfony 5 | Trabajando con Plantillas Twig

Video de Youtube
URL de Video remoto
Texto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

       En el anterior capítulo, aprendimos a generar un controlador con su respectiva página, utilizando el Bundle Make, que nos generó una serie de archivos conectados, gracias a los cuales, pudimos acceder a nuestra primera página personalizada, llamada /main, al escribir dicha url en nuestro navegador.

Curso Symfony 5 | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Si nos fijamos un poco más en detalle, podremos apreciar que esta página, nos muestra la ubicación de los dos archivos necesarios para generarla, estos son el controlador MainController.php y la plantilla Twig, llamada index.html.twig. Así que en esta ocasión vamos a conocer un poco más sobre cómo trabajar con las plantillas para mostar nuestros contenidos en Symfony.

   Documentación oficial de Twig

     Para conocer mejor el funcionamiento de las plantillas en Symfony, deberíamos visitar la documentación oficial, donde encontraremos toda clase de información relacionada, con las diferentes funcionalidades, estructuras, filtros y opciones, disponibles para nosotros, al trabajar con plantillas Twig. Te recomiendo visitarla en este enlace: 

https://twig.symfony.com/doc/3.x/

     Twig es el resultado de una evolución en la programación, basada en PHP, que te permitirá trabajar de manera más amigable, flexible y rápida, al momento de ejecutar todo tipo de operaciones o cambios en tus plantillas. 

     Con un mínimo de esfuerzo, podrás realizar todo tipo de operaciones como declaraciones de variables, arrays, loops, ordenación de elementos, entre otras.

Curso Symfony 5 | www.drupaladicto.com - Consultor especializado en drupal y symfony

   Cómo trabajar con Twig dentro de Symfony 5

     Si abrimos el archivo llamado index.html.twig, que nos aparece en nuestra página /main, veremos la siguiente estructura:

Curso Symfony 5 | www.drupaladicto.com - Consultor especializado en drupal y symfony

     En la primera línea, tenemos la declaración de una herencia, esto quiere decir, que nuestra plantilla está heredando desde la plantilla llamada base, las principales características, que son las que permitirán utilizar, por ejemplo, las etiquetas html, los css o javascript:

{% extends 'base.html.twig' %}

     Encontraremos esta plantilla base, si buscamos dentro de la carpeta llamada templates, que es justo donde se guardan por defecto, todas las plantillas generadas automáticamente.

Curso Symfony 5 | www.drupaladicto.com - Consultor especializado en drupal y symfony

   Cómo trabajar con la plantilla base.hmtl.twig

      Cuando exploramos un poco más a fondo, la estructura dentro de la plantilla base.html.twig, nos daremos cuenta de en varias partes de ella, encontraremos combinaciones de etiquetas html, con otras en un formato menos conocido:

<body>
    {% block body %}{% endblock %}
</body>

     En Twig, cuando vemos dos llaves, acompañadas de signos de porcentaje, significará que dentro se ejecuta algun proceso. En este caso, se están declarando bloques de contenido, específcamente, el bloque llamado body, correspondiente al cuerpo o parte principal de la página.

     Al igual que en otros lenguajes de programación, cuando declaramos un bloque, tendremos una "Etiqueta" de apertura y otra de cierre, es por esta razón, que vemos {% endblock %}, como parte de la estructura.

     Si abrimos nuestra plantilla generada automáticamente, entenderemos mejor, porqué parte de sus código está entre estas dos etiquetas:

{% block body %}
<style>
    .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
    .example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>

<div class="example-wrapper">
    <h1>Hello {{ controller_name }}! ✅</h1>

    This friendly message is coming from:
    <ul>
        <li>Your controller at <code><a href="{{ '/app/src/Controller/MainController.php'|file_link(0) }}">src/Controller/MainController.php</a></code></li>
        <li>Your template at <code><a href="{{ '/app/templates/main/index.html.twig'|file_link(0) }}">templates/main/index.html.twig</a></code></li>
    </ul>
</div>
{% endblock %}

   Ejemplo práctico

     Primero, analicemos la estructura que utilliza Symfony, para pasarle datos desde el controlador a la plantilla:

public function index(): Response
{
    return $this->render('main/index.html.twig', [
        'controller_name' => 'MainController',
    ]);
}

     En la primera parte de la declaración, vemos que se devuelve un objeto del tipo Response utilizando el método render, donde pasamos, como primer parámetro la ubicación de la plantilla, o sea, main/index.html.twig y a continuación, un array, con los valores que se le pasarán a dicha plantilla, en este caso, el array de datos, tiene una clave llamada controller_name y un valor asignado, que es MainController.

     Para pasar el valor y poder imprimirlo dentor de la plantilla, Symfony utiliza dobles llaves, por eso, si abrimos la plantilla, podremos ver la línea donde imprime en pantalla el valor de esta variable, utilizando la siguiente estructura:

<h1>Hello {{ controller_name }}! ✅</h1>

     Hagamos entonces la siguiente comprobación, vamos a reescribir nuestra página, para ello, primero añadiremos un nuevo array, que pasaremos como parámetro desde el controlador y a continuación, utilizaremos un bucle for, para recorrerlo e imprimir todos sus valores dentro de una lista, en la plantilla. El siguiente será el aspecto del controlador con los nuevos cambios.

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class MainController extends AbstractController
{
    /**
     * @Route("/main", name="app_main")
     */
    public function index(): Response
    {
        $recommendations = [
            'one' =>  'Poner atención en los detalles',
            'two' =>  'Nunca darte por vecido',
            'tree' => 'Siempre marcarte nuevos objetivos'
        ];
        return $this->render('main/index.html.twig', [
            'recommendations' => $recommendations,
        ]);
    }
}

 

Curso Symfony 5 | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Y a continuación, tendremos la nueva estructura dentro de nuestra plantilla, en la cual hemos removido casi todo lo generado automáticamente, para dejar solamente, la declaración de herencia {% extends 'base' %} y luego los bloques title y body:

{% extends 'base.html.twig' %}

{% block title %}Nuevo controlador {% endblock %}

{% block body %}
    <ul>
        <h2>Nuestra recomendaciones</h2>

        {# Estos son los comentarios #}
        {% for recommendation in recommendations %}
        <li>{{ recommendation }}</li>
        {% endfor %}

    </ul>
{% endblock %}

     Si guardamos los cambios y volvemos a nuestro navegador y refrescamos, el aspecto de la página /main, debería ser el siguiente:

Curso Symfony 5 | www.drupaladicto.com - Consultor especializado en drupal y symfony

    Ahora que ya sabemos, que para utilizar elementos de la plantilla base.twig.html, dentro de nuestras plantillas personalizadas, lo primero es declarar la herencia, con la sentencia {% extends 'base.html.twig' %}, y a continaución podremos definir uno o varios bloques y llamarlos desde nuestra plantilla.

Symfony 5 | Instalación con Lando en WSL2 y Windows 11

Video de Youtube
URL de Video remoto
Texto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

     Aprovechando que poco a poco, nos estamos acostumbrando a trabajar en proyectos locales de Drupal, ejecutando Lando para nuestros servidores, por ser la forma más sencilla y rápida de comenzar a desarrollar, utilizando los contenedores de Docker sin tener que complicarnos la vida; en esta ocasión, te quiero mostrar la manera de comenzar con un proyecto de Symfony 5, en un entono Linux, con WSL2 y Windows 11, y así podrás comenzar a explorar otras alternativas para tus proyectos, además de conocer la estructura en la que está basado Drupal, a partir de la versión 8.

Prerrequisitos:

- Tener instalado en tu servidor local Lando. Si todavía no lo haz hecho y quieres aprender cómo hacerlo, Haz clic aquí

 

NOTA: Puedes acceder al repositorio listo para utlizar en este enlace  https://github.com/drupaladicto/symfony5-lando

 

Cómo instalar y comenzar un proyecto con Symfony usando Lando

     En realidad es mucho más sencillo de lo que pudieras imaginar, al igual que explicamos en el capítulo para instalar Drupal 10, solo necesitaremos colocarnos en la ubicación deseada para nuestro proyecto y una vez alli, creaemos el archivo al que llamaré configurador.sh, donde lo más importante es la extensión .sh, para que nos permita ejecutarlo dentro de nuestro servidor linux.

     A continaución, copiaremos el siguiente código, le daremos permisos totales, para evitar fallos durante el proceso de descarga e instalación y ya podremos comenzar a desarrollar casi de inmediato.

# Initialize a symfony recipe
mkdir symfony5-app \
  && cd symfony5-app \
  && lando init \
    --source cwd \
    --recipe symfony \
    --webroot public \
    --name symfony5-app

# Install symfony
lando composer create-project symfony/skeleton:"^5.4" tmp && cp -r tmp/. . && rm -rf tmp

# Install other Symfony dependencies you may like
lando composer require annotations asset doctrine encore form logger profiler security security-guard stof/doctrine-extensions-bundle twig validator var-dumper

# Start it up
lando start

# List information about this app.
lando info

# Run bin/console commands with: lando console
# Here is how to clear cache; 
lando console cache:clear

 

     Aclaración 24 de abril 2022: Poco después de haber subido el video y publicado la documentación, pude comprobar que el bundle Make, de Symfony se había actualizado para la versión 5 y daba fallos con la versión 5.4.6, por lo que decidí removerlo del archivo de instalación configurador.sh.

     No obstante, una vez terminada la instalación, podrás descargar la versión estable del bundle Make, ejecutando en tu consola el siguiente comando:

lando composer make

Explicación:

     En las primeras líneas, se creará la carpeta para nuestro proyecto y, a continuación, se moverá para añadir el arhivo de configuración de Lando, e iniciará el proceso de la descarga desde el repositorio oficial de Drupal. 

     Deberías sustituir, si lo prefieres, todas las líneas donde ves symfony5-app, que en este caso se refiere tanto al nombre de la carpeta donde estará alojado el proyecto de Symfony, como al nombre que dará Lando una vez instalado y que podrás comprobar si abres el archivo de cofiguración .lando.yml.

  # Initialize a symfony recipe
mkdir symfony5-app \
  && cd drupal10-app \
  && lando init \
    --source cwd \
    --recipe symfony \
    --webroot public \
    --name symfony5-app

     Las siguientes líneas son las encargadas de descargar el esqueleto para un proyecto Symfony, utilizando el comando de Lando Composer.

# Install symfony
lando composer create-project symfony/website-skeleton tmp && cp -r tmp/. . && rm -rf tmp

     En la siguiente línea, se descargarán las dependencias o paquetes, más comunes para comenzar a desarrollar nuestros proyectos, dentro de los que se incluyen doctrine, twig, entre otros, ahorrándonos tiempo considerablemente. El resto de paquetes podrás consultarlos y descargarlos desde la web: flex.symfony.com 

 # Install other Symfony dependencies you may like
lando composer require annotations asset doctrine encore form logger maker profiler security security-guard stof/doctrine-extensions-bundle twig validator var-dumper

     A continuación, se levantan nuevamente los servicios de Lando, para poner en funcionamiento la aplicación.

# Start it up
lando start

     Por último, se muestra la información del proyecto, gracias al comando Lando info y se limpia la consola, para que podamos acceder a nuestro proyecto y comenzar a trabajar en él.

# List information about this app.
lando info

# Run bin/console commands with: lando console
# Here is how to clear cache; 
lando console cache:clear

 

Curso Symfony 5 | www.drupaladicto.com - Consultor especializado en drupal y symfony

Curso Symfony 5 | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Si quieres explorar algo más de información antes del próximo artículo, puedes visitar la documentación oficial de Lando para Symfony