Què és SDC?
Single-Directory Components ens permet la implementació de components a Drupal. Els components són parts de l’aplicació web amb un propòsit concret, per ser usats de forma modular i reutilitzable, com podria ser la creació d’un botó o d’un bàner.
Estructura dels components
Estan formats principalment pels següents fitxers, que es carregaran de manera automàtica en incloure el component a la nostra plantilla o mòdul si els fitxers estan nomenats correctament:
- TWIG: Plantilla amb l'estructura HTML.
- YML: Metadades necessàries per definir el component.
- Recursos CSS i JS (opcional).
A més, es poden afegir elements extra com imatges, README, SCSS, etc.
Exemple en l'estructura d'un component, col·locat dins d'un tema o mòdul, a la carpeta components
:
button
| - button.component.yml (requerit)
| - button.twig (requerit)
| - button.css
| - button.js
Principals avantatges i inconvenients
Avantatges:
- Millora l'organització dels components, encapsulant tot el que està relacionat amb el recurs dins d'una carpeta. Això facilita molt les millores, el manteniment i la comprensió dels elements.
- Millora l’escalabilitat dels components si s’aniden correctament.
- Millora la reutilització dels components en altres projectes.
Inconvenients:
- Per a paràmetres genèrics del tema (per exemple, variables per als colors), cal seguir important dades externes al mòdul, fet que impedeix un encapsulament complet.
- Si es comencen a generar components molt petits, pot acabar dificultant el desenvolupament per la dificultat de trobar-los o adonar-se que ja existeixen.
- Pot ser que realment no aporti gaire si el lloc no requereix molta reutilització d’elements i, en canvi, només redueixi el rendiment.
Metadades
Aquí tenim un exemple senzill de metadades per a un component que generarà un modal:
name: Modal
props:
type: object
properties:
title:
type: string
title: Title
description: The modal title.
classes:
type: string
title: Classes
description: Extra classes to be added to modal element.
text:
type: string
title: Text
description: The text inside the modal.
close_button:
type: boolean
title: Close button
description: If TRUE, the modal will show a close button.
Càrrega del component
Podem carregar el component als nostres fitxers twig de dues maneres diferents.
La primera és amb include
:
{{ include ('mytheme:modal', {
title: 'Atención',
text: 'Está previsto un mantenimiento de la web de 13:00 a 14:00',
close_button: true,
}) }}
La segona és amb embed
:
{% embed 'mytheme:modal' with {
title: 'Atención',
text: 'Está previsto un mantenimiento de la web de 13:00 a 14:00',
close_button: true,
} %} {% endembed %}
Estendre components
Una de les propietats més potents de SDC és la possibilitat d’estendre components per fer ajustos particulars. Per exemple, podem estendre la modal per crear una modal-primary
, de manera que el nou component tindrà estils o classes noves que li donaran un aspecte més específic.
Això ho faríem mitjançant el yml
, i incloent, per exemple, un nou fitxer CSS que aportarà noves regles a l’element:
name: Modal Primary
extends: modal
El fitxer twig
del modal-primary
podria ser així:
{{ include ('mytheme:modal', { classes: 'modal-primary' }) }}
Nota: L’exemple potser no és el més pràctic, és merament didàctic.
Props i Slots
Fins ara hem vist exemples de components als quals passem dades de forma estructurada (clau:valor). Això són els props (com també es pot apreciar al fitxer yml
d'exemple).
A més d’aquests, tenim un altre tipus de dades, els slots. Aquests són dades desestructurades, com components anidats o HTML, que no estan definits a l'esquema JSON de clau:valor i no són tipats.
Exemple de slots amb un slider
:
name: Slider
slots:
slide1:
title: Slide 1
description: "Slide 1"
slide2:
title: Slide 2
description: "Slide 2"
slide3:
title: Slide 3
description: "Slide 3"
Per utilitzar el slider
, carregarem els 3 slides
com a components extra que passarem per omplir els slots:
{% embed 'mytheme:slider' %}
{% block slide_1 %}
{{ include('mytheme:slide', { title: 'Slide A', description: 'This is the slider A' }) }}
{% endblock %}
{% block slide_2 %}
{{ include('mytheme:slide', { title: 'Slide B', description: 'This is the slider B' }) }}
{% endblock %}
{% block slide_3 %}
{{ include('mytheme:slide', { title: 'Slide C' }) }}
{% endblock %}
{% endembed %}
El problema de carregar els slots d’aquesta manera és que s’haurien de definir espais exactes (3 en aquest cas), i no seria dinàmic:
<div class="slider">
{% block slide_1 %}{% endblock %}
{% block slide_2 %}{% endblock %}
{% block slide_3 %}{% endblock %}
</div>
Slots dinàmics
Per carregar slots de manera dinàmica, hauríem de definir el twig
així:
<div class="slider">
{% for slide in slots.slides %}
<div class="slider-slide">
{{ slide|raw }}
</div>
{% endfor %}
</div>
Les metadades:
label: "Slider"
slots:
slides:
title: 'Slides'
description: "Array con los slides del slider."
El bloc d'inserció del component:
{{ include('mytheme:slider', {
slots: {
slides: [
include('mytheme:slide', { title: 'Slide A', description: 'This is the slider A' }),
include('mytheme:slide', { title: 'Slide B', description: 'This is the slider B' }),
include('mytheme:slide', { title: 'Slide C' }),
]
}
}) }}
Consideracions
Variables externes
Per resoldre el problema de variables SCSS globalitzades, es poden importar dins del fitxer SCSS del component:
@import "../../scss/vars";
Una altra solució seria generar variables CSS i usar-les dins del component.
Llibreries externes
Per utilitzar llibreries externes, com Bootstrap, es poden definir al YML
:
name: "Button"
description: "A reusable button component based on Bootstrap."
libraries:
- mytheme/bootstrap
props:
type: object
properties:
text:
type: string
title: Text
description: The button text.
Format correcte de càrrega dels components
Els components s’han d’incloure en el format nom_tema:component
.
{{ include ('@mytheme/components/modal.twig', {
title: 'Atención',
text: 'Está previsto un mantenimiento de la web de 13:00 a 14:00',
close_button: true,
}) }}
URLs interessants
Documentació oficial
https://www.drupal.org/docs/develop/theming-drupal/using-single-directory-components
DrupalCamp 2023 - SDC
DrupalCamp Spain 2023 - Diseño basado en componentes usando Single Directory Components (SDC)