<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: oskar calvo</title>
    <description>The latest articles on DEV Community by oskar calvo (@oskar_calvo_1615a9b3b293f).</description>
    <link>https://dev.to/oskar_calvo_1615a9b3b293f</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1765681%2F71ebf4c9-9794-4626-a552-fe301f82d5bd.jpg</url>
      <title>DEV Community: oskar calvo</title>
      <link>https://dev.to/oskar_calvo_1615a9b3b293f</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oskar_calvo_1615a9b3b293f"/>
    <language>en</language>
    <item>
      <title>Añadir un capo de tipo hora y minutos en un formulario</title>
      <dc:creator>oskar calvo</dc:creator>
      <pubDate>Wed, 01 Apr 2026 11:09:36 +0000</pubDate>
      <link>https://dev.to/oskar_calvo_1615a9b3b293f/anadir-un-capo-de-tipo-hora-y-minutos-en-un-formulario-kp7</link>
      <guid>https://dev.to/oskar_calvo_1615a9b3b293f/anadir-un-capo-de-tipo-hora-y-minutos-en-un-formulario-kp7</guid>
      <description>&lt;p&gt;Una de las cosas que más me gusta es el FORM API de Drupal.&lt;/p&gt;

&lt;p&gt;Hoy vamos a ver como añadir un campo para recoger únicamente horas y minutos, &lt;/p&gt;

&lt;p&gt;La forma de hacerlo es, a partir de la versión 11.30 de Drupal la siguiente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'datetime_time_only'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="s1"&gt;'#type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'datetime'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'#date_date_element'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'none'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'#date_time_element'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'time'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'#date_time_format'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'H:i'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si estamos trabajando en versiones anteriores a la 11.30 la forma que he encontrado de hacerlo es con el módulo duration_field el cual define un &lt;a href="https://git.drupalcode.org/project/duration_field/-/blob/8.x-2.2/src/Element/DurationElement.php" rel="noopener noreferrer"&gt;Element&lt;/a&gt; para que podamos añadir a nuestros formularios un campo de tipo time&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt; &lt;span class="c1"&gt;// Usage example:&lt;/span&gt;
 &lt;span class="c1"&gt;// @code&lt;/span&gt;
 &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'duration'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
   &lt;span class="s1"&gt;'#type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'duration'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s1"&gt;'#title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Duration),
   // Only 15 minute increments.
   '&lt;/span&gt;&lt;span class="c1"&gt;#date_increment' =&amp;gt; 900,&lt;/span&gt;
   &lt;span class="c1"&gt;// Hide seconds.&lt;/span&gt;
   &lt;span class="s1"&gt;'#granularity'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'y:m:d:h:i'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="c1"&gt;// Require hours and minutes.&lt;/span&gt;
   &lt;span class="s1"&gt;'#required_elements'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'h:i'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Comento esto porque algunos modelos LLM no saben las diferentes opciones que existen y sugieren paparruchas.&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>formapi</category>
      <category>time</category>
    </item>
    <item>
      <title>Drupal Canvas, creación de páginas I</title>
      <dc:creator>oskar calvo</dc:creator>
      <pubDate>Wed, 24 Dec 2025 13:17:49 +0000</pubDate>
      <link>https://dev.to/oskar_calvo_1615a9b3b293f/drupal-canvas-creacion-de-paginas-i-c3b</link>
      <guid>https://dev.to/oskar_calvo_1615a9b3b293f/drupal-canvas-creacion-de-paginas-i-c3b</guid>
      <description>&lt;p&gt;Vamos con la creación de una página, para ello simplemente le damos a crear una página en el botón &lt;code&gt;+ Add Page&lt;/code&gt; que nos llevará a una página como esta:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj34fh1smxuu8f8tbzr03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj34fh1smxuu8f8tbzr03.png" alt="Crear una página con Canvas y template Byte" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Importante&lt;/strong&gt;, en mi caso he añadido dos idiomas a la web, con la ruta &lt;code&gt;https://drupalcms.ddev.site/en/canvas/editor/canvas_page/12&lt;/code&gt; y &lt;code&gt;https://drupalcms.ddev.site/es/canvas/editor/canvas_page/12&lt;/code&gt; no me funciona Canvas (&lt;em&gt;tengo que investigar esto&lt;/em&gt;), pero con la ruta &lt;code&gt;https://drupalcms.ddev.site/canvas/editor/canvas_page/12&lt;/code&gt; vemos la página lista para crear contenido.&lt;/p&gt;

&lt;p&gt;Esta página recuerda en su estructura a la de Gutenberg de Wordpress&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fykwcld9oqeg9grtoxliw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fykwcld9oqeg9grtoxliw.png" alt="Gutenberg editor" width="800" height="541"&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lateral izquierdo
&lt;/h2&gt;

&lt;p&gt;En el lateral izquierdo tenemos el menú principal, con los siguientes elementos en orden:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Library&lt;/li&gt;
&lt;li&gt;Layers&lt;/li&gt;
&lt;li&gt;Code&lt;/li&gt;
&lt;li&gt;Pages&lt;/li&gt;
&lt;li&gt;Templates&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Library
&lt;/h3&gt;

&lt;p&gt;Esta opción del menú nos pinta todos los componentes que tenemos habilitados* en nuestro portal web y también nos permite elegir entre patrones si tenemos creado alguno.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6a7s07hpdcc7qxidgoze.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6a7s07hpdcc7qxidgoze.png" alt=" " width="392" height="831"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Layers
&lt;/h3&gt;

