block https://drupaladicto.com/ es Contenidos de Prueba | Generados con el módulo Devel https://drupaladicto.com/curso/programacion-drupal/contenidos-de-prueba-generados-con-el-modulo-devel <span class="field field--name-title field--type-string field--label-hidden">Contenidos de Prueba | Generados con el módulo Devel</span> <div class="field field--name-field-contenidos-cap-gratis field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <style>#video-only-870 .play-btn:hover::after { border-left: 15px solid #1fd7d9; transform: scale(20); border-left: 15px solid #fff; } #video-only-870 .play-btn::before { border: 5px solid #1fd7d9; } #video-only-870 .play-btn { background: radial-gradient(#1fd7d9 50%, rgba(66, 109, 202, 0.4) 52%); }</style> <div class="paragraph paragraph--type--video-only paragraph--view-mode--default" id="vol-870"> <section id="video-only-870" class="about area-padding video-block-wrapper"> <div class="col video-box"> <div class="portada"> <img src="/sites/default/files/styles/diapositiva_1200x650/public/2023-07/portada-gratuito-grande_2.jpg?itok=8dBQYXT7" class="img-fluid" alt=""> <div class="field field--name-vo-youtube-video field--type-entity-reference field--label-visually_hidden"> <div class="field__label visually-hidden">Video de Youtube</div> <div class="field__item"><article class="media media--type-remote-video media--view-mode-diapositiva-1200x650"> <div class="field field--name-field-media-oembed-video field--type-string field--label-visually_hidden"> <div class="field__label visually-hidden">URL de Video remoto</div> <div class="field__item"><div class="modal micromodal-slide" id="modal-media-590-0-field-media-oembed-video" aria-hidden="true"> <div class="modal__overlay" tabindex="-1" data-micromodal-close> <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-media-590-0-field-media-oembed-video-content"> <a class="modal__btn" data-micromodal-close aria-label="Close this dialog window">X</a> <main class="modal__content" id="modal-media-590-0-field-media-oembed-video-content"> <div class="videoWrapper"><iframe src="/media/oembed?url=https%3A//youtu.be/eGXutQIDMIw&amp;max_width=0&amp;max_height=0&amp;hash=xkWV5NsCeCudS1gHm_0C5rpeAX6WhQh7VbpwqGyLRG0" frameborder="0" allowtransparency="" class="media-oembed-content" title="Time Value of Money"></iframe></div> </main> </div> </div> </div> <div><a class="myButton" data-micromodal-trigger="modal-media-590-0-field-media-oembed-video"><span class="btn play-btn">.</span></a></div> </div> </div> </article> </div> </div> </div> </div> </section> </div> </div> <div class="field__item"> <div class="paragraph paragraph--type--text-only paragraph--view-mode--default" id="txonly-1185" style="background-color: ;border: solid px;border-color: #096ba0;border-radius: 5px;padding: 10px;"> <div class="clearfix text-formatted field field--name-to-text field--type-text-long field--label-visually_hidden"> <div class="field__label visually-hidden">Texto</div> <div class="field__item"><p>      Cuando estamos empezando con el desarrollo o implementación de cualquier proyecto, en la mayoría de los casos nos resultará necesario la creación de contenidos con los que podamos realizar pruebas de todo tipo.</p> <p>     Para realizar esta tarea, en Drupal contamos con el módulo <strong>Devel Generate</strong>, integrado dentro de las dependencias del módulo <a href="https://www.drupal.org/project/devel" target="_blank">Devel</a>. Por lo que, una vez instalado y activado en nuestro Drupal, sólo tendremos que dirigirnos a la url "/admin/config/development/generate/content", y allí veremos el listado de todos los tipos de contenidos que tengamos creados en nuestro proyecto.</p> <h3>CÓMO INSTALAR Y CONFIGURAR EL MÓDULO:</h3> <p><strong>Paso 1 Descargar el módulo:</strong></p> <p>     Lo primero que tendrás que hacer es descargarlo, para ello, a partir de Drupal 8 se recomienda que utilices el gestor de paquetes <a data-extlink="" href="https://getcomposer.org/" rel="noreferrer" target="_blank">Composer</a>, ya que te facilitará tanto la instalación como futuras actualizaciones del tus proyectos. No obstante también podrías descargarlo desde la <a data-extlink="" href="https://www.drupal.org/project/devel" rel="noreferrer">Página oficial del módulo</a> y una vez descargado, tendrás que colocarlo en la carpeta "modules" o "modules/contrib", dependiendo de tu instalación y asegurarte de descargar todas sus dependencias o el módulo no funcionará, esta es una de las ventajas con las que cuentas al hacer la instalación usando Composer.</p> <p><strong>Paso 2 Activación del módulo</strong> :</p> <p>     Para activar el módulo Devel, al igual que todos los demás módulos contribuidos de Drupal, tendrás la posibilidad de hacerlo, mediante el uso de la herramienta Drush, con el comando <strong>"drush en devel -y"</strong>, que sirve para activar cualquier módulos y todas sus dependencias, o desde la interfaz de Drupal.    </p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 25.08%;" data-ratio="25.08" data-b-token="b-bf562569176" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img data-entity-uuid="bbffe9dd-d7d5-4f17-9b0a-52076bde5c34" loading="lazy" alt="Devel Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/modulo_devel.png?itok=DyCTE5F_" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="650" height="163" typeof="foaf:Image" /></div></div> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 81.38%;" data-ratio="81.38" data-b-token="b-07e736f3d56" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img data-entity-uuid="e63f7359-7862-4490-b2de-6abe96112e6c" loading="lazy" alt="Devel Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/generar_contenido.jpg?itok=dQhk5U7r" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="650" height="529" typeof="foaf:Image" /></div></div> <p>     Además de poder generar automáticamente nuestros contenidos, podremos configurar algunas opciones adicionales como, especificar su fecha de publicación, comentarios relacionados, títulos para los contenidos con un límite de caracteres específico, el idioma o incluso los usuarios que los crearon, esta última opción nos facilitará el testeo de los permisos de usuario.</p> <p>     Para generar nuestro contenidos, sólo tendremos que marcar las opciones con las que deseamos trabajar, es recomendable intentarlo la primera vez como poco contenido para estar seguros de obtener lo que pensábamos o si hará falta modificar algún campo.</p> <p>     Si no estás conforme con el contenido generado o simplemente quieres volver a generar contenidos otra vez, puedes seleccionar la opción de eliminar todos los contenidos previamente creados antes de ejecutarlo.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 74%;" data-ratio="74" data-b-token="b-4b2c2db1ff0" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img data-entity-uuid="f0925341-0457-435c-b020-899f5a76c3ec" loading="lazy" alt="Devel Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/como_generar_contenidos.jpg?itok=P7foOYOI" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="650" height="481" typeof="foaf:Image" /></div></div> <p>     Una vez que hayamos revisado todos los campos que nos interesan, haremos clic en el botón que aparece en la parte inferior de la pantalla y comenzará el proceso inmediatamente.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 62.62%;" data-ratio="62.62" data-b-token="b-529a6e0212d" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img data-entity-uuid="b59a89a7-77d6-44a7-b385-3b59d1edc906" loading="lazy" alt="Devel Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/idioma_y_usuarios.jpg?itok=faRslW2Z" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="650" height="407" typeof="foaf:Image" /></div></div> <p>     Cuando se haya realizado el proceso de generación de nuestros contenidos, veremos un mensaje de confirmación en la parte superior de la pantalla, con la cantidad y el tipo de contenido que decidimos utilizar.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 49.91%;" data-ratio="49.91" data-b-token="b-6a5876e61c1" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img data-entity-uuid="dac200ad-bc83-4875-81f5-e8f373ae57f9" loading="lazy" alt="Devel Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/generados.png?itok=lhYaSXTY" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="533" height="266" typeof="foaf:Image" /></div></div> <p>     Para comprobarlo, sólo tendremos que dirigirnos al listado de contenidos en la url "/admin/content" y veremos el listado de contenidos generados por el módulo con las configuraciones adicionales, si es que hemos seleccionado alguna.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 49.38%;" data-ratio="49.38" data-b-token="b-4e4a8d061ee" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img data-entity-uuid="182f2e84-9c0d-473e-93c7-26d287a6072f" loading="lazy" alt="Devel Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/listado_generados.jpg?itok=Jtk5KaGC" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="650" height="321" typeof="foaf:Image" /></div></div> </div> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Dom, 19/03/2023 - 09:10</span> Sun, 19 Mar 2023 08:10:21 +0000 webmaster 409 at https://drupaladicto.com Bloque personalizado | Creación programáticamente en Drupal 9 https://drupaladicto.com/curso/programacion-drupal/bloque-personalizado-creacion-programaticamente-en-drupal-9 <span class="field field--name-title field--type-string field--label-hidden">Bloque personalizado | Creación programáticamente en Drupal 9</span> <div class="field field--name-field-contenidos-cap-gratis field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <style>#video-only-863 .play-btn:hover::after { border-left: 15px solid #1fd7d9; transform: scale(20); border-left: 15px solid #fff; } #video-only-863 .play-btn::before { border: 5px solid #1fd7d9; } #video-only-863 .play-btn { background: radial-gradient(#1fd7d9 50%, rgba(66, 109, 202, 0.4) 52%); }</style> <div class="paragraph paragraph--type--video-only paragraph--view-mode--default" id="vol-863"> <section id="video-only-863" class="about area-padding video-block-wrapper"> <div class="col video-box"> <div class="portada"> <img src="/sites/default/files/styles/diapositiva_1200x650/public/2023-07/portada-gratuito-grande_2.jpg?itok=8dBQYXT7" class="img-fluid" alt=""> <div class="field field--name-vo-youtube-video field--type-entity-reference field--label-visually_hidden"> <div class="field__label visually-hidden">Video de Youtube</div> <div class="field__item"><article class="media media--type-remote-video media--view-mode-diapositiva-1200x650"> <div class="field field--name-field-media-oembed-video field--type-string field--label-visually_hidden"> <div class="field__label visually-hidden">URL de Video remoto</div> <div class="field__item"><div class="modal micromodal-slide" id="modal-media-583-0-field-media-oembed-video" aria-hidden="true"> <div class="modal__overlay" tabindex="-1" data-micromodal-close> <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-media-583-0-field-media-oembed-video-content"> <a class="modal__btn" data-micromodal-close aria-label="Close this dialog window">X</a> <main class="modal__content" id="modal-media-583-0-field-media-oembed-video-content"> <div class="videoWrapper"><iframe src="/media/oembed?url=https%3A//youtu.be/-OmXU1UGqqk&amp;max_width=0&amp;max_height=0&amp;hash=2tjtx5l8C8BOLGST1_JAbDxN072duOotP_ScsRDAAkY" frameborder="0" allowtransparency="" class="media-oembed-content" title="Time Value of Money"></iframe></div> </main> </div> </div> </div> <div><a class="myButton" data-micromodal-trigger="modal-media-583-0-field-media-oembed-video"><span class="btn play-btn">.</span></a></div> </div> </div> </article> </div> </div> </div> </div> </section> </div> </div> <div class="field__item"> <div class="paragraph paragraph--type--text-only paragraph--view-mode--default" id="txonly-1177" style="background-color: ;border: solid px;border-color: #096ba0;border-radius: 5px;padding: 10px;"> <div class="clearfix text-formatted field field--name-to-text field--type-text-long field--label-visually_hidden"> <div class="field__label visually-hidden">Texto</div> <div class="field__item"><h2><strong>Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... <a href="https://youtu.be/-OmXU1UGqqk" target="_blank">HAZ CLIC AQUI</a></strong></h2> <h2>QUÉ ES UN BLOQUE Y CÓMO FUNCIONAN</h2> <p>     Hoy te quiero hablar sobre los bloques en Drupal, que no son más que regiones, en las que puedes incluir prácticamente cualquier tipo de contenido, imágenes, texto simple o añadir campos editables por el usuario y que luego podrán mostrarse en cualquier área y página de tu web, además de ofrecerte la opción para controlar quiénes podrán ver su contenido, configurando los permisos de usuario.</p> <p>     Por defecto, una instalación de Drupal viene dividida en varias zonas con "Bloques" en su interior, el nombre y la cantidad de dichos bloques podrían variar, en función del "Theme" o tema que tengas instalado en tu proyecto. </p> <p>     Para que entiendas el concepto de Bloques, imagina que tu web es como una casa, con sus respectivas habitaciones, y que el mobiliario o la decoración que puedes añadir, quitar o modificar en cualquier de ellas es el bloque.</p> <p>     Para administrar los bloques, tendrás que ir a la url <strong>"/admin/structure/block"</strong>, allí encontrarás el listado de todos los bloques activados con las diferentes zonas de tu proyecto.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 65.42%;" data-ratio="65.42" data-b-token="b-4cdc9ac51b0" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" title="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/imagenes/file-6374fb3a8d42b.jpg?itok=zQoRNQUg" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="587" height="384" typeof="foaf:Image" /></div></div> <p>     Desde esta pantalla, tendrás la oportunidad de añadir cualquier otro bloque en la zona que desees, haciendo clic en el botón <strong>"Colocar Bloque"</strong> y seleccionando posteriormente cualquiera de los que se mostrará en el listado que te aparecerá a continuación. </p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 14.36%;" data-ratio="14.36" data-b-token="b-09ed080695e" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" title="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/imagenes/file-6374fb7b99cb3.jpg?itok=UnJPgCgE" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="801" height="115" typeof="foaf:Image" /></div></div> <p>     Además de añadir, también podrás desactivar, recolocar o remover menús, vistas personalizadas del tipo bloque, información del sitio, etc. o si lo necesitaras, utilizar instancias del mismo bloque en zonas diferentes de tu web.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 32.13%;" data-ratio="32.13" data-b-token="b-74df45b1a8a" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" title="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/imagenes/file-6374fb99c3e03.jpg?itok=4WKU-qyT" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="800" height="257" typeof="foaf:Image" /></div></div> <h2>BIBLIOTECA DE BLOQUES PERSONALIZADOS</h2> <p>     Otra de las opciones disponibles al trabajar con bloques, es la Biblioteca de bloques personalizados, donde podrás crear un modelo de bloque, para reutilizarlo como base siempre que te haga falta. </p> <p>     Un ejemplo práctico, sería que tuvieras en tu web un tipo de bloque personalizado al que llamaras, por ejemplo "Banner Publicitario", con la opción de añadir, editar o eliminar dentro de él, diferentes imágenes anunciando ofertas o descuentos, en varias partes de la web, sin tener que construir cada vez un bloque nuevo.</p> <p>     Los bloques personalizados se guardan en la pestaña "Biblioteca de bloques personalizados", y desde este apartado puedes modificar el modelo principal, por ejemplo añadiendo un botón que se llame "precio especial", y que automáticamente estará disponible para todo el resto de bloques que usan este modelo como base.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 42.88%;" data-ratio="42.88" data-b-token="b-5e9b68145c9" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" title="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/imagenes/file-6374fbb8694bb.jpg?itok=gJe7iQ9S" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="800" height="343" typeof="foaf:Image" /></div></div> <h2>CÓMO CREAR UN BLOQUE PROGRAMÁTICAMENTE EN DRUPAL 9</h2> <p>PRERREQUISITOS:</p> <ul><li><a href="/actualidad/como-crear-un-modulo-en-drupal-9" target="_blank">Cómo crear un módulo en Drupal 9</a></li> </ul><h3>     PASO 1 CREAR MÓDULO PERSONALIZADO:</h3> <p>          Lo primero que debemos hacer para crear un bloque, usando nuestro propio módulo, es añadir una carpeta con el nombre del módulo, dentro de la carpeta "modules/custom", con el objetivo de tener separados los módulos contribuidos de Drupal, que son los que descargamos desde la Página Oficial, y que si utilizamos Composer, se guardarán automáticamente en la ubicación "modules/contrib"</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 27.23%;" data-ratio="27.23" data-b-token="b-9a0e001d348" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" title="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/imagenes/file-6374fc0c58f61.png?itok=pILGrHhJ" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="650" height="177" typeof="foaf:Image" /></div></div> <p>          Una vez hayamos creado la carpeta con el nombre de nuestro módulo, lo siguiente será añadir el archivo que utiliza Drupal para identificar cualquier módulo, el nombre de este archivo deberá coincidir con el nombre de nuestra carpeta y terminar con la extensión <strong>".info.yml"</strong>, en nuestro caso, nuestro archivo se llamará <strong>drupal_block.info.yml.</strong></p> <p>          Puedes crear el archivo y copiar el siguiente código dentro para continuar con el ejercicio.</p> <pre> name: Drupal Block description: 'Create custom block' package: drupaladicto type: module core_version_requirement: ^8.8.0 || ^9.0</pre> <p>          Puedes comprobar que todo funciona correctamente, si activas el módulo en la url "/admin/modules/". Aunque no hará más nada que confirmarte con un mensaje en la parte superior de la pantalla, indicándote que se ha activado correctamente.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 78%;" data-ratio="78" data-b-token="b-658ec43c552" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" title="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/imagenes/file-6374fc31175c4.jpg?itok=4ItWQCrI" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="409" height="319" typeof="foaf:Image" /></div></div> <p>     Ahora desinstala el módulo nuevamente, antes de continuar con las siguientes modificaciones para evitar errores.</p> <h3>     PASO 2 CREACIÓN DEL BLOQUE PERSONALIZADO:</h3> <p>          Para lograr que nuestro módulo personalizado genere un Bloque, una vez lo hayamos terminado, tendremos que crear varios archivos. </p> <p>          Crearemos tres carpetas: <strong>"src"</strong>, <strong>"Plugin"</strong> y <strong>"Block"</strong>, estas deberán estar una dentro de la otra, respetando los estándares de estructura para que Drupal reconozca su contenido y funcione correctamente.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 53.33%;" data-ratio="53.33" data-b-token="b-1b3cdf20ba2" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" title="Custom Module Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/imagenes/file-6374fc588ec29.png?itok=e0O-RJdP" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="240" height="128" typeof="foaf:Image" /></div></div> <p>          A continuación, crearemos el archivo php con la clase responsable de construir nuestro módulo, es recomendable que el nombre de tu clase corresponda con el de tu módulo, utilizando Mayúsculas en el caso de que lo formen varias palabras. Por lo tanto, para nuestro ejemplo, la clase se llamará <strong>DrupalBlock.php</strong> y tendrá dentro el siguiente contenido:</p> <pre> &lt;?php namespace Drupal\drupal_block\Plugin\Block; use Drupal\Core\Block\BlockBase; /** * @Block( * id = "Drupal Block", * admin_label = @translation("Drupal Block"), * category = @translation("Drupal Block"), * ) */ class DrupalBlock extends BlockBase{ /** * {@inheritdoc } */ public function build(){ return [ '#markup' =&gt; $this-&gt;getFrases(), '#cache' =&gt; [ 'max-age' =&gt; 0, ] ]; } private function getFrases(){ $frase = [ 'Hola, que tal', 'Otras vez por aquí?', 'Nos vemos pronto!!!' ]; return $frase[array_rand($frase)]; } } </pre> <p><strong>     Explicación: </strong></p> <p>          En la primera parte del código, tenemos el <strong>namespace</strong>, que permite a Drupal encontrar la ubicación de nuestro módulo para leer su contenido. A continuación, invocamos a la clase <strong>BlockBase</strong>, porque será necesaria para genera nuestro bloque, ya que heredaremos de ésta algunas funcionalidades, utilizando la palabra <strong>extends</strong>, que utilizaremos dentro de nuestra clase.</p> <pre> &lt;?php namespace Drupal\drupal_block\Plugin\Block; use Drupal\Core\Block\BlockBase;</pre> <p> </p> <p>     La siguiente fracción del código, corresponde a lo que se conoce como <strong>Annotations, </strong>puedes <a href="https://www.drupal.org/docs/drupal-apis/plugin-api/annotations-based-plugins">visitar la Página oficial de Drupal</a> para saber más sobre ellas. En resumen, aunque su formato es similar al de los comentarios de Php, su función va mucho más allás, permitiendo pasar varios parámetros necesarios para que Drupal interprete, en este caso, que se trata de un Bloque personalizado y muestre varias informaciones relacionadas, que podremos ver una vez esté activado el módulo, dentro de la pantalla de Administración de Bloques.</p> <pre> /** * @Block( * id = "Drupal Block", * admin_label = @translation("Drupal Block"), * category = @translation("Drupal Block"), * ) */</pre> <p>     La última parte que nos falta, es el contenido en sí, de nuestra clase. En esencia, lo que estamos haciendo es, construir el bloque, utilizando el método <strong>build(){ }, </strong>que nos devolverá un arreglo o array, con un elemento html que envolverá una frase, además al refrescar el navegador, dicha frase también cambiará aleatoriamente, ya que hemos utilizado el <strong>array_rand() </strong>de php para conseguirlo.</p> <pre> class DrupalBlock extends BlockBase{ /** * {@inheritdoc } */ public function build(){ return [ '#markup' =&gt; $this-&gt;getFrases(), '#cache' =&gt; [ 'max-age' =&gt; 0, ] ]; } private function getFrases(){ $frase = [ 'Hola, que tal', 'Otras vez por aquí?', 'Nos vemos pronto!!!' ]; return $frase[array_rand($frase)]; } }</pre> <p>Si quieres más información sobre los bloques personalizados, puedes visitar la <a href="https://www.drupal.org/docs/creating-custom-modules/creating-custom-blocks/create-a-custom-block" target="_blank">página oficial de Drupal</a></p> </div> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Jue, 09/03/2023 - 09:18</span> Thu, 09 Mar 2023 08:18:03 +0000 webmaster 292 at https://drupaladicto.com Habilita las sugerencias para aplicar plantillas en bloques https://drupaladicto.com/snippet/habilita-las-sugerencias-para-aplicar-plantillas-en-bloques <span class="field field--name-title field--type-string field--label-hidden">Habilita las sugerencias para aplicar plantillas en bloques</span> <div class="clearfix text-formatted field field--name-field-snippet-descripcion field--type-text-long field--label-above"> <div class="field__label">Descripción</div> <div class="field__item"><p>Este código te permite habilitar las sugerencias de nombres para modificar las plantillas de los bloques.</p> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mar, 28/02/2023 - 21:01</span> <div class="clearfix text-formatted field field--name-field-codigo field--type-text-long field--label-hidden field__item"><pre dir="ltr"> /** * Implements template_theme_suggestions_block_alter(). */ function mitema_theme_suggestions_block_alter(&amp;$suggestions, $variables) { $content = $variables['elements']['content']; if (isset($content['#block_content']) &amp;&amp; $content['#block_content'] instanceof \Drupal\block_content\BlockContentInterface) { $suggestions[] = 'block__' . $content['#block_content']-&gt;bundle(); } }</pre> </div> <div class="field field--name-field-snippet-paginador field--type-image field--label-above"> <div class="field__label">Paginador</div> <div class="field__item"> <img src="/sites/default/files/imagenes/snippets/snippet-pager_40.png" width="100" height="100" alt="Snippet | www.drupaladicto.com - Consultores especializados en Drupal y Symfony" title="Snippet | www.drupaladicto.com - Consultores especializados en Drupal y Symfony" loading="lazy" typeof="foaf:Image" class="img-fluid" /> </div> </div> <div class="field field--name-field-categoria-snippet field--type-entity-reference field--label-above"> <div class="field__label">Categoría</div> <div class="field__items"> <div class="field__item"><a href="/categoria/twig" hreflang="es">twig</a></div> <div class="field__item"><a href="/categoria/twig-template" hreflang="es">twig template</a></div> <div class="field__item"><a href="/categoria/block" hreflang="es">block</a></div> <div class="field__item"><a href="/categoria/custom-block" hreflang="es">custom block</a></div> <div class="field__item"><a href="/categoria/custom-theme" hreflang="es">custom theme</a></div> <div class="field__item"><a href="/categoria/subtheme" hreflang="es">subtheme</a></div> <div class="field__item"><a href="/categoria/themes" hreflang="es">themes</a></div> <div class="field__item"><a href="/categoria/plantillas" hreflang="es">plantillas</a></div> <div class="field__item"><a href="/categoria/hook" hreflang="es">hook</a></div> </div> </div> <div class="field field--name-field-portada-snippet field--type-entity-reference field--label-above"> <div class="field__label">Portada</div> <div class="field__item"><article class="media media--type-imagen media--view-mode-default"> </article> </div> </div> Tue, 28 Feb 2023 20:01:24 +0000 webmaster 65 at https://drupaladicto.com Mostrar bloque vista usando Preprocess Function Drupal 8/9 https://drupaladicto.com/snippet/mostrar-bloque-vista-usando-preprocess-function-drupal-89 <span class="field field--name-title field--type-string field--label-hidden">Mostrar bloque vista usando Preprocess Function Drupal 8/9</span> <div class="clearfix text-formatted field field--name-field-snippet-descripcion field--type-text-long field--label-above"> <div class="field__label">Descripción</div> <div class="field__item"><p>Este código te permitirá mostrar una vista tipo bloque en un nodo o paragraphs</p> <p>Para Nodos:<br /> /** * Implements hook_preprocess_node() for node.html.twig. */<br /> function TUSUBTHEME_preprocess_node(array &amp;$variables) {<br />   $variables['nombre_variable_para_mostrar'] = views_embed_view('nombre_maquina', 'nombre_vista_dentro');</p> <p>}</p> <p>Para Paragraphs</p> <p>/* Implement hook_preprocess_paragraph() */<br /> function wct_oct2020_preprocess_paragraph(&amp;$variables) {<br />   $variables['nombre_variable_para_mostrar'] = views_embed_view('nombre_maquina', 'nombre_vista_dentro');</p> <p>}</p> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mar, 28/02/2023 - 20:41</span> <div class="clearfix text-formatted field field--name-field-instrucciones field--type-text-long field--label-above"> <div class="field__label">Instrucciones</div> <div class="field__item"><p>Para mostrar una vista tipo bloque en usando Preprocess Function:</p> <ol><li>Abre el archivo TUSUBTHEME.theme para añadir las Preprocess function según necesites, copia el código que está debajo dependiendo de si la usarás para presentarla en un nodo o en un elemento Paragraphs.<br />  </li> <li>Crea una plantilla para el tipo de contenido donde quieres mostrar la vista, conoce el nombre para la plantilla activando el modo depurador.<br />  </li> <li>Añade la el nombre de la variable en la plantilla, en el lugar donde quieres imprimir la vista:<br /><br /> {{ nombre_variable_para_mostrar }}<br />  </li> <li>Refrescar cache</li> </ol></div> </div> <div class="clearfix text-formatted field field--name-field-codigo field--type-text-long field--label-hidden field__item"><pre> /** * Implements hook_preprocess_node() for node.html.twig. */ function TUSUBTHEME_preprocess_node(array &amp;$variables) { $variables['nombre_variable_para_mostrar'] = views_embed_view('nombre_maquina', 'nombre_vista_dentro'); } /* Implement hook_preprocess_paragraph() */ function wct_oct2020_preprocess_paragraph(&amp;$variables) { $variables['nombre_variable_para_mostrar'] = views_embed_view('nombre_maquina', 'nombre_vista_dentro'); }</pre> </div> <div class="field field--name-field-snippet-paginador field--type-image field--label-above"> <div class="field__label">Paginador</div> <div class="field__item"> <img src="/sites/default/files/imagenes/snippets/snippet-pager_27.png" width="100" height="100" alt="Snippet | www.drupaladicto.com - Consultores especializados en Drupal y Symfony" title="Snippet | www.drupaladicto.com - Consultores especializados en Drupal y Symfony" loading="lazy" typeof="foaf:Image" class="img-fluid" /> </div> </div> <div class="field field--name-field-categoria-snippet field--type-entity-reference field--label-above"> <div class="field__label">Categoría</div> <div class="field__items"> <div class="field__item"><a href="/categoria/block" hreflang="es">block</a></div> <div class="field__item"><a href="/categoria/custom-block" hreflang="es">custom block</a></div> <div class="field__item"><a href="/categoria/bloque-personalizado" hreflang="es">bloque personalizado</a></div> <div class="field__item"><a href="/categoria/hook" hreflang="es">hook</a></div> <div class="field__item"><a href="/categoria/preprocess-function" hreflang="es">preprocess function</a></div> <div class="field__item"><a href="/categoria/subtheme" hreflang="es">subtheme</a></div> <div class="field__item"><a href="/categoria/subtema" hreflang="es">subtema</a></div> <div class="field__item"><a href="/categoria/tema-personalizado" hreflang="es">tema personalizado</a></div> <div class="field__item"><a href="/categoria/alter" hreflang="es">alter</a></div> <div class="field__item"><a href="/categoria/hooks" hreflang="es">hooks</a></div> </div> </div> <div class="field field--name-field-portada-snippet field--type-entity-reference field--label-above"> <div class="field__label">Portada</div> <div class="field__item"><article class="media media--type-imagen media--view-mode-default"> </article> </div> </div> Tue, 28 Feb 2023 19:41:28 +0000 webmaster 52 at https://drupaladicto.com Pros y contras de utilizar en Drupal Blocks y/o Paragraphs https://drupaladicto.com/actualidad/pros-y-contras-de-utilizar-en-drupal-blocks-yo-paragraphs <span class="field field--name-title field--type-string field--label-hidden">Pros y contras de utilizar en Drupal Blocks y/o Paragraphs</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Dom, 26/02/2023 - 16:34</span> <div class="field field--name-field-contenidos-post field--type-entity-reference-revisions field--label-visually_hidden"> <div class="field__label visually-hidden">Contenidos</div> <div class="field__items"> <div class="field__item"> <div class="paragraph paragraph--type--text-only paragraph--view-mode--default" id="txonly-1142" style="background-color: ;border: solid px;border-color: #096ba0;border-radius: 5px;padding: 10px;"> <div class="clearfix text-formatted field field--name-to-text field--type-text-long field--label-visually_hidden"> <div class="field__label visually-hidden">Texto</div> <div class="field__item"><p>     Si te consideras como yo, uno de los apasionados por utilizar Drupal, o estás a punto de comenzar a probar las versiones más actuales, en las que se implementaron grandes cambios, como la estructura a partir del Framework Symfony, o la integración en el núcleo, de varios módulos que en versiones anteriores a Drupal8, debían descargarse manualmente, es posible que te haya saltado una duda razonable, ¿cuál sería la mejor manera de comenzar a diseñar tu proyecto web?.</p> <p>     Debido a la gran cantidad de opciones disponibles en este CMS, a veces podría resultar abrumador encontrar las primeras indicaciones, que te permitan comenzar poco a poco a experimentar, las mejores alternativas, para lograr una web fácil de mantener, actualizar y con diseño sea flexible y adaptado a cualquier dispositivo.</p> <h2>   ¿Qué es mejor de utilizar en Drupal Blocks o Paragraphs?</h2> <p>        Todos los que hemos trabajado en las versiones 6 o 7 de Drupal, pudimos conocer o experimentar, en algún momento, con el uso de los bloques, para aplicarlo sobretodo en la página principal, ya que nos permitía dividir en zonas, cualquier página y a su vez añadir contenidos referenciados, a través del uso del campos especiales o vistas.</p> <p>        A partir de la versión 8, además de la implementación en entidades, se añadió el módulo que marcó para siempre, según mi punto de vista, la forma en que podríamos construir una web más versátil, tanto de cara a los administradores, o gestorese de contenidos, como al usuario final. Me refiero a los Paragraphs; que añadieron múltiples maneras de manipulación de los contenidos, además de ofrecer un sustituyo mucho más potente, que el fieldgroup o los bloques convencionales.</p> <p>       No obstante, cada proyecto tiene sus propias necesidades y es decisión nuestra implementar, las mejores alternativas, para sacar provecho a cualquiera de las opciones con las que disponemos.</p> <p>      </p> <table border="1" cellpadding="1" cellspacing="1"><caption>Comparativa entre Bloques y Paragraphs</caption> <thead><tr><th scope="col">OPCIONES DISPONIBLES</th> <th scope="col">BLOQUES</th> <th scope="col">PARAGRAPHS</th> </tr></thead><tbody><tr><td>Uso de campos referenciados (apuntandos a vistas, otros contenidos, imágenes, etc)</td> <td>SI</td> <td>SI</td> </tr><tr><td>Capacidad de integración dentro de Páginas y/o Tipos de contenido</td> <td>NO</td> <td>SI</td> </tr><tr><td>Plantillas idependientes</td> <td>SI</td> <td>SI</td> </tr><tr><td>Capacidad de edición en línea</td> <td>SI</td> <td>SI (Módulo Geysir)</td> </tr><tr><td>Control de acceso por permisos y roles</td> <td>SI</td> <td>SI</td> </tr><tr><td>Reutilizable</td> <td>SI</td> <td>SI</td> </tr></tbody></table><h2>     Ejemplo práctico (Web básica) con Paragraphs</h2> <p>          Supongamos que los requerimientos fundamentales de nuestro proyecto serán, una página de inicio y varias páginas interiores, como por ejemplo, Conctacto, Quienes somos, Blog y/o Listado de productos. Además en la página principal, tendremos varios elementos: un carrusel con las promociones, un pequeño resumen sobre lo que hace nuestra empresa, otro apartado con los productos o servicios destacados, una galería de imágenes y un formulario. Y para nuestras páginas interiores, tendremos una imagen de cabecera, con algún texto descriptivo del contenido, un título principal, y algunos textos, imágenes o formulario de contacto, cuyos contenidos variarán según la página, compartiendo el mismo diseño de cabecera y estructura general.</p> <p>          Podríamos crear o configurar dos tipos de contenido principales, uno llamado "pagina_inicio", al que añadiríamos un sólo campo llamado, del tipo paragraphs, por ejemplo "contenidos", y dentro tendríamos varios paragraph, que a su vez apuntaran a todos los contenidos que pensamos mostrar.De esta forma, la página principal sería muy sencilla de personalizar y actualizar sin necesidad de grandes conocimientos ni experiencia previa.</p> <p>          Puedes visitar <a href="https://demo.webcontodo.com/">https://demo.webcontodo.com/</a> para ver cómo queda.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 178.66%;" data-ratio="178.66" data-b-token="b-f3093b77672" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img class="img-fluid media__element b-lazy b-filter" data-entity-uuid="70181c70-8271-4eb4-858e-019a4ced5653" data-responsive-image-style="" alt="paragraphs - www.drupaladicto.org Formacion especializada en drupal y symfony" decoding="async" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/explicacion_inicio.png?itok=dW1WrifF" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="389" height="695" typeof="foaf:Image" /></div></div> <p>    En el caso de la páginas interiores, como compartirán la cabecera, los títulares principales, y envolveremos el resto de elementos dentro de algún contenedor, tipo bootstrap, para garantizar un diseño responsivo; el enfoque sería parecido al anterior, con algunas variaciones y podríamos reaprovechar algunos de los paragraphs, para no tener que crear nuevas plantillas individuales en cada caso.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 178.66%;" data-ratio="178.66" data-b-token="b-e5ad3e8494d" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img class="img-fluid media__element b-lazy b-filter" data-entity-uuid="e0797b59-3350-4e9b-b1aa-ae00ac7372ff" data-responsive-image-style="" alt="paragraphs - www.drupaladicto.org Formacion especializada en drupal y symfony" decoding="async" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/pagina_interior_contacto.png?itok=xdLHbu4e" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="389" height="695" typeof="foaf:Image" /></div></div> <p>     En resumen, con este planteamiento, podríamos ofrecer la posibilidad de personalizar rápidamente todas las páginas de la web, cambiando de orden los elementos, añadiendo o removiendo elementos existentes, creando estructura que podrían llegar a ser bastante complejas, dependiendo de las necesidades y todo sin la necesidad de invertir demasiado tiempo en la aplicación de correcciones o definición de los estilos, ya que casi todo el contenido mostrado sería reutilizable, escalable como proyecto y fácil de aplicar, incluso en entornos diferentes con algunos cambios.</p> <p>     Aunque el uso de los bloques tradiciones nos permite un resultado parecido para nuestra página de inicio, tiene la desventaja de no formar parte de la página como tal, sino que tendríamos que modificarla desde su propia página de configuración en la url "estructura/diseño de bloques", esto no resulta nada práctico para el gestor de contenidos, además de que puede crear mucha confusión al tener que cambiar de pantallas para comprobar los resultados. </p> <p>     Además, con respecto a las páginas interiores, aunque pudiéramos poner un bloque "Cabecera", que apareciera en todas las páginas interiores, tampoco sería parte de su estructura, tendríamos que añadir una nueva cabecera por cada una de las páginas, volviendo al problema principal que es la configuración fuera de nuestro contenido.</p> <p>     Como dije al principio, Drupal nos ofrece múltiples maneras de enfocar nuestros proyectos, y es decisión nuestra aplicar la que mejor nos convenga. Los bloques también ofrecen la novedad de "Bloques personalizados", que podrían resolver algunas de los inconvenientes con respecto a los tradicionales, pero en definitiva, considero que será mucho más práctico el uso de paragraphs para implementar en cualquier proyecto.</p> <p>     Si tomamos en cuenta, la posibilidad de crear módulos personalizados, para cada tipo de paragrahps, signficaría que en cada proyecto nuevo podríamos simplemente instalar dichos módulos y realizar unos cambios mínimos de configuración y tendríamos un resultado cuyas prestaciones nos ahorrarían muchos dolores de cabeza.</p> </div> </div> </div> </div> </div> </div> <div class="field field--name-field-categoria-post field--type-entity-reference field--label-above"> <div class="field__label">Categoría</div> <div class="field__items"> <div class="field__item"><a href="/categoria/backend" hreflang="es">backend</a></div> <div class="field__item"><a href="/categoria/paragraphs" hreflang="es">paragraphs</a></div> <div class="field__item"><a href="/categoria/block" hreflang="es">block</a></div> <div class="field__item"><a href="/categoria/custom-block" hreflang="es">custom block</a></div> <div class="field__item"><a href="/categoria/apariencia" hreflang="es">apariencia</a></div> <div class="field__item"><a href="/categoria/database" hreflang="es">database</a></div> <div class="field__item"><a href="/categoria/base-de-datos" hreflang="es">base de datos</a></div> </div> </div> Sun, 26 Feb 2023 15:34:55 +0000 webmaster 19 at https://drupaladicto.com