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 %}