&lt;p&gt;Esta opción nos permite definir con que capa de la página queremos trabajar, en e caso de Byte existen tres capas, Contenido, cabecera, y pie.&lt;/p&gt;

&lt;p&gt;También muestra los diferentes componentes que se están usando en cada capa en una estructura jerárquica, y en permite mover algunos componentes arriba y abajo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvizs7ojmvmvactlfjqa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvizs7ojmvmvactlfjqa.png" alt=" " width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;

&lt;p&gt;Esta opción nos permite añadir componentes mediante código, a esto e dedicaremos una entrada en exclusiva de esta serie.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pages
&lt;/h3&gt;

&lt;p&gt;Esta opción nos muestra el listado de todas las páginas que existen, recordemos, páginas de Canvas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Templates
&lt;/h3&gt;

&lt;p&gt;Esta opción nos permite usar Canvas para personalizar los view mode que tenemos definidos de  tipos de nodos.&lt;/p&gt;

&lt;p&gt;En caso de que se quiera usar un view mode concreto tenemos que ver si está activado en el nodo para poder usarlo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTA&lt;/strong&gt;: Lo que he visto por ahora con los nodos es que si añadimos un componente a un tipo de nodo (por ejemplo de blog) en Canvas afecta a todos los nodos, no he visto una forma para que un componente se aplique a un único nodo, estoy preguntando y mirando esto, porque si esto no se puede realizar sería algo a tener en cuenta si queremos elegir entre Layout Builder y Canvas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lateral derecho
&lt;/h2&gt;

&lt;p&gt;En el lateral derecho vemos las opciones de configuración del componente que se está trabando. Cuando se entra a la página lo que se muestra son los valores básicos de la página: título, URL, SEO Settings, Media, Page Title (meta-atributos), Meta Description.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2t1ine7liqqhtz7l3g64.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2t1ine7liqqhtz7l3g64.png" alt="Page data" width="353" height="821"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Drupal Canvas, Adminstración de contenido</title>
      <dc:creator>oskar calvo</dc:creator>
      <pubDate>Wed, 24 Dec 2025 12:08:50 +0000</pubDate>
      <link>https://dev.to/oskar_calvo_1615a9b3b293f/canvas-parte-2-primeros-pasos-4gf4</link>
      <guid>https://dev.to/oskar_calvo_1615a9b3b293f/canvas-parte-2-primeros-pasos-4gf4</guid>
      <description>&lt;p&gt;Este artículo los escribo con una instalación de DrupalCMS beta 2.x y template de instalación "Byte".&lt;/p&gt;

&lt;p&gt;Cuando hemos arrancado lo primero que he visto es que las páginas de canvas son independientes de la sección de contenido que solemos ver en Drupal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsvbrnw82pdxh86ebq5w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsvbrnw82pdxh86ebq5w.png" alt=" " width="313" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pages nos pinta el listado de "paginas" (no confundir con "basic pages") de Canvas, y el enlace CMS nos pinta la administración clasica de &lt;code&gt;/admin/content&lt;/code&gt; de Drupal.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pages
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffew3z0wfmgbfceuiraj9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffew3z0wfmgbfceuiraj9.png" alt="Pages" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Drupal CMS
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnb3795xbm267av65t7x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnb3795xbm267av65t7x.png" alt="Drupal CMS" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como se puede ver en las imágenes la administración (publicar/despublicar/borrar) para las páginas de Canvas es parecida, las operaciones que podemos hacer son borrar/ver/editar, y crear una página nueva además de buscar por el título de la página y filtrar por publicadas/despublicadas.&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>drupalcms</category>
      <category>uidesign</category>
      <category>contentwriting</category>
    </item>
    <item>
      <title>Drupal Canvas, introducción</title>
      <dc:creator>oskar calvo</dc:creator>
      <pubDate>Wed, 24 Dec 2025 11:57:09 +0000</pubDate>
      <link>https://dev.to/oskar_calvo_1615a9b3b293f/canvas-parte-1-566b</link>
      <guid>https://dev.to/oskar_calvo_1615a9b3b293f/canvas-parte-1-566b</guid>
      <description>&lt;p&gt;&lt;a href="https://www.drupal.org/project/canvas" rel="noopener noreferrer"&gt;Canvas &lt;/a&gt;es un módulo añadido a Drupal que permite la construcción de páginas webs simplemente agarrando y soltando elementos y luego personalizando dichos elementos.&lt;/p&gt;

&lt;p&gt;Uno de los puntos importantes respecto a otros módulos de Drupal que permitían construir páginas es que esta vez Canvas no viene de desarrolladores de backend dando funcionalidades a creadores de contenido/diseñadores, sino que ha sido un trabajo de análisis de que había en el mercado, ver como funcionaba, coger lo mejor de todo aquello que se ha analizado, hablar con diseñadores y creadores de contenido y luego sacar las funcionalidades que se quieren implementar, vamos que se ha pensando más como un producto con los diseñadores y creadores de contenido como  público objetivo. &lt;/p&gt;

&lt;p&gt;Que nadie me mal interprete, no digo que Layout Builder, Paragraphs, Panels, etc... no fueran buenos productos, pero mi opinión personal es que en la comunidad de Drupal durante muchos años hemos pensado en sacar módulos/productos pensados para desarrolladores backend/hardcoder y no tanto herramientas sencillas de usar para diseñadores o creadores de contenidos, y esto es precisamente lo que hizo que Wordpress triunfase donde no lo hizo Drupal, ellos sacaron un producto pensado para diseñadores o personas sin conocimientos y sin ganas de leerse un libro enorme.&lt;/p&gt;

