campos
Gutenberg | Módulo Drupal
Aunque en mi opinión, una de las cosas que me enamoró de Drupal en cuanto lo conocí, es la posibilidad de manipular, personalizar y saber encontrar, prácticamente dónde y cuando ocurren la mayoría de sus funcionalidades, entiendo que el objetivo principal de cualquier herramienta de desarrollo, debería ser facilitarnos la vida, además de ofrecernos grandes posibilidades a nuestro alcance.
Como cada proyecto requiere de diferentes requisitos para llevarse a cabo, y por lo general, uno de los más importantes, es el tiempo que tendremos que invertir hasta su puesta en producción, muchos desarrolladores web prefieren apostar por otros CMS o construir desde cero proyectos enteros, para sentir que tienen mayor control sobre sus creaciones.
No obstante, creo que con un pequeño conocimiento sobre cómo instalar Drupal 9 usando Composer y un breve vistazo a cómo gestionar usuarios y permisos, complementado con la ayuda del Módulo Gutenberg, conocido mayormente por usuarios de Wordpress, podrías llegar a tener lo que haz estado buscando hace tiempo, una plataforma simple de manipular, pero potente, con posibilidad de adaptación a la mayoría de webs sencillas.
Es por esta razón que a continuación, te voy a mostrar cómo puedes utilizar las opciones que integra este módulo a la interfaz de usuario, facilitándote de forma notable, la creación de nuevos contenidos en Drupal 9.
Descarga y Activación:
Para descargar y activar cualquier módulo de Drupal tienes varias opciones:
Descarga:
1.- La forma recomendada a partir de Drupal 8, es utilizando el gestor de paquetes Composer, ejecutando en tu consola el comando:
composer require drupal/gutenberg
2.- Descargándolo manualmente el módulo desde la página oficial del Módulo Gutenberg y una vez descargado y colocado en carpeta "modules/contrib", si haz descargado todos tus módulos manualmente, deberías crear la carpeta "contrib", para que puedas diferenciar entre tus módulos personalizados y los que están disponibles directamente en la Página oficial de Drupal.
Activación:
1.- Utilizando la herramienta de consola Drush, la opción "-y" activará todos los sub-modulos automáticamente
drush en gutenberg -y
2.- Desde la interfaz de usuario de Drupal, en la url "/admin/modules", y luego marcando el check junto al nombre de tu módulo y haciendo clic en el botón guardar que aparecer al final de la página.
Cómo utilizar Gutenberg
Una vez activado el Módulo Gutenberg, veremos que se ha añadido una nueva opción, en la parte inferior izquierda de todos los contenidos, llamada Gutenberg Experience y que al activarla podremos ver dos listados con todos los nuevos bloques, tanto del propio módulo como de el núcleo de Drupal, que podremos activar o no, para que estén disponibles como parte de las opciones del tipo de contenido en que se han activado, modificando inmediatamente la interfaz de creación de dicho contenido.
La idea principal de Gutenberg, es que convierte todos los elementos que podamos añadir, en bloques individuales, con sus propias opciones, disponibles en el momento en que seleccionamos dicho bloque o elemento, haciéndolo mucho más gráfico el método para añadir, modificar o reutilizar dicho elemento.
Para comenzar a añadir contenidos o "Bloques" en nuestro tipo de contenido, veremos un símbolo de más dentro de un círculo y al hacer clic sobre éste, se desplegarán las diferentes opciones disponibles para agregar y una vez seleccionado el elemento que deseamos añadir y se añade, inmediatamente cambiará el panel de la derecha de la pantalla, adaptándose a las opciones disponibles para él.
De entre sus opciones más llamativas, está la posibilidad de arrastrar directamente los elementos hasta la posición deseada desde el escritorio de tu ordenador, la integración con módulos como Media o Imagen, insertar directamente elementos embebidos como vídeos, sonidos, etc, o la posibilidad de crear "Bloques" de contenido reutilizables en cualquier otro lugar de la web.
El objetivo de utilizar Gutenberg, es que todos tus tipos de contenido, sólo tengan el campo "Body" y dentro de este campo se podrán añadir, editar o eliminar el resto de elementos que se mostrará en tus páginas, incluyendo imágenes o incluso bloques del núcleo de Drupal.
Gutenberg Cloud
Una de las opciones más novedosas de este módulo, es la posibilidad de añadir "bloques" de contenido, directamente desde su repositorio en la web Gutenbergcloud.org, mediante el sistema de CDN, por lo que dichos bloques, con características, estilos y funcionalidades prediseñados, no se guardan como el resto de contenidos en la base de datos de Drupal. Por el contrario, se añaden como etiquetas dentro del campo "BODY", que añade Drupal por defecto cada vez que creamos un nuevo tipo de contenido.
Para añadir esta funcionalidad, sólo habría que activarla como cualquier otro módulo y una vez hecho esto, se añadirá como una de las opciones disponibles para agregar en el listado de bloques cuando hagamos clic en el selector.
Por desgracia, esta funcionalidad no es compatible para todas las versiones de Drupal 9, por lo menos al momento de escribir este artículo. Pero sí podrás utilizarla en cualquier instalación de Drupal 8 o menor que la 9.1.
Landing Page Drupal | Plantillas Twig (Parte 2) - Bootstrap y Flexbox
Debido a que estamos trabajando con Bootstrap 5, para la creación de nuestra Landing Page personalizable en Drupal 8/9/10, hoy utilizaremos las clases de Bootstrap 5 compatibles con Flexbox; de esta manera, nuestro diseño quedará adaptado a múltiples dispositivos (Responsive), sin la necesidad de manipular nuestra hoja de estilos.
Si analizamos el comportamiento que esperamos obtener para la visualización de nuestra Landing Page, al acceder desde un ordenador, veremos que en la parte central, los elementos deberían presentarse dentro de tres columnas, las dos primeras para la imagen e información del producto, y la última, a todo el ancho del contenido, donde se muestra el formulario para la realización de los pedidos.
Al acceder a la Página Oficial de Bootstrap, en el apartado de Utilidades, dedicado a FLEX HAZ CLIC AQUI, podremos explorar el listado de clases y sus comportamientos, para facilitarnos la aplicación de casi todas las opciones necesarias en nuestros diseños resposivos, sin demasiados cambios en las hojas de estilos css.
Si ya conocías Bootstrap, sabrás que, añadiendo una o varias clases dentro de cualquier contenedor o etiqueta html, obtendrás el mismo resultado que si aplicaras varias líneas de código css; esto implica un ahorro considerable dentro de las tareas de diseño, además de ofrecer una amplia documentación y varios ejemplos, que podrás encontrar, tanto dentro de la página oficial, como el muchas otras disponibles en internet.
Ahora que ya sabemos cómo documentarnos, sobre el uso de las clases de Bootstrap y Flexbox, volvamos a explorar el archivo node--landingpage--full.html.twig, responsable de mostrar nuestra plantilla.
Recuerda, que hemos creado esta plantilla, gracias a que activamos el modo Debug o Depurador de Drupal, explicado en capítulos anteriores del curso.
Si prestamos atención en el código que forma, la parte superior de la plantilla, donde hemos añadido ya la imagen de cabera y el texto que aparece justo debajo de ella, encontraremos algunas de las clases de Bootstrap y Flexbox que acabamos de comentar.
{% if content.field_cabecera_landing|render is not empty %} <div class="d-flex container-fluid" lc-helper="background" style="height:50vh;background:url({{ file_url(content.field_cabecera_landing[0]['#media'].field_media_image.entity.uri.value) }}) center / cover no-repeat;"> {% endif %} </div> <div class="container p-5 bg-light" style="margin-top:-100px"> <div class="row"> <div class="col-md-4 text-center align-self-center"> <div class="lc-block border-end border-2 "> <div editable="rich"> <p class="display-4 text-secondary">WHY?</p> </div> </div><!-- /lc-block --> </div><!-- /col --> <div class="col-md-8"> <div class="lc-block "> <div editable="rich"> <p class="display-4">{{ label.0 }}</p> </div> </div><!-- /lc-block --> </div><!-- /col --> </div>
Explicación
d-flex: Es la primera de las clases que deberíamos añadir en nuestra etiqueta HTML, para poder emplear la combinación de Flex y Boostrap; añadirla es el equivalente a escribir la propiedad display: flex, dentro de nuestra hoja de estilos.
container / container-fluid: tiene la misma funcionalidad que ya conoces de Boostrap, y que en este caso, añadirá la propiedad padding, configurada por defecto para Drupal, cuando utilizamos el tema basado en Boostrap.
p-5: Esta clase es la encargada de modificar la propiedad padding, tienes varios valores disponibles, además de la opción de utilizarla, especificando si quieres aplicar un padding-top pt-5, o padding buttom pb-5, por ejemplo.
align-self-center: esta clase, como su nombre lo indica, se encargará de centrar los elementos, dentro del contenedor.
col-md-4: esta es una de las clases que ya deberías conocer, por versiones anteriores de bootstrap, encargada de adaptar el tamaño de la columna, en los dispositivos de tamaño medio (Tablets, Ipads, etc.)
Si quieres profundizar más sobre las clases disponibles y su implementación, te recomiendo visitar la página oficial de Boostrap. HAZ CLIC AQUI.
Añadiendo cambios en la plantilla
Es el momento de continuar con el resto de cambios necesarios, para seguir ajustando nuestra Landing Page, hasta conseguir que se parezca a nuestra propuesta de diseño.
En esta ocasión, vamos a sustituir en nuestra plantilla, todo el espacio que ocupa el texto central, para dejarle paso, a dos nuevas filas, donde añadiremos los campos correspondientes, encargados de mostrar las imágenes e información de los productos, además del formulario para los peidos.
He añadido un para de clases adicionales, sólo para que sea más fácil de entender, donde colocaremos cada uno de los elementos.
El resultado final, con el nuevo cambio, debería ser parecido al siguiente código:
<div class="row contenido-central"> <div class="col-md-12"> <div class="row info-productos"> LOS PRODUCTOS AQUI </div> <div class="row formulario-pedidos"> EL FORMULARIO AQUI </div> </div> </div> </div>
Ahora ya tenemos claro, cuál debería ser la estructrura para conseguir el resultado esperado en mi Landing Page, el problema con el que nos encontramos, es que nuestra plantilla sólo tienes dos campos, con los que podamos jugar, field_cabecera_landing y field_contenidos_landing, ya que hemos optado, por el uso de paragraphs, para facilitar la personalización de sus contenidos.
Si volvemos a la parte del código donde imprimimos nuestra imagen, podremos concluir, que lo que necesitamos para obtener el resto de valores de nuestra página, es añadir la variable que imprime el campo global de los paragraphs y a continuación, añadir las plantillas correspondientes, para cada uno de los elementos contenidos dentro de éste.
Lo primero que deberíamos hacer será remover la parte del código donde estarán las imágenes, información y el formulario, para añadir dentro sólo el campo global de los paragraphs.
Por ahora, nuestra plantilla principal, node--landingpage--full.html.twig, debería quedar con el suguiente resultado:
<div class="row contenido-central"> <div class="col-md-12 p-5"> {{ content.field_contenidos_landing }} </div> </div> </div>
Una vez añadido el código anterior, si visitamos nuestra Landing Page, deberíamos ver en pantalla, algo parecido a la siguiente imagen:
Si todo ha ido correctamente, y ves en pantalla un resultado parecido al anterior, es el momento de inspeccionar los elementos y crear las plantillas correspondientes a cada paragraphs, para cotinuar con el resto de modificaciones.
Plantilla principal para la landing page
El código final de la plantilla general para la landing (node--landingpage--full.html.twig), que incluye además, el campo de selección para el color, gracias al módulo Color Field, será :
{{ attach_library('bootstrap_barrio/node') }} {% set classes = [ 'node', 'node--type-' ~ node.bundle|clean_class, node.isPromoted() ? 'node--promoted', node.isSticky() ? 'node--sticky', not node.isPublished() ? 'node--unpublished', view_mode ? 'node--view-mode-' ~ view_mode|clean_class, 'clearfix', ] %} <article{{ attributes.addClass(classes) }}> <header> {{ title_prefix }} {% if label and not page %} <h2{{ title_attributes.addClass('node__title') }}> <a href="{{ url }}" rel="bookmark">{{ label }}</a> </h2> {% endif %} {{ title_suffix }} {% if display_submitted %} <div class="node__meta"> {{ author_picture }} {% block submitted %} <em{{ author_attributes }}> {% trans %}Submitted by {{ author_name }} on {{ date }}{% endtrans %} </em> {% endblock %} {{ metadata }} </div> {% endif %} </header> <div{{ content_attributes.addClass('node__content', 'clearfix') }}> {% if content.field_cabecera_landing|render is not empty %} <div class="d-flex container-fluid" lc-helper="background" style="height:50vh;background:url({{ file_url(content.field_cabecera_landing[0]['#media'].field_media_image.entity.uri.value) }}) center / cover no-repeat;"> {% endif %} </div> <div class="container p-lg-5" style="margin-top:-100px; background-color: {{ content.field_color_fondo_landing.0 }}" > <div class="row"> <div class="col-md-4 text-center align-self-center"> <div class="lc-block border-end border-2 "> <div editable="rich"> <p class="display-4 text-secondary">WHY?</p> </div> </div><!-- /lc-block --> </div><!-- /col --> <div class="col-md-8"> <div class="lc-block "> <div editable="rich"> <p class="display-4">{{ label.0 }}</p> </div> </div><!-- /lc-block --> </div><!-- /col --> </div> <div class="row contenido-central"> <div class="col-md-12 p-md-5"> {{ content.field_contenidos_landing }} </div> </div> </div> </div> </article>
Plantilla para la imagen y el texto del producto
El código correspondiente a la parte superior, donde mostramos la imagen del producto, acompañada de un título y un párrafo, (paragraph--bloque-imagen-y-textos.html.twig) será:
{% set classes = [ 'paragraph', 'd-lg-flex', 'paragraph--type--' ~ paragraph.bundle|clean_class, view_mode ? 'paragraph--view-mode--' ~ view_mode|clean_class, not paragraph.isPublished() ? 'paragraph--unpublished' ] %} <style> @media (min-width: 992px) { .field--name-field-imagen-producto { width: 550px; } } </style> {% block paragraph %} <div{{ attributes.addClass(classes) }}> {% block content %} <div class="row no-gutters d-flex"> <div class="imagen-producto d-sm-column"> {{ content.field_imagen_producto }} </div> </div> <div class="row no-gutters d-flex"> <div class="texto-producto d-sm-column"> <h2>{{ content.field_texto_superior.0 }}</h2> <p>{{ content.field_textos_producto.0 }}</p> </div> </div> {% endblock %} </div> {% endblock paragraph %}
Plantilla para el Bloque formulario
Para la plantilla, encargada de modificar el aspecto gráfico correspondiente al formulario, que además incluye la etiqueta html <hr />, con algunos estilos en línea, (paragraph--bloque-formulario.html.twig), será:
{% set classes = [ 'paragraph', 'd-flex flex-column', 'paragraph--type--' ~ paragraph.bundle|clean_class, view_mode ? 'paragraph--view-mode--' ~ view_mode|clean_class, not paragraph.isPublished() ? 'paragraph--unpublished' ] %} {% block paragraph %} <div{{ attributes.addClass(classes) }}> {% block content %} <hr style="height: 5px; background-color: #333333;margin-top: 40px; margin-bottom: 40px"/> <div class="titular text-align-center flex-row"><h2>{{ content.field_titulo_formulario }}</h2></div> <div class="formulario"> {{ content.field_formulario_bloque }} </div> {% endblock %} </div> {% endblock paragraph %}
Contenidos de Prueba | Generados con el módulo Devel
Cuando estamos empezando con el desarrollo o implementación de cualquier proyecto, en la mayoría de los casos nos resultará necesario la creación de contenidos con los que podamos realizar pruebas de todo tipo.
Para realizar esta tarea, en Drupal contamos con el módulo Devel Generate, integrado dentro de las dependencias del módulo Devel. Por lo que, una vez instalado y activado en nuestro Drupal, sólo tendremos que dirigirnos a la url "/admin/config/development/generate/content", y allí veremos el listado de todos los tipos de contenidos que tengamos creados en nuestro proyecto.
CÓMO INSTALAR Y CONFIGURAR EL MÓDULO:
Paso 1 Descargar el módulo:
Lo primero que tendrás que hacer es descargarlo, para ello, a partir de Drupal 8 se recomienda que utilices el gestor de paquetes Composer, ya que te facilitará tanto la instalación como futuras actualizaciones del tus proyectos. No obstante también podrías descargarlo desde la Página oficial del módulo y una vez descargado, tendrás que colocarlo en la carpeta "modules" o "modules/contrib", dependiendo de tu instalación y asegurarte de descargar todas sus dependencias o el módulo no funcionará, esta es una de las ventajas con las que cuentas al hacer la instalación usando Composer.
Paso 2 Activación del módulo :
Para activar el módulo Devel, al igual que todos los demás módulos contribuidos de Drupal, tendrás la posibilidad de hacerlo, mediante el uso de la herramienta Drush, con el comando "drush en devel -y", que sirve para activar cualquier módulos y todas sus dependencias, o desde la interfaz de Drupal.
Además de poder generar automáticamente nuestros contenidos, podremos configurar algunas opciones adicionales como, especificar su fecha de publicación, comentarios relacionados, títulos para los contenidos con un límite de caracteres específico, el idioma o incluso los usuarios que los crearon, esta última opción nos facilitará el testeo de los permisos de usuario.
Para generar nuestro contenidos, sólo tendremos que marcar las opciones con las que deseamos trabajar, es recomendable intentarlo la primera vez como poco contenido para estar seguros de obtener lo que pensábamos o si hará falta modificar algún campo.
Si no estás conforme con el contenido generado o simplemente quieres volver a generar contenidos otra vez, puedes seleccionar la opción de eliminar todos los contenidos previamente creados antes de ejecutarlo.
Una vez que hayamos revisado todos los campos que nos interesan, haremos clic en el botón que aparece en la parte inferior de la pantalla y comenzará el proceso inmediatamente.
Cuando se haya realizado el proceso de generación de nuestros contenidos, veremos un mensaje de confirmación en la parte superior de la pantalla, con la cantidad y el tipo de contenido que decidimos utilizar.
Para comprobarlo, sólo tendremos que dirigirnos al listado de contenidos en la url "/admin/content" y veremos el listado de contenidos generados por el módulo con las configuraciones adicionales, si es que hemos seleccionado alguna.
Twig | Introducción a la programación de plantillas
Twig, Introducción
El lenguaje Twig es una evolución, adaptada a todo público, que facilita su aplicación, a pesar de que no tengas muchos conocimientos sobre programación php.
Twig es amigable tanto para el diseñador como para el desarrollador al adherirse a los principios de PHP y agregar funcionalidad útil para entornos de creación de plantillas.
Las características clave son...
Rápido: Twig compila plantillas en código PHP optimizado simple. La sobrecarga en comparación con el código PHP normal se redujo al mínimo.
Seguro: Twig tiene un modo de caja de arena para evaluar el código de plantilla que no es de confianza. Esto permite que Twig se use como lenguaje de plantilla para aplicaciones en las que los usuarios pueden modificar el diseño de la plantilla.
Flexible: Twig funciona con un lexer y un analizador flexibles. Esto permite al desarrollador definir sus propias etiquetas y filtros personalizados y crear su propio DSL.
Twig es utilizado por muchos proyectos de código abierto como Symfony, Drupal8, eZPublish, phpBB, Matomo, OroCRM; y muchos marcos lo admiten, así como Slim, Yii, Laravel y Codeigniter, solo por nombrar algunos.
Te dejo los enlaces, para que puedas comenzar a utilizar Twig, en tus plantillas de Drupal, tanto de contenidos, como de las vistas
- Plantillas Twig, Uso de Condicionales y campos
- Views Template | Personalizar vistas con plantillas Parte 1
- Views Template | Personalizar vistas con plantillas Parte 2
- Imprime imagen en una views template
- ¿Cómo imprimir el logo de drupal en una plantilla twig?
Puedes encontrará más información sobre Twig, en su Página Oficial. HAC CLIC AQUÍ
Formularios | Manipulación con Preprocess Functions
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
Aunque existe un módulo bastante completo llamado webform, Drupal ha mejorado considerablemente el Formulario de contacto que trae por defecto, ofreciendo una alternativa más fácil y práctica, si lo que necesitas es ofrecer esta posibilidad de contactar en tu sitio web.
Para hacerlo aún más funcional, podremos imprimir este formulario de contacto, dentro de varios contenidos o incluso, dentro de contenedores del tipo Paragraphs, para ello nos ayudaremos de las preprocess_functons(), con las que podremos pasar toda clase de valores, como variables y posteriormente utilizarlas donde nos hagan falta.
Cómo imprimir el formulario de contacto en un Paragraphs utilizando Preprocess Functions
Como hemos dicho al principio de este artículo, las Preprocess functions(), nos permitirán pasar como parámetros toda clase de valores, mediante el uso de variables que podremos reutilizar cuando sea requerido, en este ejemplo en particular vamos a utilizarlas para imprimir nuestro formulario de contacto dentro de un elemento Paragraphs, pero tienes otros ejemplos para emplearlas aquí: Ejemplos de uso Preprocess functions
Para que podamos imprimir el formulario de contacto, como hemos decidido crear un Subtheme, sólo tendremos que añadir el código dentro del archivo de funciones de nuestro subtheme, tal y como te muestro en la imagen siguiente:
Si quieres mostrar el formulario en un contenido normal de Drupal, tipo página por ejemplo: hook_preprocess_node()
En este ejemplo en particular, aprovechando que, dentro de un elemento Paragraphs podremos incluir cualquier tipo de campo, nodo o incluso otos Paragraphs, vamos a utilizar la Preprocess function para pasarle como parámetro en formulario a un nodo y posteriormente llamaremos a este nodo desde el Paragraphs.
Si lo que quisieras lograr es pasar directamente el formulario dentro de la plantilla del Paragraphs, también podrías lograrlo con esta otra función:
Cómo imprimir un formulario contacto dentro de un Paragraphs Drupal 9
Formularios | Configuración con base de datos en Drupal 9
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
Si estás leyendo este artículo, es porque ya has aprendido Cómo crear formularios programáticamente en Drupal 9, sino, Haz clic aquí, pero si todavía no has tenido la oportunidad de leer el artículo, además de ver el video en el que te explico cómo hacerlo, te recomiendo que dediques el tiempo que haga falta, para verlos y entenderlo, antes de continuar con el ejercicio que te voy a mostrar a continuación.
Nos enfocaremos en programar un formulario, conectado a una base de datos, que nos permita, por ejemplo, rellenar los registros de una tabla personalizada, utilizando los datos introducidos por los usuarios, al complementar la información de sus campos .
También exploraremos la creación de una plantilla o "template" personalizada para el formulario y, de esta forma, podrás modificar su aspecto, en función de los requerimientos que te hagan falta en otros proyectos similares.
Requisitos:
- Cómo crear un módulo en Drupal 9
- Cómo crear un bloque programáticamente en Drupal 9
- Cómo crear formularios programáticamente en Drupal 9
- Cómo crear módulos con su Controlador y Plantilla en Drupal 9
- Cómo crear tablas programáticamente en Drupal 9
Cómo crear un formulario conectado a una base de datos programáticamente
Partiendo de que ya tienes los conocimientos necesarios para crear un módulo personalizado y un formulario con sus respectivos campos, nos enfocaremos en continuar ampliando las funcionalidades del formulario base, creando algunos campos adicionales y explorando los atributos, que nos proporcionarán otras opciones con las que podrás ir experimentando a partir de ahora.
El formulario que vamos a crear es para la que los usuarios de nuestra web, puedan inscribirse en un curso de cocina vegetariana. La idea principal será utilizar los campos del formulario, para obtener un poco más de información, sobre los interesados en participar, antes de iniciar el curso.
Puedes aprender sobre los diferentes tipos de campos del formulario, su implementación y algunos ejemplos, visitando la Página oficial de Drupal Form Api.
Utilizaremos "taxonomías" o vocabularios, con la opción de autocompletar, para filtrar el área profesional de nuestros futuros alumnos y utilizaremos campos dependientes, para añadir preguntas adicionales, en función del campo seleccionado por el interesado, en el momento en que esté complementando el formulario.
Paso 1 Creación de un bloque usando un módulo personalizado:
Como el objetivo es crear un formulario independiente al proyecto, que podamos personalizar y reutilizar en cualquiera de nuestras webs, tendremos que crear un módulo personalizado, donde colocaremos todos los elementos relacionados con él.
Lo primero que haremos será crear un módulo personalizado, con el cual vamos a generar el bloque, donde colocaremos posteriormente nuestro formulario de inscripción, de esta forma, podremos activarlo en diferentes zonas de la web, además de restringir su acceso definiendo las páginas y usuarios desde la sección de Administración de Bloques.
Para cumplir con este primer objetivo, vamos a crear las carpetas y archivos necesarios para genera un bloque personalizado, si todavía no sabes cómo, te invito a echar un vistazo antes de continuar a este artículo Cómo crear un bloque programáticamente en Drupal 9, Haz clic aquí
Una vez hayas terminado, con la creación de todos las carpetas y archivos, necesarios para generar un bloque personalizado, deberías tener una estructura parecida a la de la siguiente imagen.
Y dentro de la clase con la que vamos a generar nuestro módulo, copiarás y pegarás el siguiente código para comenzar con las pruebas de desarrollo.
<?php namespace Drupal\vegetarian_food_course\Plugin\Block; use Drupal\Core\Block\BlockBase; /** * @Block( * id = "Vegetarian Food Course Form", * admin_label = @translation("Vegetarian Food Course Form"), * category = @translation("Vegetarian Food Course Form") * ) */ class VegetarianFoodCourseBlock extends BlockBase { /** * {@inheritdoc } */ public function build(){ return [ '#markup' => '<h1>Formulario de inscripción</h1>', '#cache' => [ 'max-age' => 0, ], ]; } }
Si haz puesto suficiente atención en el proceso, deberías poder activar tu módulo personalizado desde la url "/admin/modules" y a continuación, podrás dirigirte a la pantalla de activación de los bloques, en la url "/admin/structure/block", donde seleccionarás la zona o área Sidebar first, para activar tu módulo y puedas comprobar que se muestra en tu página principal tal y cómo se ve en las siguientes imágenes:
Paso 2 Creación del formulario de inscripción:
Ahora que ya hemos comprobado que todo funciona de acuerdo con nuestros planes, pasemos a la siguiente etapa, que consiste en la creación de nuestro formulario de inscripción con todos los campos.
Para ellos, tendremos que crear todas las carpetas y archivos necesarios, si todavía no sabes cómo, te recomiendo que eches un vistazo antes de continuar a este artículo Cómo crear formularios programáticamente en Drupal 9, Haz clic aquí.
Una vez tengas listos todas las carpetas y archivos necesarios para crear el formulario de inscripción, podrás copiar y pegar en tu clase el código que te muestro a continuación, dentro de la clase de tu formulario:
<?php namespace Drupal\vegetarian_food_course\Form; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; /** * @file * Implement Form API */ class VegetarianFoodForm extends FormBase { /** * {@inheritdoc } */ public function getFormId() { return 'vegetarian_food_course_form'; } /** * {@inheritdoc } */ public function buildForm(array $form, FormStateInterface $form_state) { $form['name'] = [ '#type' => 'textfield', '#title' => $this->t('Name'), '#description' => $this->t('Name of participant'), '#attributes' => [ 'placeholder' => $this->t('Your Name'), ], '#required' => TRUE, ]; $form['email'] = [ '#type' => 'email', '#title' => $this->t('Email'), '#attributes' => [ 'placeholder' => $this->t('Your Email') ], '#required' => TRUE, ]; $form['vegetarian_question']['active'] = array( '#type' => 'radios', '#title' => $this ->t('Are you Vegetarian?'), '#default_value' => 1, '#options' => array( 0 => $this ->t('No'), 1 => $this ->t('Yes'), ), ); // $form['occupation'] = [ // '#type' => 'entity_autocomplete', // '#target_type' => 'taxonomy_term', // '#title' => 'Occupation', // '#selection_settings' => [ // 'target_bundles' => ['tags'], // ], // ]; $form['actions']['type'] = 'actions'; $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Subscribe'), ]; return $form; } /** * {@inheritdoc } */ public function submitForm(array &$form, FormStateInterface $form_state) { $this->messenger()->addStatus($this->t('Thanks for subscribing @name you will recibe to your email: @email all the information about it', ['@name' => $form_state->getValue('name'), '@email' => $form_state->getValue('email')])); } }
Además, ahora cambiarás el contenido de tu clase VegetarianFoodCourseBlock.php, por el siguiente código, para que en lugar de imprimir un mensaje, como lo hicimos en la primera comprobación, imprima el contenido del formulario que hemos creado.
Copia y pega el siguiente código, sustituyendo sólo la parte correspondiente a la clase:
class VegetarianFoodCourseBlock extends BlockBase { /** * {@inheritdoc } */ public function build(){ return [ \Drupal::formBuilder()->getForm('\Drupal\vegetarian_food_course\Form\VegetarianFoodForm'), '#cache' => [ 'max-age' => 0, ], ]; } }
Ahora, si vuelves a activar el módulo y el bloque personalizado que creamos anteriormente, podrás ver un formulario con varios campos. Si rellenas los campos y haces clic en el botón Suscribirse, deberías ver en pantalla, un mensaje de confirmación con algunos de los datos que haz introducido.
Habrás notado, que dentro de la clase hay un campo comentado y por lo tanto no aparece en el formulario, se trata de un campo de tipo autocompletar, que utiliza las taxonomías como opción del formulario, si quisieras activarlo, sólo tendrías que crear previamente algunos términos, dentro del vocabulario al que apunta el campo, para que se muestren dentro del formulario.
Si decides hacer la prueba, antes de continuar, solamente tendrás que descomentar el campo y refrescar el caché de Drupal, recuerda que antes deberías tener al menos un valor para que funcione el autocompletado dentro del campo.
Paso 3 Creación de una plantilla para el formulario:
Como nuestra idea es, además de presentar el formulario, imprimir en pantalla los valores que vamos a extraer desde la base de datos, directamente dentro de su mismo bloque y no como un mensaje por defecto en la parte superior de la pantalla, vamos a crear la configuración necesaria, utilizando la función hook_theme(){ }.
Si todavía no sabes como utilizarla, te invito a que, antes de continuar, le eches un vistazo al artículo Cómo crear módulos con su controlador y plantilla en Drupal 9, Haz clic aquí, donde te explico los principios para que puedas entender lo que sucederá a continuación.
A continuación, vamos a crear el archivo ".module", donde podremos ejecutar los hooks o funciones php de Drupal, en este caso, la hook_theme(){ }, nos permitirá configurar una plantilla personalizada con la que modificaremos los datos que se presentan dentro del bloque, además de imprimir los valores que obtendremos desde la base de datos un poco más adelante.
Por ahora, tendrás que crear el archivo vegetarian_food_course.module y dentro copiarás y pegarás el código siguiente, correspondiente a la función y los parámetros que vamos a pasarle desde el bloque.
<?php /** * @file * Implements hook_theme() */ function vegetarian_food_course_theme($existing, $type, $theme, $path) { return [ 'vegetarian-food-course-form' => [ 'variables' => [ 'title' => NULL, 'records' => NULL, 'form' => NULL, ] ] ]; }
Esta función nos permitirá crear una plantilla Twig, que nos devolverá un arreglo o array llamado variables, y dentro del mismo, hemos declarado tres valores nulos, porque los obtendremos directamente desde la clase que genera nuestro bloque.
Estos tres valores, son:
- Title: que utilizaremos para reescribir el que se muestra por defecto en nuestro bloque
- Records: que nos permitirá imprimir los valores obtenidos cuando nos conectemos a la base de datos
- Form: que nos permitirá imprimir el formulario y hacer modificaciones en su aspecto.
La siguiente modificación que tendremos que hacer, será dentro de nuestra clase VegetarianFoodCourseBlock.php, porque vamos a invocar la función hook_theme(){ } y además, añadiremos una variable para el formulario y otra para los valores de la base de datos.
Copia y sustituye el código que te muestro a continuación en la clase VegetarianFoodCourseBlock.php
class VegetarianFoodCourseBlock extends BlockBase { /** * {@inheritdoc } */ public function build(){ $form = \Drupal::formBuilder()->getForm('\Drupal\vegetarian_food_course\Form\VegetarianFoodForm'); $output = []; return [ '#theme' => 'vegetarian-food-course-form', '#title' => $this->t('Formulario de Inscripción'), '#records' => $output, '#form' => $form, '#cache' => [ 'max-age' => 0, ], ]; } }
Llegados a este punto, tendremos que crear la plantilla twig, con el nombre vegetarian-food-course-form.html.twig, dentro de la carpeta templates, tal y como te muestro en la imagen.
Luego, copia el código que te muestro a continuación, dentro de tu plantilla y una vez realizado este proceso, podrás ver los cambios dentro del bloque.
<style> h1.titulo-inscripcion { text-align: center; font-weight: 600; text-decoration: underline; margin-bottom: 30px; } .formulario-inscripcion { padding: 20px 10px; border: 2px dotted; margin-bottom: 20px; } </style> <h1 class="titulo-inscripcion"> {{ title }} </h1> <div class="formulario-inscripcion"> {{ form }} </div>
Notarás inmediatamente el nuevo aspecto de tu bloque, hemos añadido algunos estilos en la parte superior de la plantilla, para poder modificar el aspecto del los elementos utilizando las clases con las que hemos envuelto el título y el formulario.
Si ves el título del bloque por duplicado, es porque todavía estará marcado dentro de la pantalla de Administración de bloques, una vez lo hayas modificados, si refrescas caché lo verás tal y como se muestra en la imagen.
Paso 4 Creación de la tabla dentro de la base de datos:
Sientes un gran estado de emoción, por lo lejos que haz llegado en tan poco tiempo, ya conoces la forma de crear un bloque personalizado, un formulario, y además, combinar ambos, para mostrarlos dentro de una plantilla, a la que puedes manipular a tu antojo.
Así que, sin más dilación, vamos a la parte cumbre de este ejercicio, crearemos la tabla, donde alojaremos todos los datos introducidos a través del formulario, para luego mostrarlos en la plantilla.
Para lograr nuestro objetivo, crearemos una tabla programáticamente y luego simplemente tendremos que configurar, en el bloque para que los datos que recogeremos se muestren en pantalla.
Si todavía no haz creado tu primera tabla programáticamente, es el momento de parar para ver el artículo Cómo crear tablas programáticamente en Drupal 9 Haz clic aquí, donde te lo explico detalladamente.
Crea un archivo llamado vegetarian_food_course.install y dentro, pega el siguiente código, para que se genere tu nueva tabla, con todos los campos que hemos definido en ella.
<?php /** * Implment hook_schema() */ function vegetarian_food_course_schema() { $schema['vegetarian_food_course'] = array( 'description' => 'Save the data of the registrants for the course', 'fields' => array( 'vid' => array( 'type' => 'serial', 'not null' => TRUE, 'description' => 'Primary Key: Identificador único del participante.', ), 'name' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'Participant name.', ), 'lastname' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'Participant\'s last name.', ), 'email' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'Participant email.', ), 'vegetarian_question' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'Participant email.', ), 'occupation' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'Participant email.', ), ), 'primary key' => array('vid'), 'indexes' => array( 'name' => array('name'), 'lastname' => array('lastname'), 'email' => array('email'), 'vegetarian_question' => array('vegetarian_question'), 'occupation' => array('occupation'), ), ); return $schema; }
Esta vez, tendrás que desinstalar el módulo y volver a instalarlo, ya que vamos a crear una tabla, en el momento en que realizamos dicha instalación.
Además, aprovechamos para añadir algunos campos adicionales, como el apellido y descomentamos el autocompletado del formulario, después de añadir algunos términos dentro del vocabulario tag, para que ya puedas ver al completo como sería el funcionamiento real.
Por lo tanto, para que puedas probarlo sin errores, copia y sustituye el código dentro de la clase del formulario:
<?php namespace Drupal\vegetarian_food_course\Form; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; /** * @file * Implement Form API */ class VegetarianFoodForm extends FormBase { /** * {@inheritdoc } */ public function getFormId() { return 'vegetarian_food_course_form'; } /** * {@inheritdoc } */ public function buildForm(array $form, FormStateInterface $form_state) { $form['name'] = [ '#type' => 'textfield', '#title' => $this->t('Name'), '#description' => $this->t('Name of participant'), '#attributes' => [ 'placeholder' => $this->t('Your Name'), ], '#required' => TRUE, ]; $form['lastname'] = [ '#type' => 'textfield', '#title' => $this->t('Last Name'), '#description' => $this->t('Last Name of participant'), '#attributes' => [ 'placeholder' => $this->t('Your Last Name'), ], '#required' => TRUE, ]; $form['email'] = [ '#type' => 'email', '#title' => $this->t('Email'), '#attributes' => [ 'placeholder' => $this->t('Your Email') ], '#required' => TRUE, ]; $form['vegetarian_question']['active'] = array( '#type' => 'radios', '#title' => $this ->t('Are you Vegetarian?'), '#default_value' => 1, '#options' => array( 0 => $this ->t('No'), 1 => $this ->t('Yes'), ), ); $form['occupation'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'taxonomy_term', '#title' => 'Occupation', '#selection_settings' => [ 'target_bundles' => ['tags'], ], ]; $form['actions']['type'] = 'actions'; $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Subscribe'), ]; return $form; } /** * {@inheritdoc } */ public function submitForm(array &$form, FormStateInterface $form_state) { $this->messenger()->addStatus($this->t('Thanks for subscribing @name you will recibe to your email: @email all the information about it', ['@name' => $form_state->getValue('name'), '@email' => $form_state->getValue('email')])); } }
Y recuerda, que como hemos desinstalado el módulo, tendremos que volver a Administrar bloques para activarlo nuevamente, tomando en cuenta de que hemos modificado su nombre con el hook_theme(){ }, tendremos que buscarlo con el nuevo nombre que hayamos puesto en la variable title.
Si todo ha ido bien, deberías poder ver un formulario completo, con el nuevo campo autocompletar y el apellido, y al rellenar todos los datos, sería como el que te muestro en la siguiente imagen.
A continuación vamos a realizar los últimos cambios, primero crearemos una consulta dinámica, dentro de nuestro bloque, para poder mostar los datos de la tabla en nuestra plantilla, si quieres conocer un poco más sobre la construcción de queries o consultas en Drupal, tienes la Página oficial.
Copia y pega el código siguiente, dentro de la plantilla que genera nuestro bloque:
class VegetarianFoodCourseBlock extends BlockBase { /** * {@inheritdoc } */ public function build(){ $form = \Drupal::formBuilder()->getForm('\Drupal\vegetarian_food_course\Form\VegetarianFoodForm'); $database = \Drupal::database(); $query = $database->select('vegetarian_food_course', 'vgc'); $query->fields('vgc'); $result = $query->execute()->fetchAll(); return [ '#theme' => 'vegetarian-food-course-form', '#title' => $this->t('Formulario de Inscripción'), '#records' => $result, '#form' => $form, '#cache' => [ 'max-age' => 0, ], ]; } }
En esta parte del código, nuestro objetivo es decirle a Drupal que consulte en nuestra tabla vegetarian_food_course, todos sus campos y luego los recorra para poder acceder a ellos e imprimirlo dentro de la plantilla, hemos sustituido el array output por $result, para que tenga más coherencia, pero puedes usar el mismo si lo deseas.
Otra modificación, está en la función submitForm(){}, para que en lugar de imprimir el mensaje en pantalla, como hacíamos al principio del artículo, ahora, cuando rellenemos los campos del formulario, se guarden dentro de la tabla que hemos creado.
Copia y sustituye el código dentro de la clase que genera el formulario, para conseguir este cambio de funcionalidad.
/** * {@inheritdoc } */ public function submitForm(array &$form, FormStateInterface $form_state) { \Drupal::database()->insert('vegetarian_food_course') ->fields(['name', 'lastname','email','vegetarian_question','occupation']) ->values(array( $form_state->getValue('name'), $form_state->getValue('lastname'), $form_state->getValue('email'), $form_state->getValue('vegetarian_question'), $form_state->getValue('occupation'), )) ->execute(); $this->messenger()->addStatus($this->t('Thanks for subscribing @name you will recibe to your email: @email all the information about it', ['@name' => $form_state->getValue('name'), '@email' => $form_state->getValue('email')])); } }
Ahora que ya hemos realizado los cambios en la clase del bloque y en la función submit, si desinstalas y reinstalas el módulo, al rellenar los campos y darte el mensaje de confirmación como antes, también podrás ver que tus datos han sido añadidos a la tabla correspondiente en nuestra base de datos.
Si abres tu gestor de base de datos, y buscas la tabla relacionada con nuestro módulo, podrás comprobar que todo funciona según lo planeado.
Añadir traducciones (PLUS):
Para que nuestro módulo sea completo, pensamos que sería correcto añadirle los archivos de traducción y la configuración adicional, para que al instalarlo, Drupal los reconozca y automáticamente los muestre en el idioma correspondiente.
Para que podamos añadir archivos de este tipo, primero tendremos que agregar algunas líneas dentro de nuestro archivo .info, y, posteriormente, el archivo que contendrá todas nuestras traducciones.
Nuestro archivo .info, quedará de la siguiente forma:
name: Vegetarian Food Course description: 'Create a registration form for the course' package: drupaladicto type: module core_version_requirement: ^8.8.0 || ^9.0 project: vegetarian_food_course 'interface translation project': vegetarian_food_course 'interface translation server pattern': modules/custom/vegetarian_food_course/translations/vegetarian_food_course-%language.po dependencies: - node
Una vez hayamos añadido la información relacionada con nuestro archivo de traducciones y su ruta, podremos añadir nuestro archivo correspondiente, que para este ejercicio queda de la siguiente forma:
msgid "Name of participant" msgstr "Nombre del participante" msgid "Last Name of participant" msgstr "Apellido del participante" msgid "Are you Vegetarian?" msgstr "¿Eres vegetariano?" msgid "More Vegetarians in your Family?" msgstr "¿Hay más vegetarianos en tu familia?" msgid "Other vegetarians" msgstr "Otros familiares vegetarianos" msgid "Occupation" msgstr "Profesión" msgid "Your Name" msgstr "Su nombre" msgid "Your Last Name" msgstr "Su apellido" msgid "Your Email" msgstr "Su correo electrónico" msgid "1 Person" msgstr "1 Persona" msgid "2 Persons" msgstr "2 Personas" msgid "3 Persons" msgstr "3 Personas" msgid "All my family" msgstr "Toda mi familia"
Recuerda, que la ubicación debe corresponder con la que haz declarado en tu archivo .info o no funcionará.
Formularios | Imprimir en bloque programáticamente
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
Una de las necesidades con las que podremos encontrarnos, al desarrollar ciertos proyectos web, es que nuestro cliente necesite, además de tener un formulario personalizado, la característica o funcionalidad adicional, de mostrarlo en cualquier lugar de la web que lo requiera.
Una de las posibles razones, para requerir de esta opción, sería, por ejemplo, si quiere hacer una campaña, anunciando un descuento específico a los usuarios que se registren para aprovechar dicha oferta.
Por esta razón, hoy vamos a desarrollar un módulo personalizado, en el que presentaremos un pequeño formulario, que podremos mostrar en cualquier página de la web, utilizando los bloques de Drupal.
La idea, es explorar un poco más acerca de la creación de formularios personalizados, además de conocer la manera de invocarlos, para que estén disponibles en cualquier lugar que nos haga falta, mediante el uso de la clase "FormBuilder" de Drupal.
Requisitos:
Cómo imprimir un formulario dentro de un bloque en Drupal 9
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"
Y dentro del archivo bloque_formulario_personalizado.info.yml, necistarás el código para que Drupal lo reconozca como módulo y pueda ser activado una vez hayamos terminado.
name: Bloque Formulario Personalizado description: 'Bloque Formulario Personalizado' package: drupaladicto type: module core_version_requirement: ^8.8.0 || ^9.0
Paso 2 Creación del formulario personalizado:
Ahora que ya tenemos lo necesario para activar nuestro módulo, la siguiente tarea será crear nuestro formulario personalizado. Para hacer esto posible, primero tendremos que crear dos carpetas: src y Form y a continuación la clase que nos servirá para general nuestro formulario.
Dentro de nuestra clase FormularioPersonalizado.php, añadiremos las clases y elementos necesarios para la creación del formulario. Para continuar con el ejercicio, deberías haber leído y antes el artículo dónde explico paso a paso Haz clic aquí, lo único adicional que hemos añadido para este ejemplo son los atributos para imprimir el "Placeholder" y la opción de "Required" para hacer el campo obligatorio.
El formulario, una vez activado el módulo, mostrará los campos "Nombre" y "Correo electrónico" con su respectivo botón "Enviar" y al hacer clic en dicho botón, imprimirá en pantalla un mensaje de confirmación con los datos del formulario.
<?php namespace Drupal\bloque_formulario_personalizado\Form; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; /** * @file * Formulario Inscripcion Form */ class FormularioPersonalizado extends FormBase { /** * {@inheritdoc } */ public function getFormId() { return 'bloque_formulario_personalizado_form'; } /** * {@inheritdoc } */ public function buildForm(array $form, FormStateInterface $form_state) { $form['nombre'] = [ '#title' => $this->t('nombre'), '#type' => 'textfield', '#attributes' => [ 'placeholder' => $this->t('name'), ], '#required' => TRUE, ]; $form['email'] = [ '#type' => 'email', '#attributes' => [ 'placeholder' => $this->t('Write your email'), ], ]; $form['actions']['type']= 'actions'; $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Enviar'), '#buttom_type' => 'primary' ]; return $form; } /** * {@inheritdoc } */ public function submitForm(array &$form, FormStateInterface $form_state) { return $this->messenger()->addStatus($this->t('Your info @nombre and @email has been updated', ['@nombre'=>$form_state->getValue('nombre'),'@email' =>$form_state->getValue('email')])); } }
Paso 3 Creación del Bloque personalizado:
A continuación, vamos a crear el bloque personalizado, para poder imprimir dentro de éste nuestro formulario y así, tendremos la opción de manipularlo para mostrarlo en cualquier página de nuestra web, accediendo a la url "/admin/structure/block", donde se administran los bloques en Drupal.
Para la creación del bloque personalizado puedes consultar el artículo Haz clic aquí, donde verás todo el proceso explicado paso a paso para que puedas entender lo que estamos haciendo.
En el código que verás a continuación, la única novedad que hemos añadido es la llamada a nuestro formulario, utilizando el método getForm de la clas FormBulder de Drupal ; con este método, sólo necesitarás pasarle como parámetro el namespace que apunta a tu formulario y él se encargará de buscarlo e interpretarlo para que se muestre en tu web.
<?php namespace Drupal\bloque_formulario_personalizado\Plugin\Block; use Drupal\Core\Block\BlockBase; /** * @Block( * id= "formulario_inscripcion_block", * admin_label = @translation("Formulario Inscripcion Block"), * category = @translation("Formulario Inscripcion Block") * ) */ class FormularioInscripcionBlock extends BlockBase{ /** * {@inheritdoc } */ public function build() { return [ \Drupal::formBuilder()->getForm('\Drupal\bloque_formulario_personalizado\Form\FormularioPersonalizado'), '#cache' => [ 'max-age' => 0, ], ]; } }
Paso 4 Activación del módulo y el el bloque:
Ya sólo nos queda activar el módulo desde la url "/admin/modules" y una vez realizada esta acción, nos moveremos hacia la pantalla de administración de los bloques, donde podremos seleccionar la región o zona para mostrarlo, además de poder filtrar si queremos que sólo se vea en la página principal o en alguna otra página específica.
Formularios | Creación programáticamente en Drupal 9
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
Una de las partes de más importantes de toda web son sus formularios, desde el típico que utilizamos para que nuestros usuarios nos contacten, con cualquier tipo de solicitud de información, hasta otros mucho más complejos como el de suscripción a un curso o el de compra de artículos en una tienda online.
A partir de Drupal 8, el formulario de contacto del sitio, que nos viene por defecto en una instalación, nos ofrece varias novedades como la de ampliar el número de campos para recabar más información, si nos hace falta, o también la oportunidad de combinar formulario de contacto del sitio, con otros elementos como los paragraphs Haz clic aquí, por medio de las "preprocess_functions" añadiendo así un amplio abanico de opciones.
Otra alternativa con la que contamos ya en Drupal 9 es el Módulo Webform, que también ofrece un gran número de opciones y configuraciones, que prácticamente nos permitirán cubrir cualquier necesidad en cuanto a la generación de formularios, aunque, debido a su gran tamaño y complejidad, puede que debas pensarlo bien antes de descargar y activar un montón de recursos para tu web, sin una verdadera necesidad que lo justifique.
Por último, pero no menos importante, está la creación de formularios creados a medida, mediante un módulo personalizado y la API de Drupal, ofreciéndote así un control absoluto sobre sus funcionalidades, para que tus proyectos cumplan con los requisitos exactos.
Requisitos:
- Antes de comenzar a crear tu propio formulario, necesitarán al menos conocer cómo crar módulos personalizados en Drupal 9 Haz clic aquí.
Cómo crear un formulario programáticamente
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"
Paso 2 Añadir nuestra clase Form:
A continuación, añadiremos la clase php en la que vamos a guardar todo el código relacionado con la creación y funcionalidades de nuestro formulario. Esta clase estará alojada dentro de las carpetas "src/Form" y tendrá el mismo nombre que nuestro módulo, con la diferencia de que estará compuesta por las dos palabras con mayúscula inicial, terminado en la extensión php.
Para conocer más sobre la creación de formularios en Drupal 9, puedes dirigirte a la Página oficial de Drupal, donde explica con más detalle los pasos y componentes necesarios para crear un formulario programáticamente, tal y como hemos hecho en nuestro video.
También puedes aprender sobre los diferentes tipos de campos del formulario, su implementación y algunos ejemplos, visitando la Página oficial de Drupal Form Api.
Contenido de la clase Form
Namespace, FormBase y FormStateInterface:
En la primera sección de nuestra clase, tendremos que especificar el namespace o ruta, para que Drupal pueda encontrar nuestro módulo. Y a continuación, necesitaremos añadir dos clases fundamentales para la creación de cualquier formulario, estas clases son "FormBase" y "FormStarteInterface", la primera se encarga de generar la estructura del formulario y sus funcionalidades principales y la segunda, nos servirá para gestionar los datos introducidos a través del formulario, mediante la clase $form_state.
<?php namespace Drupal\custom_form\Form; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface;
Generación del ID o identificador del formulario:
El primero de los métodos que vamos a necesitar es el "getFormId(){ }", que nos servirá para configurar el identificador único, con el que Drupal podrá activar y leer los datos relacionados con nuestro formulario. Es una práctica recomendada, el uso del nombre del módulo, como parte de este identificador, de esta forma evitaremos conflictos con otros formularios existentes en nuestra instalación.
class CustomForm extends FormBase{ /** * {@inheritdoc } */ public function getFormId(){ return 'custom_form_form'; }
Construcción del formulario:
El segundo de los métodos imprescindibles para la creación de nuestro formulario personalizado, es el "buildForm(){ }", que se encargará de construir verdaderamente la estructura central del fomulario.
Esto significa que en esta parte es donde tendremos que definir todos los campos, con sus respectivos atributos, como tipo, clases, si son obligatorios o dependientes de otros campos, etc.
Es muy importante, no olvidar que en este método deberán estar el botón del Submit, que es el que nos servirá para ejecutar el siguiente paso una vez hallamos rellenado el formulario, y el "return $form", para garantizar que se impriman en pantalla todos los campos que hemos definido previamente.
/** * {@inheritdoc } */ public function buildForm(array $form, FormStateInterface $form_state) { $form['name']=[ '#type' => 'textfield', '#title' => $this->t('name'), ]; $form['lastname']=[ '#type' => 'textfield', '#title' => $this->t('lastname'), ]; $form['submit']=[ '#type' => 'submit', '#value' => $this->t('Send'), ]; return $form; }
Ejecutando la acción del formuario:
En este último método, llamado "submitForm() {}", es donde definimos lo que queremos que suceda, una vez el usuario haya completado el formulario y hecho clic en el botón submit.
Esta acción puede ser desde imprimir un mensaje en pantalla, usando los datos del formulario, como hemos decidido hacer en nuestro ejemplo, hasta guardar los datos en base de datos de Drupal, enviarlos a un correo electrónico o conectarse mediante servicios web con otro servidor externo a nuestra instalación.
En nuestro ejemplo, lo que haremos es recoger los valores de los campos, nombre (name) y apellido (lastname), para imprimirlos en pantalla utilizando el servicio $messenger, que sustituye al antiguo set_message(), utilizado en versiones anteriores de Drupal.
Además, concatenaremos los valores extraidos del formulario con un texto adicional.
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $this->messenger()->addStatus($this->t('Good mornig @fullname', ['@fullname' => $form_state->getValue('name')." ". $form_state->getValue('lastname')])); }
Puedes explorar otras formas opciones disponibles para imprimir mensajes usando $messenger en Drupal 9 Haz clic aquí
Una vez completada la configuración de la clase, para generar nuestro formulario y antes de activar nuestro módulo, necesitaremos crear el archivo "routing.yml", para poder acceder al formulario vía url, una vez activado.
La clase CustomForm.php completa, queda de la siguiente manera:
<?php namespace Drupal\custom_form\Form; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; class CustomForm extends FormBase{ /** * {@inheritdoc } */ public function getFormId(){ return 'custom_form_form'; } /** * {@inheritdoc } */ public function buildForm(array $form, FormStateInterface $form_state) { $form['name']=[ '#type' => 'textfield', '#title' => $this->t('name'), ]; $form['lastname']=[ '#type' => 'textfield', '#title' => $this->t('lastname'), ]; $form['submit']=[ '#type' => 'submit', '#value' => $this->t('Send'), ]; return $form; } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $this->messenger()->addStatus($this->t('Good mornig @fullname', ['@fullname' => $form_state->getValue('name')." ". $form_state->getValue('lastname')])); } }
Paso 3 Cofiguración ruta de acceso:
Ya tenemos nuestro formulario listo para que funcione, ahora solamente nos falta decirle a Drupal, cómo podrá acceder para mostrarlo en pantalla; para ello, tendremos que crear nuestro archivo "custom_form.routing.yml", con la información necesaria para que esto suceda correctamente una vez activemos nuestro módulo.
Es muy importante vigilar los espacios en cada una de las líneas del archivo routing, o no podremos obtener el resultado esperado.
No utilices el tabulador al crear este tipo de archivo, en su lugar vigila tener en cuenta "dos espacios", contando a partir del margen izquierdo, en cada nueva línea y sumando "dos espacios más", en el caso de elementos que estén dentro de otros.
El archivo "custom_form.routing.yml", queda de la siguiente manera:
custom_form.form: path: '/miformulario' defaults: _form: '\Drupal\custom_form\Form\CustomForm' _title: 'My Custom form' requirements: _permission: 'access content'
En la primera línea, al igual que hicimos en nuestra clase, especificamos el "namespace", pero en formato "yml", esto nos servirá al momento de implementar otras funcionalidades como por ejemplo, el acceso desde un menú.
En la segunda línea, definimos la url de acceso para que Drupal encuentre nuestro formulario una vez activado el módulo.
El apartado "Defaults", nos permite indicar la ruta de acceso a nuestra clase y el título que se mostrará en la página del formulario, una vez lo hayamos activado.
En el apartado "requirements", estamos definiendo los permisos o accesos específicos para nuestro formulario, en este ejemplo, el permiso es el que tiene drupal para todos los usuarios públicos.
Formularios en Drupal | Introducción a Form API
Las clases de formulario implementan \Drupal\Core\Form\FormInterface y el flujo de trabajo básico de un formulario se define mediante los métodos buildForm, validateForm y submitForm de la interfaz.
Cuando se solicita un formulario, se define como un arreglo (array) representable, a menudo denominada arreglo (array) API de formulario o simplemente arreglo (array) $form.
El arreglo $form se convierte a HTML mediante el proceso de representación y se muestra al usuario final. Cuando un usuario envía un formulario, la solicitud se realiza a la misma URL en la que se mostró el formulario, Drupal nota los datos HTTP POST entrantes en la solicitud y esta vez, en lugar de crear el formulario y mostrarlo como HTML, crea el formulario y luego procede a llamar a los controladores de validación y envío correspondientes.
Definir formularios como arreglos estructurados, en lugar de HTML directo, tiene muchas ventajas, entre ellas:
- Salida HTML coherente para todos los formularios.
- Los formularios provistos por un módulo pueden ser modificados fácilmente por otro sin una lógica compleja de búsqueda y reemplazo.
- Los elementos de formularios complejos, como la carga de archivos y los widgets de votación, se pueden encapsular en paquetes reutilizables que incluyen lógica de visualización y procesamiento.
Hay varios tipos de formularios comúnmente utilizados en Drupal. Cada uno tiene una clase base que puede ampliar en su propio módulo personalizado.
Primero, identifique el tipo de formulario que necesita construir:
- Una forma genérica. Ampliar FormBase..
- Un formulario de configuración que permite a los administradores actualizar la configuración de un módulo. Ampliar ConfigFormBase.
- Un formulario para eliminar contenido o configuración que proporciona un paso de confirmación. Ampliar ConfigFormBase.
FormBase implementa FormInterface, y tanto ConfigFormBase como ConfirmFormBase extienden FormBase, por lo tanto, cualquier formulario que amplíe estas clases debe implementar algunos métodos necesarios.
Métodos requeridos
FormBase implementa FormInterface y, por lo tanto, cualquier formulario que tenga FormBase en su jerarquía debe implementar algunos métodos:
Para más información, visita la página oficial de Drupal Form Api
Paginación
- Página 1
- Siguiente página