&lt;p&gt;Con Canvas Drupal rompe esa dinámica y tenemos una herramienta pensada para ese tipo de usuarios.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi05u143qo880voyv6n93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi05u143qo880voyv6n93.png" alt=" " width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>uidesign</category>
      <category>ui</category>
      <category>contentwriting</category>
    </item>
    <item>
      <title>Añadir programáticamente un campo de tipo cshs a un formulario.</title>
      <dc:creator>oskar calvo</dc:creator>
      <pubDate>Tue, 11 Nov 2025 11:20:42 +0000</pubDate>
      <link>https://dev.to/oskar_calvo_1615a9b3b293f/anadir-programaticamente-un-campo-de-tipo-cshs-a-un-formulario-45o3</link>
      <guid>https://dev.to/oskar_calvo_1615a9b3b293f/anadir-programaticamente-un-campo-de-tipo-cshs-a-un-formulario-45o3</guid>
      <description>&lt;p&gt;El módulo &lt;a href="https://www.drupal.org/project/cshs" rel="noopener noreferrer"&gt;Client-side Hierarchical Select&lt;/a&gt; de Drupal permite elegir un elemento de un select cuando tenemos una jerarquía en árbol con múltiples valores.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojixqxc4epdtu300xnek.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojixqxc4epdtu300xnek.png" alt=" " width="640" height="150"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h6&gt;
  
  
  (Fuente de la foto: &lt;a href="https://www.drupal.org/project/cshs" rel="noopener noreferrer"&gt;https://www.drupal.org/project/cshs&lt;/a&gt;)
&lt;/h6&gt;
&lt;/blockquote&gt;

&lt;p&gt;Añadir este widget a las entidades de contenido es sencillo, simplemente en la pestaña de "Administrar la visualización del formulario" podemos elegir que widget queremos usar y si tenemos activado el módulo &lt;strong&gt;Cshs&lt;/strong&gt; lo veremos para los campos de taxonomías. &lt;/p&gt;

&lt;p&gt;El problema es que los formularios creados a medida para añadir funcionalidades, o los formularios de entidades de configuración no tienen la opción de "Administrar la visualización del formulario".&lt;/p&gt;

&lt;p&gt;En este caso muestro como usando el módulo Hux añado un hook_form_alter para añadir un campo adicional a la entidad que trae el módulo simplenews para poder categorizar los tipos de boletines que se crean usando un vocabulario ya definido en el proyecto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
  &lt;span class="cd"&gt;/**
   * Implement hook_form_alter().
   */&lt;/span&gt;
  &lt;span class="na"&gt;#[Alter('form')]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;addThematicFieldToNewsletters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;\Drupal\Core\Form\FormStateInterface&lt;/span&gt; &lt;span class="nv"&gt;$form_state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$form_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;in_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$form_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'simplenews_newsletter_edit_form'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'simplenews_newsletter_add_form'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="kc"&gt;TRUE&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'container_thematics'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s1"&gt;'#type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'fieldset'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'#title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Thematics'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;];&lt;/span&gt;

          &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'container_thematics'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'thematics'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s1"&gt;'#type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'cshs'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'#title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Select the thematic'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="s1"&gt;'#options'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;buildCshsOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'thematics'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="s1"&gt;'#weight'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="cd"&gt;/** @var \Drupal\simplenews\Entity\Newsletter $newsletter */&lt;/span&gt;
            &lt;span class="s1"&gt;'#default_value'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$form_state&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getFormObject&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getEntity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getThirdPartySetting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'gobcan_newsletters'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'thematics'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

          &lt;span class="p"&gt;];&lt;/span&gt;

            &lt;span class="c1"&gt;// Añadir entity builder para procesar los third party settings&lt;/span&gt;
            &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'#entity_builders'&lt;/span&gt;&lt;span class="p"&gt;][]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'buildThematicsEntity'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para definir correctamente el widget de formulario de Cshs tenemos que definir el campo del formulario como ´'#type' =&amp;gt; 'cshs',´ , además el array de ´#Options´ no sirve un array de tipo clave valor, sino que tiene que tener una estructura concreta para que Cshs pueda procesarlo, por eso se ha creado el método ´buildCshsOptions()´.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
    &lt;span class="cd"&gt;/**
     * Entity builder para las temáticas.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;buildThematicsEntity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$entity_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;\Drupal\simplenews\Entity\Newsletter&lt;/span&gt; &lt;span class="nv"&gt;$newsletter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;\Drupal\Core\Form\FormStateInterface&lt;/span&gt; &lt;span class="nv"&gt;$form_state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$thematics_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$form_state&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'thematics'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nv"&gt;$newsletter&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setThirdPartySetting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$module_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'thematics'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$thematics_value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta funciión es la función necesaria para guardar los valores en la entidad como configuraciones de terceros.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;buildCshsOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$vocabulary&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nv"&gt;$term_options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="nv"&gt;$terms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;entityTypeManager&lt;/span&gt;
      &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'taxonomy_term'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;loadTree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$vocabulary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kc"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kc"&gt;TRUE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$terms&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$termId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$term&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$term&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;target_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$term_options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$termId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CshsOption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$term&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="nv"&gt;$term&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;target_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$term_options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$termId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CshsOption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$term&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$term_options&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este método construimos la estructura del array que necesita Cshs para poder construir el widget correcto, usamos la clase CshsOption que trae el módulo para hacerlo.&lt;/p&gt;

&lt;p&gt;El código es de &lt;a href="https://www.drupal.org/u/dmudie" rel="noopener noreferrer"&gt;David Mudie (dmudie)&lt;/a&gt; lo saqué de esta &lt;a href="https://www.drupal.org/project/cshs/issues/3361342" rel="noopener noreferrer"&gt;Issue&lt;/a&gt; en Drupal.org&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>php</category>
      <category>formapi</category>
    </item>
    <item>
      <title>PHP 8.5 nos trae closures en constantes de clases.</title>
      <dc:creator>oskar calvo</dc:creator>
      <pubDate>Tue, 23 Sep 2025 21:52:15 +0000</pubDate>
      <link>https://dev.to/oskar_calvo_1615a9b3b293f/php-85-nos-trae-closures-en-constantes-de-clases-22d3</link>
      <guid>https://dev.to/oskar_calvo_1615a9b3b293f/php-85-nos-trae-closures-en-constantes-de-clases-22d3</guid>
      <description>&lt;p&gt;La verdad es que esta nueva funcionalidad me deja frío, y es añadir una constante que puede ejecutar una función anónima no termina de convencerme.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="no"&gt;VALIDATOR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(fuente del código: &lt;a href="https://pixicstudio.medium.com/php-8-5-new-developer-features-f9617311c590" rel="noopener noreferrer"&gt;https://pixicstudio.medium.com/php-8-5-new-developer-features-f9617311c590&lt;/a&gt;) &lt;br&gt;
Para resolver eso mismo podemos crear un &lt;a href="https://www.kai-sassnowski.com/post/php-functors-1/" rel="noopener noreferrer"&gt;functor&lt;/a&gt; o podemos usar también un &lt;a href="https://www.php.net/manual/en/language.oop5.traits.php" rel="noopener noreferrer"&gt;trait&lt;/a&gt;, o incluso una clase con un método estático (pero mejor los traits).&lt;/p&gt;

&lt;p&gt;Un functor al ser una clase se puede inyectar sin problemas en otras clases y un trait está precisamente pensado para ser usado dentro de otras clases.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Functor&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;fmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;callable&lt;/span&gt; &lt;span class="nv"&gt;$fn&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;Functor&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Arr&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Functor&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;fmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;callable&lt;/span&gt; &lt;span class="nv"&gt;$fn&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;Functor&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(fuente del código: &lt;a href="https://www.kai-sassnowski.com/post/php-functors-1/" rel="noopener noreferrer"&gt;https://www.kai-sassnowski.com/post/php-functors-1/&lt;/a&gt;) &lt;/p&gt;

&lt;p&gt;Un functor o un servicio normal los plantearía en caso de que sea necesario conectar con la capa de Infraestructura (acceso a bbdd, a servicios externos de terceros, etc.), un trait por otro lado lo implementaría en caso de que correspondiere a la capa de Dominio para manipular datos pero es que no veo en que momento sería buena idea o interesante añadir una función anónima a una constante.&lt;/p&gt;

&lt;p&gt;Así que lo dicho, no veo en qué momento sería buena idea añadir una función anónima a una constante. &lt;/p&gt;

</description>
      <category>php</category>
      <category>closures</category>
      <category>functors</category>
      <category>trait</category>
    </item>
    <item>
      <title>¿Ha sido una buena DrupalCampSpain 2025?</title>
      <dc:creator>oskar calvo</dc:creator>
      <pubDate>Tue, 23 Sep 2025 06:31:26 +0000</pubDate>
      <link>https://dev.to/oskar_calvo_1615a9b3b293f/ha-sido-una-buena-drupalcampspain-2025-12op</link>
      <guid>https://dev.to/oskar_calvo_1615a9b3b293f/ha-sido-una-buena-drupalcampspain-2025-12op</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Voy a dar mi opinión personal.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Creo que es una pregunta con una respuesta difícil y que depende más de los puntos de vista.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Desde mi punto de vista como persona que ha asistido a varias charlas&lt;/strong&gt;, la verdad es que la Camp ha sido interesante, quizás para mi gusto demasiada IA, pero no podemos negar que ahora mismo la IA es lo que está tirando de una parte importante del carro de la innovación en el sector de la informática/tecnología tanto a nivel de desarrollo y mejoras como de inversión económica, pero mi sensación es que después del pico del hype que hemos sufrido con la IA estamos en estos momentos en un momento meseta y no tengo claro si de aquí volverá a subir o tendrá una caída.&lt;/p&gt;

&lt;p&gt;También he echado en falta charlas más transversales que no sea únicamente Drupal, o en las que Drupal esté presente pero como una tecnología más, charlas del tipo "CSS moderno", "Gestión de proyectos", "SEO en un mundo el que Google está matando la navegación por los resultados de búsqueda", "el futuro de la web abierta", etc...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Desde mi punto de vista como ponente&lt;/strong&gt;, este año he tenido que dar dos talleres, uno en el Centro de Nuevas Tecnologías de Galicia y otro en la Camp, la verdad es que como siempre ha sido una experiencia enriquecedora ya que el hecho de preparar, revisar, volver a preparar los talleres se aprende mucho y ayuda a asentar conocimientos. El único pero que me pongo a mi mismo es en taller de ECA que a pesar de tener ejemplos muy sencillos del módulo quise enseñar algunas cosas algo más complejas que no terminaron de funcionar bien, ya tengo un posit para ver que ha pasado y poder explicarlo a los asistentes en una futura publicación.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Desde mi punto de vista como parte de la organización&lt;/strong&gt;, creo que la Camp ha ido rodada, ocurrieron pequeñas cosas pero todo se pudo subsanar sin problemas, si hasta acompañó el tiempo durante todo el evento. &lt;/p&gt;

&lt;p&gt;Mención especial se merece &lt;a href="https://www.linkedin.com/in/esmeraldalcastro/" rel="noopener noreferrer"&gt;Esmeralda&lt;/a&gt;, que se ha currado unos textos increíbles para ir publicando en Linkedin, este debería ser el nivel a seguir los próximos años, quizás nos tenemos que plantear que de cara al sprint final de las Camps (cuando más hincapié hacemos en RRSS) la AED debería contratar a una persona que trabaje en comunicación/RRSS para que nos ayude con los textos.&lt;/p&gt;

&lt;p&gt;Lo dicho, creo que ha salido una Camp muy redonda y para estar Galicia en "Finis Terrae" la comunidad ha respondido muy bien y hemos tengo una Camp con una gran afluencia de profesionales. &lt;/p&gt;

</description>
      <category>drupal</category>
      <category>drupalcamp</category>
    </item>
    <item>
      <title>¿Cómo detectar cuando un proyecto se ha construido bien?</title>
      <dc:creator>oskar calvo</dc:creator>
      <pubDate>Thu, 07 Aug 2025 18:14:41 +0000</pubDate>
      <link>https://dev.to/oskar_calvo_1615a9b3b293f/como-detectar-cuando-un-proyecto-se-ha-construido-bien-8ik</link>
      <guid>https://dev.to/oskar_calvo_1615a9b3b293f/como-detectar-cuando-un-proyecto-se-ha-construido-bien-8ik</guid>
      <description>&lt;p&gt;Este artículo es totalmente subjetivo basado en apreciaciones ya que valorar la calidad de un proyecto es una tarea compleja y se tienen que valorar muchos elementos: tests, documentación, arquitectura, etc...&lt;/p&gt;

&lt;p&gt;En una conversación de Medium, si a veces salen cosas interesantes en Medium y últimamente salen más cosas interesantes en los comentarios que en los contenidos (que de una temporada a esta parte apestan a IA que echa para atrás), comentamos lo que gustaba más sobre las últimas novedades de PHP y algunas de las novedades que denotaban no solo usar un PHP moderno sino que el equipo de desarrollo se preocupa por hacer buen código eran los siguientes.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;declare(strict_types=1);&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Esta declaración de constructor define que el código que sigue a continuación esté obligada a usar tipado estricto en la definición de métodos y funciones.&lt;/p&gt;

&lt;p&gt;Usar esta declaración no es el santo grial pero si ayuda a entender mucho mejor el código, también ayuda a las herramientas de análisis de código estático a encontrar posibles errores, y hace el código más mantenible y organizado.&lt;/p&gt;

&lt;p&gt;Se que se puede usar mixed como una forma de "escapar" del tipado estricto pero usando el histórico de git sabríamos que desarrollador lo está usando.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;final class&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;final class&lt;/code&gt; permite definir que clases pueden ser heredables y cuales no, esta funcionalidad me parece interesante porque de forma explícita indica la relación jerárquica de las clases, y evita que haya una herencia de unas clases a otras de forma infinita.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;readonly class&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Readonly class es otra forma de declarar las clases, en este caso una clase que es instanciada con sus valores no podrá ser modificada, esta forma de declarar una clase ayuda para entender el uso de las mismas y normalmente las suelo usar en las clases de tipo Value Object como los DTO se benefician de readonly.&lt;/p&gt;

</description>
      <category>php</category>
    </item>
    <item>
      <title>Add custom twig templates to drupal regions</title>
      <dc:creator>oskar calvo</dc:creator>
      <pubDate>Mon, 07 Jul 2025 13:57:54 +0000</pubDate>
      <link>https://dev.to/oskar_calvo_1615a9b3b293f/add-custom-twig-templates-to-drupal-regions-2dfi</link>
      <guid>https://dev.to/oskar_calvo_1615a9b3b293f/add-custom-twig-templates-to-drupal-regions-2dfi</guid>
      <description>&lt;h2&gt;
  
  
  page.hmtl.twig
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="c1"&gt;#
/**&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;Tara&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;theme&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;single&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="n"&gt;doctype&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nc"&gt;Instead&lt;/span&gt; &lt;span class="n"&gt;they&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;twig&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;Available&lt;/span&gt; &lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;General&lt;/span&gt; &lt;span class="n"&gt;utility&lt;/span&gt; &lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;base_path&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="no"&gt;URL&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="nc"&gt;Drupal&lt;/span&gt; &lt;span class="n"&gt;installation&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nc"&gt;Will&lt;/span&gt; &lt;span class="n"&gt;usually&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="s2"&gt;"/"&lt;/span&gt; &lt;span class="n"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;have&lt;/span&gt; &lt;span class="n"&gt;installed&lt;/span&gt; &lt;span class="nc"&gt;Drupal&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;is_front&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="n"&gt;indicating&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;front&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;logged_in&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="n"&gt;indicating&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;registered&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;signed&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;is_admin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="n"&gt;indicating&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;permission&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;access&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;administration&lt;/span&gt; &lt;span class="n"&gt;pages&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;Site&lt;/span&gt; &lt;span class="n"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;front_page&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="no"&gt;URL&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;front&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="kn"&gt;Use&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;instead&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="nf"&gt;base_path&lt;/span&gt; &lt;span class="n"&gt;when&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;linking&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;front&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nc"&gt;This&lt;/span&gt; &lt;span class="n"&gt;includes&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;language&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="k"&gt;or&lt;/span&gt; &lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;Page&lt;/span&gt; &lt;span class="nf"&gt;content&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;occurrence&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;twig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Fully&lt;/span&gt; &lt;span class="n"&gt;loaded&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;there&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;automatically&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;loaded&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;associated&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="no"&gt;ID&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="nf"&gt;path&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;12345&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;12345&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;revisions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;but&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;12345&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;Regions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;header_top&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site_branding&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;Items&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logo&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt; &lt;span class="n"&gt;slogan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt; &lt;span class="n"&gt;branding&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;primary_menu&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;primary&lt;/span&gt; &lt;span class="n"&gt;menu&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search_box&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;full&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="n"&gt;search&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;breadcrumb&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;breadcrumb&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;highlighted&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;highlighted&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content_top&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content_bottom&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="n"&gt;bottom&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sidebar_first&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="n"&gt;sidebar&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sidebar_second&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;sidebar&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;footer_top&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;footer&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;footer_first&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;footer&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;footer_second&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="n"&gt;footer&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;footer_third&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;third&lt;/span&gt; &lt;span class="n"&gt;footer&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;footer_fourth&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;fourth&lt;/span&gt; &lt;span class="n"&gt;footer&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;footer_bottom&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;footer&lt;/span&gt; &lt;span class="n"&gt;bottom&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;see&lt;/span&gt; &lt;span class="nf"&gt;template_preprocess_page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;see&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;twig&lt;/span&gt;
 &lt;span class="o"&gt;*/&lt;/span&gt;
&lt;span class="c1"&gt;#}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="s1"&gt;'@tara/template-parts/header.html.twig'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="s1"&gt;'@tara/template-parts/breadcrumb_region.html.twig'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="s1"&gt;'@tara/template-parts/highlighted.html.twig'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"main-wrapper"&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"main-wrapper"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"container"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"main-container"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"page-content"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"main-content"&lt;/span&gt; &lt;span class="n"&gt;tabindex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-1"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="c1"&gt;# link is in html.html.twig #}&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="s1"&gt;'@tara/template-parts/content_top.html.twig'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="s1"&gt;'@tara/template-parts/content_bottom.html.twig'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="s1"&gt;'@tara/template-parts/left_sidebar.html.twig'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="s1"&gt;'@tara/template-parts/right_sidebar.html.twig'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="c1"&gt;# /.main-container #}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="c1"&gt;# /.container #}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="c1"&gt;# /main-wrapper #}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="s1"&gt;'@tara/template-parts/footer.html.twig'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  header-top-content.html.twig.twig
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"header-top"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"header-top-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      {% if page.header_top %}
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"header-top-left header-top-block"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          {% include '@tara/partials/header-top-content.html.twig' with { content: page.header_top } %}
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!--/.header-top-left --&amp;gt;&lt;/span&gt;
      {% endif %}
      {% if all_icons_show %}
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"header-top-right header-top-block"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          {% include '@tara/template-parts/social-icons.html.twig' %}
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!--/.header-top-right --&amp;gt;&lt;/span&gt;
      {% endif %}
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!--/.header-top-container --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!--/.container --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!--/.header-top --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  header-top-content.html.twig
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="c1"&gt;# themes/custom/tara/templates/partials/header-top-content.html.twig #}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"custom-header-top-content"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>My two cents about drupal templates marketplaces</title>
      <dc:creator>oskar calvo</dc:creator>
      <pubDate>Sat, 14 Jun 2025 17:14:58 +0000</pubDate>
      <link>https://dev.to/oskar_calvo_1615a9b3b293f/my-two-cents-about-drupal-templates-marketplaces-5d16</link>
      <guid>https://dev.to/oskar_calvo_1615a9b3b293f/my-two-cents-about-drupal-templates-marketplaces-5d16</guid>
      <description>&lt;p&gt;First of all, I want to state that this text represents my fears and my opinion based on my personal experience. It is not intended as an attack on anyone or anything.&lt;/p&gt;

&lt;p&gt;Although the idea of a Drupal template marketplace seems like a good idea to me and could be a good boost for Drupal as a product and therefore for the Drupal community, these are my doubts, fears, or a mix of everything.&lt;/p&gt;

&lt;p&gt;When we talk about a Drupal template marketplace, the WordPress marketplace comes to mind. It's true that this marketplace works and has possibly been one of WordPress's successes in becoming the product it is today, as it allowed someone without technical knowledge to have a beautiful and operational website.&lt;/p&gt;

&lt;p&gt;But we have to take the following into account: a high percentage of sites built with WordPress only use the two content types that come standard in WordPress: page and blog. Having such a basic and simple content architecture makes it easy to create themes that can be sold, since the fields used are known and therefore it doesn't pose any problem.&lt;/p&gt;

&lt;p&gt;To be able to do something similar, we either create a marketplace solely for Drupal CMS, or Drupal themes will only use "Article" and "Basic Page," which could be an option, a kind of Minimum Viable Product (MVP). However, my suspicion is that both Drupal CMS projects and Drupal in general will transcend the content architecture that these two products offer.&lt;/p&gt;

&lt;p&gt;From my experience, Drupal usually tends towards content architectures that adapt very well to the needs of projects and do not usually remain in the basic proposals.&lt;/p&gt;

&lt;p&gt;How can we overcome the particularity of Drupal having content architectures tailored to project needs and at the same time work with a theme marketplace? I believe that a solution would be recipes and the SDC module.&lt;/p&gt;

&lt;p&gt;If the community builds a kind of PSR (PHP Standards Recommendations) for content type recipes that can be installed as dependencies in projects, and in turn these recipes include an SDC for each element, it would make things much easier.&lt;/p&gt;

&lt;p&gt;On the one hand, these recipes would make it easier for site builders (and also for end users with less technical knowledge) when creating a project, as they could navigate between the different content type recipe options and choose the ones they need for the project. As I mentioned above, these recipes, in addition to a standard content type configuration, should have an associated SDC so that, without needing to buy a theme, they at least have the necessary HTML to be basic but correct.&lt;/p&gt;

&lt;p&gt;On the other hand, with this standardization, what will be achieved is that the themes programmed for Drupal will be more consistent with the project's content types. In fact, it would be interesting for themes to indicate the content types they style in their theme definition, so that a buyer can search among those that interest them most.&lt;/p&gt;

&lt;p&gt;Another of my fears is that the people who program the themes will move the backend logic to the Twig templates, either through Drupal community modules or through code they have programmed themselves.&lt;br&gt;
I don't have a solution for this. Perhaps a product rating and comment system, but these types of services eventually become very biased. Perhaps an agent of an LLM model that analyzes the code and can publish comments about it, but this would also be complex and costly.&lt;/p&gt;

&lt;p&gt;These are my fears and concerns, and what I seek with this exposition is not to scare anyone, but to work with the community to find the best way to build a healthy marketplace that helps the development of Drupal as a community and as a product. (editado) &lt;/p&gt;

</description>
      <category>drupal</category>
      <category>marketplaces</category>
      <category>templates</category>
    </item>
    <item>
      <title>Drupal Form state with select multiple</title>
      <dc:creator>oskar calvo</dc:creator>
      <pubDate>Tue, 03 Jun 2025 16:18:27 +0000</pubDate>
      <link>https://dev.to/oskar_calvo_1615a9b3b293f/drupal-form-state-with-select-multiple-1pdj</link>
      <guid>https://dev.to/oskar_calvo_1615a9b3b293f/drupal-form-state-with-select-multiple-1pdj</guid>
      <description>&lt;p&gt;A veces el código habla por si mismo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="s1"&gt;'#type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'item'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'#markup'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'This example demonstrates the #states
property. #states makes an element visibility dependent on another.'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'needs_accommodation'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="s1"&gt;'#type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'select'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'#title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Need Special Accommodations?'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'#options'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'1'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'si'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'2'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'no'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'3'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'vete a saber'&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="s1"&gt;'#multiple'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;TRUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="c1"&gt;// The #states property used here binds the visibility of the&lt;/span&gt;
    &lt;span class="c1"&gt;// container element to the value of the needs_accommodation checkbox above.&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'accommodation'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="s1"&gt;'#type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'container'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'#attributes'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'class'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'accommodation'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="c1"&gt;// #states is an associative array. Each key is the name of a state to&lt;/span&gt;
      &lt;span class="c1"&gt;// apply to the element, such as 'visible'. Each value is another array,&lt;/span&gt;
      &lt;span class="c1"&gt;// making a list of conditions that denote when the state should be&lt;/span&gt;
      &lt;span class="c1"&gt;// applied. Every condition is a key/value pair, whose key is a jQuery&lt;/span&gt;
      &lt;span class="c1"&gt;// selector that denotes another element on the page, and whose value is&lt;/span&gt;
      &lt;span class="c1"&gt;// an array of conditions, which must be met on in order for the state to&lt;/span&gt;
      &lt;span class="c1"&gt;// be applied.&lt;/span&gt;
      &lt;span class="c1"&gt;//&lt;/span&gt;
      &lt;span class="c1"&gt;// For additional documentation on the #states property including a list&lt;/span&gt;
      &lt;span class="c1"&gt;// of valid states and conditions see drupal_process_states().&lt;/span&gt;
      &lt;span class="s1"&gt;'#states'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="c1"&gt;// The state being affected is "invisible".&lt;/span&gt;
        &lt;span class="s1"&gt;'visible'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="c1"&gt;// Drupal will only apply this state when the element that satisfies&lt;/span&gt;
          &lt;span class="c1"&gt;// the selector input[name="needs_accommodation"] is un-checked.&lt;/span&gt;
          &lt;span class="s1"&gt;'select[name="needs_accommodation[]"]'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'value'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'3'&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'accommodation'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'diet'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="s1"&gt;'#type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'textfield'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'#title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Dietary Restrictions'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="c1"&gt;// Add a submit button that handles the submission of the form.&lt;/span&gt;
    &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'actions'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'submit'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="s1"&gt;'#type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'submit'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'#value'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Submit'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Los kudos para &lt;a href="https://www.linkedin.com/in/penyaskito/" rel="noopener noreferrer"&gt;Penyaskito&lt;/a&gt;&lt;/p&gt;

</description>
      <category>formstate</category>
      <category>select</category>
      <category>multiple</category>
    </item>
    <item>
      <title>Extender plugins de tipo bloque en Drupal</title>
      <dc:creator>oskar calvo</dc:creator>
      <pubDate>Sun, 25 May 2025 15:28:44 +0000</pubDate>
      <link>https://dev.to/oskar_calvo_1615a9b3b293f/extender-plugins-de-tipo-bloque-en-drupal-3od6</link>
      <guid>https://dev.to/oskar_calvo_1615a9b3b293f/extender-plugins-de-tipo-bloque-en-drupal-3od6</guid>
      <description>&lt;p&gt;Una de las cosas que más me gustán hacer en Drupal es crear una clase abstracta a modo de "base" cuando estoy definiendo bloques que se van a usar en un Slide.&lt;/p&gt;

&lt;p&gt;En este caso como el Slide afectaba a la información de páginas de taxonomías de un vocabulario lo que hice fue crear una clase abstracta para definir todos los elementos comunes de todos los bloques.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Drupal\project_term_area_study\Plugin\Block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Drupal\Core\Block\BlockBase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Drupal\Core\Entity\EntityTypeManagerInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Drupal\Core\Plugin\ContainerFactoryPluginInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\DependencyInjection\ContainerInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Drupal\taxonomy\TermInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Base class for all blocks used in area of study taxonomy pages.
 */&lt;/span&gt;
&lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AreaOfStudyBaseBlock&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BlockBase&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ContainerFactoryPluginInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="cd"&gt;/**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$entityTypeManager&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="cd"&gt;/**
   * Constructs a new MyCustomBlockBase object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$configuration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;$plugin_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;$plugin_definition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;EntityTypeManagerInterface&lt;/span&gt; &lt;span class="nv"&gt;$entity_type_manager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$configuration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$plugin_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$plugin_definition&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;entityTypeManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$entity_type_manager&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="cd"&gt;/**
   * {@inheritdoc}
   */&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ContainerInterface&lt;/span&gt; &lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$configuration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$plugin_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$plugin_definition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nv"&gt;$configuration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;$plugin_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;$plugin_definition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'entity_type.manager'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="cd"&gt;/**
   */&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getTermContext&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;?TermInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$term&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getContextValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'taxonomy_term'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$term&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;TermInterface&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$term&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo que ambos bloques que voy a usar comparten es que ambos necesitan el servicio entity_type.manager, y usan el contexto de bloques, en este caso para recuperar el término al que corresponde la página.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Drupal\project_term_area_study\Plugin\Block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Drupal\Core\Url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Provides an area study degree standard name list block.
 *
 * @Block(
 *   id = "project_term_area_study_degree_standard_name_list",
 *   admin_label = @Translation("Area study degree standard name list"),
 *   category = @Translation("project"),
 *   context_definitions = {
 *     "taxonomy_term" = @ContextDefinition("entity:taxonomy_term")
 *   }
 * )
 */&lt;/span&gt;
&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AreaOfStudyDegreeStandardNameListBlock&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AreaOfStudyBaseBlock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="cd"&gt;/**
   * {@inheritdoc}
   */&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$term&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getTermContext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este caso no tenemos que volve a definir ni el constructor ni el método create para cargar los servicios definidos en la clase abstracta ya que son los mismos.&lt;/p&gt;

&lt;p&gt;El segundo bloque necesita el servicio rendered, así que si se tiene que instanciar el constructor y el método create; lo importante también es que a parent::constructor además de los métodos por defecto de la base de plugins de Drupal se le tiene que pasar entityTypeManager que es un método que carga la clase abstracta que hemos definido.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Drupal\project_term_area_study\Plugin\Block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Drupal\Core\Entity\EntityTypeManagerInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\DependencyInjection\ContainerInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Drupal\taxonomy\TermInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Drupal\views\Views&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Drupal\Core\Render\RendererInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Provides an area of study - others area of study block.
 *
 * @Block(
 *   id = "project_term_area_study_others_area_of_study",
 *   admin_label = @Translation("Area of study - others area of study"),
 *   category = @Translation("project"),
 *   context_definitions = {
 *     "taxonomy_term" = @ContextDefinition("entity:taxonomy_term")
 *   }
 * )
 */&lt;/span&gt;
&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AreaOfStudyOthersAreaOfStudyBlock&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AreaOfStudyBaseBlock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="cd"&gt;/**
   * The current renderer.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$renderer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="cd"&gt;/**
   * Constructs the plugin instance.
   */&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$configuration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;$plugin_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;$plugin_definition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;EntityTypeManagerInterface&lt;/span&gt; &lt;span class="nv"&gt;$entityTypeManager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;RendererInterface&lt;/span&gt; &lt;span class="nv"&gt;$renderer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$configuration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$plugin_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$plugin_definition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$entityTypeManager&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$renderer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="cd"&gt;/**
   * {@inheritdoc}
   */&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ContainerInterface&lt;/span&gt; &lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$configuration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$plugin_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$plugin_definition&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nv"&gt;$configuration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;$plugin_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;$plugin_definition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'entity_type.manager'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'renderer'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="cd"&gt;/**
   * {@inheritdoc}
   */&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$term&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getTermContext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="cd"&gt;/**
   */&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getListOfTerms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;TermInterface&lt;/span&gt; &lt;span class="nv"&gt;$term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kt"&gt;?array&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// Code here.&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="cd"&gt;/**
   */&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;renderViewContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$view_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$display_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$arguments&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;mixed&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// Code here.&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;También es importante que aunque el método getTermContext() lo hemos definido en la clase abstracta en ambos bloques se tiene que definir dentro del "&lt;a class="mentioned-user" href="https://dev.to/block"&gt;@block&lt;/a&gt;" para que Drupal pueda cargar el contexto.&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>block</category>
      <category>extends</category>
    </item>
  </channel>
</rss>
