<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Códice | Entradas sobre «portfolio»</title><description>Feed RSS de publicaciones etiquetadas con portfolio</description><link>https://javguerra.github.io/</link><item><title>Conceptos Full Stack Web Developer</title><link>https://javguerra.github.io/blog/conceptos-fswd</link><guid isPermaLink="true">https://javguerra.github.io/blog/conceptos-fswd</guid><description>Ejemplo de maquetación HTML y CSS</description><pubDate>Sat, 23 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/conceptos-fswd.CgRI9xye_Zl0Fl1.webp&quot; alt=&quot;Conceptos full stack&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Maquetación elaborada con HTML 5, CSS 3 y JavaScript Vanilla que incluye formulario y es accesible y responsive.&lt;/p&gt;
&lt;h2 id=&quot;conceptos-fswd&quot;&gt;Conceptos FSWD&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Práctica final del Ramp-up del Bootcamp de FSWD&lt;/strong&gt;&lt;br&gt;
Repositorio en GitHub: &lt;a href=&quot;https://github.com/JavGuerra/conceptos-fswd&quot;&gt;JavGuerra / conceptos-fswd&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;la-página&quot;&gt;La página&lt;/h3&gt;
&lt;p&gt;Esta página corresponde a la práctica final del ramp-up del &lt;a href=&quot;/blog/beca-santander-fswd&quot;&gt;bootcamp sobre Full Stack Web Developer&lt;/a&gt; que estoy realizando en este momento.&lt;/p&gt;
&lt;p&gt;En ella se muestran algunos conceptos aprendidos en esta primera fase, e incluye «algo más» de mi propia cosecha. A continuación algunas de estas mejoras.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/conceptos-fswd/index.html&quot;&gt;&lt;button&gt;Acceder a la página web&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;14-características-destacables-de-esta-página-web&quot;&gt;14 características destacables de esta página web&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CSS transpilado con &lt;a href=&quot;https://es.wikipedia.org/wiki/Sass&quot;&gt;Sass&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Usa Vanilla JS (JavaScript puro).&lt;/li&gt;
&lt;li&gt;La web implementa los criterios del estándar XHTML (revisado con &lt;a href=&quot;https://html5.validator.nu/&quot;&gt;Nu Html Checker&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;El diseño es adaptable (&lt;a href=&quot;https://es.wikipedia.org/wiki/Dise%C3%B1o_web_adaptable&quot;&gt;&lt;em&gt;responsive&lt;/em&gt;&lt;/a&gt;) según el dispositivo.&lt;/li&gt;
&lt;li&gt;Usa la librería y los iconos de &lt;a href=&quot;https://icons.getbootstrap.com/&quot;&gt;Bootstrap Icons&lt;/a&gt; y las fuentes de letra de &lt;a href=&quot;https://fonts.google.com/&quot;&gt;Google Fonts&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Aplica un &lt;a href=&quot;https://blog.hubspot.es/marketing/efecto-parallax&quot;&gt;efecto Paralax&lt;/a&gt; a la portada (&lt;em&gt;hero&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Implementa el protocolo &lt;a href=&quot;https://ogp.me/&quot;&gt;Open Graph&lt;/a&gt; (&lt;em&gt;head&lt;/em&gt;) para la correcta inserción de la web en redes sociales.&lt;/li&gt;
&lt;li&gt;Es compatible con &lt;em&gt;Progessive Web Aplication&lt;/em&gt; (&lt;a href=&quot;https://developer.mozilla.org/es/docs/Web/Progressive_web_apps&quot;&gt;PWA&lt;/a&gt;) a través de fichero &lt;a href=&quot;https://developer.mozilla.org/es/docs/Web/Manifest&quot;&gt;manifest.json&lt;/a&gt;, por lo que la página puede ser instalada en dispositivos móviles como una web app.&lt;/li&gt;
&lt;li&gt;Implementa técnicas de seguridad en el formulario:
&lt;ul&gt;
&lt;li&gt;Hace uso de un &lt;a href=&quot;https://es.wikipedia.org/wiki/Honeypot&quot;&gt;&lt;em&gt;Honeypod&lt;/em&gt;&lt;/a&gt;, mediante el campo “hp”, para evitar el SPAM.&lt;/li&gt;
&lt;li&gt;Hace uso de un campo oculto “dato” para evitar ataques por &lt;a href=&quot;https://es.wikipedia.org/wiki/Cross-site_scripting&quot;&gt;XSS&lt;/a&gt; y &lt;a href=&quot;https://es.wikipedia.org/wiki/Cross-site_request_forgery&quot;&gt;CRSF&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Es accesible (revisado con el complemento &lt;a href=&quot;https://wave.webaim.org/&quot;&gt;WAVE&lt;/a&gt;):
&lt;ul&gt;
&lt;li&gt;Emplea párrafos y etiquetas contextuales sólo visibles para lectores de pantalla.&lt;/li&gt;
&lt;li&gt;Hace uso de etiquetas &lt;a href=&quot;https://en.wikipedia.org/wiki/WAI-ARIA&quot;&gt;WAI-ARIA&lt;/a&gt; para describir eventos interactivos.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;El fichero README.md tiene sintáxis de marcado ligero &lt;a href=&quot;https://es.wikipedia.org/wiki/Markdown&quot;&gt;Markdown&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Dispone de un código QR para acceso rápido a la web a través de dispositivos móviles.&lt;/li&gt;
&lt;li&gt;Ha sido probado en los navegadores web &lt;strong&gt;Firefox&lt;/strong&gt; y &lt;strong&gt;Chrome&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Web alojada en &lt;a href=&quot;https://github.com/JavGuerra/conceptos-fswd&quot;&gt;Github&lt;/a&gt; pages.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;acceder-a-la-página-web&quot;&gt;Acceder a la página web&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/conceptos-fswd/img/qrcode.svg&quot; alt=&quot;icono&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/conceptos-fswd/index.html&quot;&gt;&lt;button&gt;Ir a la página web&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/conceptos-fswd.CgRI9xye_Zl0Fl1.webp"/><category>portfolio</category><category>web</category><category>código</category><category>html</category><category>css</category><category>javascript</category><author>JavGuerra</author></item><item><title>Buscaminas en JavaScript</title><link>https://javguerra.github.io/blog/buscaminas</link><guid isPermaLink="true">https://javguerra.github.io/blog/buscaminas</guid><description>Pequeño juego online para manejo de eventos</description><pubDate>Thu, 28 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/buscaminas.BEDLb0fd_265uBE.webp&quot; alt=&quot;Buscaminas&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#bootstrap&lt;/em&gt;, &lt;em&gt;#jquery&lt;/em&gt;, &lt;em&gt;#juego&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Programé &lt;a href=&quot;https://javguerra.github.io/BuscaminasJS/index.html&quot;&gt;Buscaminas en JavaScript&lt;/a&gt; como un juego atípico que no consiste en evitar las minas, como estamos acostumbrados en los juegos de escritorio del mismo nombre, sino en hacerlas estallar.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/BuscaminasJS/index.html&quot;&gt;&lt;button&gt;Jugar a Buscaminas&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Una vez se genera el tablero con las dimensiones que deseemos, tendremos una serie de intentos para acertar la posición de las minas. Cada fallo cuenta, así como cada acierto. Termina la partida cuando se han superado el número de fallos posibles o cuando se encuentran todas las minas.&lt;/p&gt;
&lt;p&gt;Realicé este juego durante una semana, como práctica de programación de la asignatura de Desarrollo Web en Entorno Cliente de Formación Profesional de Grado Superior de Desarrollo de Aplicaciones Web (DAW).&lt;/p&gt;
&lt;p&gt;La aplicación, programada en JavaScript, usa Bootstrap y JQuery, es &lt;em&gt;cross-browser&lt;/em&gt; y compatible con navegadores antiguos, tiene diseño &lt;em&gt;responsive&lt;/em&gt;, cumple con los estándares W3C, de accesibilidad web y de accesibilidad de contenidos dinámicos (WAI-ARIA).&lt;/p&gt;
&lt;p&gt;Como ejercicio de programación, es un buen ejemplo de manejo de eventos en JavaScript para interactuar con las casillas del tablero.&lt;/p&gt;
&lt;h2 id=&quot;te-apetece-una-partidita&quot;&gt;¿Te apetece una partidita?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/BuscaminasJS/index.html&quot;&gt;&lt;button&gt;Jugar a Buscaminas&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/JavGuerra/BuscaminasJS&quot;&gt;Ver el codigo fuente en Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;PS.: La ayuda depara alguna sorpresa… pero intenta jugar sin hacer trampa.&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/buscaminas.BEDLb0fd_265uBE.webp"/><category>portfolio</category><category>web</category><category>código</category><category>css</category><category>html</category><category>javascript</category><category>bootstrap</category><category>jquery</category><category>juego</category><author>JavGuerra</author></item><item><title>Carousel con Bootstrap</title><link>https://javguerra.github.io/blog/galeria-carousel</link><guid isPermaLink="true">https://javguerra.github.io/blog/galeria-carousel</guid><description>Una pequeña galería de fotos de ejemplo</description><pubDate>Fri, 29 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/galeria-vnzla.-8Rqrg6B_Z1gNkrA.webp&quot; alt=&quot;Galería Venezuela&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#viaje&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#bootstrap&lt;/em&gt;, &lt;em&gt;#fotografía&lt;/em&gt;, &lt;em&gt;#edición&lt;/em&gt;, &lt;em&gt;#venezuela&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Las primeras veces que viajé a Venezuela quedé impactado por su belleza y las gentes que allí conocí. Me inspiró para realizar esta &lt;a href=&quot;https://badared.com/javguerra/daw/galeria/&quot;&gt;galería de fotos&lt;/a&gt; de ejemplo para la asignatura de Diseño de Interfaces Web de Formación Profesional de Grado Superior de Desarrollo de Aplicaciones Web (DAW).&lt;/p&gt;
&lt;p&gt;La galería muestra un carousel de imágenes con Boortrap y JavaScript, es &lt;em&gt;responsive&lt;/em&gt; y cumple con los estándares web y de accesibilidad.&lt;/p&gt;
&lt;p&gt;Es un buen ejercicio para mostrar las posibilidades del diseño web con HTML y CSS.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://badared.com/javguerra/daw/galeria/&quot;&gt;&lt;button&gt;visita la galería de fotos&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La foto de esta entrada es un montaje que realicé con Gimp tomando como base las tres fotos de la galería componiendo con ellas un collage y aplicando filtros de envejecido.&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/galeria-vnzla.-8Rqrg6B_Z1gNkrA.webp"/><category>portfolio</category><category>web</category><category>viaje</category><category>código</category><category>css</category><category>html</category><category>javascript</category><category>bootstrap</category><category>fotografía</category><category>edición</category><category>venezuela</category><author>JavGuerra</author></item><item><title>Summer Quiz</title><link>https://javguerra.github.io/blog/summer-quiz</link><guid isPermaLink="true">https://javguerra.github.io/blog/summer-quiz</guid><description>Un juego que obtiene sus preguntas a través de una API</description><pubDate>Tue, 21 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/summer-quiz.CeOcInKG_1DP5P4.webp&quot; alt=&quot;Summer Quiz&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#juego&lt;/em&gt;, &lt;em&gt;#accesibilidad&lt;/em&gt;, &lt;em&gt;#responsive&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;«Fun 10-question quiz to test your knowledge». &lt;strong&gt;Práctica final del módulo de JavaScript avanzado del Bootcamp de FSWD&lt;/strong&gt;, por Alejandro Rodríguez y Javier Guerra.&lt;/p&gt;
&lt;h1 id=&quot;el-juego&quot;&gt;El juego&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/summer-quiz/&quot;&gt;&lt;button&gt;Acceder al juego&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El &lt;a href=&quot;/blog/beca-santander-fswd&quot;&gt;bootcamp de FSWD&lt;/a&gt; que estoy realizando, consta de varios módulos. El de JavaScript avanzado termina ahora, y este es el ejercicio final de esta fase de mi formación.&lt;/p&gt;
&lt;p&gt;Se trata de un ejercicio que comprende todos los conceptos generales aprendidos, y que, como siempre, incluye alguna que otra cosa más allá del enunciado.&lt;/p&gt;
&lt;h1 id=&quot;enunciado&quot;&gt;Enunciado&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;El ejercicio consiste en elaborar una SPA que consulte una API de preguntas y respuestas y que cuente con tres partes: 1. bienvenida y gráficas de estadísticas, 2. mostrar diez preguntas, una a una, con sus respectivas opciones de respuesta, y 3. página de resultado.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Conceptualmente hablando, las estadísticas de la parte 1 bien podrían aparecer en la fase 3, la de resultados, pero este es, en resumidas cuentas, el enunciado.&lt;/p&gt;
&lt;p&gt;Algunas características destacables del enunciado son que la aplicación se debe ejecutar en una sola página web (SPA), que realiza consultas a una API, que guarda las puntuaciones en localStorage y que muestra estadísticas. Esta última parte, aunque accesoria, pues no se ha visto en el bootcamp, supuso un reto interesante, ya que ha dado para escribir varias entradas previas en este blog: &lt;a href=&quot;/blog/spinner-loader-asincrono&quot;&gt;Spinner loader asíncrono&lt;/a&gt;, &lt;a href=&quot;/blog/contador-resultados&quot;&gt;Creación de un contador de resultados&lt;/a&gt;, &lt;a href=&quot;/blog/grafica-lineas&quot;&gt;Gráfica de lineas dinámica con SVG&lt;/a&gt; y &lt;a href=&quot;/blog/carga-svg&quot;&gt;Cargar SVG dinámicamente&lt;/a&gt;, todas ellas técnicas incluidas en el ejercicio.&lt;/p&gt;
&lt;p&gt;Es un buen ejercicio para practicar, e igualmente espero que puedas disfrutarlo jugándolo. Este ejercicio lo he llevado a cabo con el apoyo del compañero Alejando.&lt;/p&gt;
&lt;h1 id=&quot;características-destacables&quot;&gt;Características destacables&lt;/h1&gt;
&lt;h2 id=&quot;operativa-de-la-aplicación&quot;&gt;Operativa de la aplicación&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Aplicación de una sola página (SPA).&lt;/li&gt;
&lt;li&gt;Integración de 25 preguntas propias en un JSON. Usa una en cada partida.&lt;/li&gt;
&lt;li&gt;Hace uso de localStorage pata guardar y leer las puntuaciones.&lt;/li&gt;
&lt;li&gt;Gráficas dinámicas en SVG de elaboración propia y uso de DOM para su gestión.
&lt;ul&gt;
&lt;li&gt;Gráfica de líneas para mostrar estadísticas. Manejo del id ‘theline’.&lt;/li&gt;
&lt;li&gt;Contador visual para mostrar el resultado final del quiz. Manejo del id ‘hand’.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Animaciones CSS de gráfica de líneas y personajes.&lt;/li&gt;
&lt;li&gt;Carga de las gráficas &lt;strong&gt;SVG&lt;/strong&gt; al inicio de la app con &lt;code&gt;fetch&lt;/code&gt; para hacer uso de los &lt;code&gt;id&lt;/code&gt; que incorporan y poder así hacer cambios dinámicos. Con &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; esto no funcionaría.&lt;/li&gt;
&lt;li&gt;Los posibles errores se muestran a través de una ventana modal &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Usa JavaScript puro (Vanilla JS) sin &lt;em&gt;frameworks&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Recopila librería de funciones propia en el fichero &lt;code&gt;js/functions.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Repositorio compartido en Github y web alojada en Github pages.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;usabilidad&quot;&gt;Usabilidad&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;La web implementa los criterios del estándar XHTML (revisado con &lt;a href=&quot;https://html5.validator.nu/&quot;&gt;Nu Html Checker&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;El diseño es adaptable (&lt;em&gt;responsive&lt;/em&gt;) según el dispositivo.&lt;/li&gt;
&lt;li&gt;Es accesible (revisado con el complemento del navegador &lt;a href=&quot;https://wave.webaim.org/&quot;&gt;WAVE&lt;/a&gt;):
&lt;ul&gt;
&lt;li&gt;Hace uso de etiquetas &lt;strong&gt;WAI-ARIA&lt;/strong&gt; para describir eventos interactivos.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tiene temática coherente y un cuidado aspecto visual trabajado con CSS.&lt;/li&gt;
&lt;li&gt;Interfaz en inglés acorde al contenido de la API.&lt;/li&gt;
&lt;li&gt;Emplea un ‘spin’ asíncrono para informar al usuario de que se está gestionado la consultas.&lt;/li&gt;
&lt;li&gt;Los botones no se activan hasta que terminan los procesos asíncronos: cargas, consultas…&lt;/li&gt;
&lt;li&gt;La selección de las opciones de cada pregunta se hace a través de botones de radio cuyo aspecto modificado con CSS simula el aspecto de botones de selección.&lt;/li&gt;
&lt;li&gt;Muestra barra de puntuaciones medias y barra de progreso del cuestionario.&lt;/li&gt;
&lt;li&gt;Implementa el protocolo &lt;a href=&quot;https://ogp.me/&quot;&gt;&lt;em&gt;Open Graph&lt;/em&gt;&lt;/a&gt; (en el &lt;code&gt;head&lt;/code&gt;) para la correcta inserción de la web en RRSS.&lt;/li&gt;
&lt;li&gt;Es compatible con &lt;em&gt;Progessive Web Aplication&lt;/em&gt; (PWA) a través de fichero manifest.json, por lo que la página puede ser instalada en dispositivos móviles como una web app.&lt;/li&gt;
&lt;li&gt;Se dispone de un código QR para acceso rápido a la web a través de dispositivos móviles.&lt;/li&gt;
&lt;li&gt;Ha sido probada con los navegadores web Firefox y Chrome.&lt;/li&gt;
&lt;li&gt;Extra: La consola del navegador muestra ayuda con las respuestas.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/summer-quiz/assets/img/qrcode.svg&quot; alt=&quot;QR Code&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/summer-quiz/&quot;&gt;&lt;button&gt;Acceder al juego&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/summer-quiz&quot;&gt;Repositorio / Codigo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/spinner-loader-asincrono&quot;&gt;Spinner loader asíncrono&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/contador-resultados&quot;&gt;Creación de un contador de resultados&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/grafica-lineas&quot;&gt;Gráfica de lineas dinámica con SVG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/carga-svg&quot;&gt;Cargar SVG dinámicamente&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/summer-quiz.CeOcInKG_1DP5P4.webp"/><category>portfolio</category><category>web</category><category>código</category><category>html</category><category>css</category><category>javascript</category><category>juego</category><category>accesibilidad</category><category>responsive</category><author>JavGuerra</author></item><item><title>Tienda 8 bits</title><link>https://javguerra.github.io/blog/tienda-8-bits</link><guid isPermaLink="true">https://javguerra.github.io/blog/tienda-8-bits</guid><description>Proyecto de graduación del Bootcamp Full Stack Web Developer</description><pubDate>Fri, 18 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/tienda-8-bits.BGpB2fQx_Znqyrs.webp&quot; alt=&quot;Banner tienda 8 bits&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#formación&lt;/em&gt;, &lt;em&gt;#becas&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#express&lt;/em&gt;, &lt;em&gt;#react&lt;/em&gt;, &lt;em&gt;#mongodb&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#accesibilidad&lt;/em&gt;, &lt;em&gt;#responsive&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Durante el año 2022 cursé el &lt;a href=&quot;/blog/beca-santander-fswd&quot;&gt;Bootcamp de Desarrollo Web Full Stack&lt;/a&gt; que &lt;a href=&quot;https://www.becas-santander.com/es/index.html&quot;&gt;Becas Santander&lt;/a&gt; llevó a cabo en colaboración con &lt;a href=&quot;https://www.universia.net/es/empleo&quot;&gt;Fundación Universia&lt;/a&gt;, &lt;a href=&quot;https://www.indracompany.com/&quot;&gt;Indra&lt;/a&gt; y &lt;a href=&quot;https://www.thebridge.tech/&quot;&gt;The Bridge&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.badared.com/proyecto/tienda8bits/&quot;&gt;&lt;button&gt;Ir a la aplicación on-line&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El día 17 de noviembre finalizó la formación con un acto de entrega de diplomas on-line en el que tuve ocasión de mostrar mi proyecto final «Tienda 8 bits» junto con Alex, otro de mis compañeros, quien también expuso su proyecto.&lt;/p&gt;
&lt;p&gt;A parte de los compañeros y los profesores, asistieron al evento Alejandra Cuenca y Diego Díaz por parte de The Bridge, Cristina Soriano por Minsait/Indra, y Beatriz Arribas y Carlos Sánchez por Universia.&lt;/p&gt;
&lt;h2 id=&quot;video&quot;&gt;Video&lt;/h2&gt;
&lt;p&gt;El evento se llevó a cabo de forma presencial y on-line, y de él he rescatado el video de mi presentación que comparto a continuación.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Video de presentación&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/tienda.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/XlswjqhxJZ8&quot;&gt;&lt;button&gt;Ver el video en YouTube&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;descripción-técnica&quot;&gt;Descripción técnica&lt;/h2&gt;
&lt;h3 id=&quot;back-end&quot;&gt;Back end&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Tecnologías empleadas&lt;/strong&gt;: Node.js + Express + MongoDB + Mongoose&lt;br&gt;
&lt;strong&gt;Módulos&lt;/strong&gt;: compression, cors, helmet, dotenv, nodemon, mongoose-paginator-v2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Características destacadas de la API&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Emplea módulos ESM.&lt;/li&gt;
&lt;li&gt;Está preparada para el versionado de la API.&lt;/li&gt;
&lt;li&gt;Está preparada para el uso de BBDD MongoDB local o en remoto (config.js).&lt;/li&gt;
&lt;li&gt;Preserva la seguridad del acceso a la API con el uso del módulo helmet.&lt;/li&gt;
&lt;li&gt;Devuelve las rutas de los enlaces a las fotos y logos dinámicamente.&lt;/li&gt;
&lt;li&gt;Cuenta con documentación de la API.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;front-end&quot;&gt;Front end&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Tecnologías empleadas&lt;/strong&gt;: React + Vite, axios, react-router-dom, react-hook-form&lt;br&gt;
&lt;strong&gt;Módulos propios&lt;/strong&gt;: setSpin, inactiveBtn, compareTwoObjects&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Características destacadas de la App&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El diseño es adaptable (responsive) según el dispositivo.&lt;/li&gt;
&lt;li&gt;CSS propio. No usa frameworks.&lt;/li&gt;
&lt;li&gt;Es accesible (revisado con el complemento &lt;a href=&quot;https://wave.webaim.org/&quot;&gt;WAVE&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Utiliza fuentes de Google Font en los títulos para preservar la accesibilidad.&lt;/li&gt;
&lt;li&gt;Implementa el protocolo &lt;a href=&quot;https://ogp.me/&quot;&gt;Open Graph&lt;/a&gt; para la correcta inserción de la web en RRSS.&lt;/li&gt;
&lt;li&gt;Es compatible con Progessive Web Aplication (&lt;a href=&quot;https://developer.mozilla.org/es/docs/Web/Progressive_web_apps&quot;&gt;PWA&lt;/a&gt;) a través de fichero &lt;a href=&quot;https://developer.mozilla.org/es/docs/Web/Manifest&quot;&gt;manifest.json&lt;/a&gt;, por lo que la página puede ser instalada en dispositivos móviles como una web app.&lt;/li&gt;
&lt;li&gt;Ha sido probada con los navegadores web Firefox y Chrome.&lt;/li&gt;
&lt;li&gt;Tratamiento de imágenes con software libre: Gimp e InkScape.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;fuentes&quot;&gt;Fuentes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Wikipedia&lt;/li&gt;
&lt;li&gt;Enciclopedia «Mi Computer», editorial Delta, 1984.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;licencias&quot;&gt;Licencias&lt;/h3&gt;
&lt;p&gt;Sobre el código fuente: &lt;a href=&quot;https://github.com/JavGuerra/tienda-8-bits/blob/main/LICENSE&quot;&gt;GNU GENERAL PUBLIC LICENSE Version 3&lt;/a&gt;&lt;br&gt;
Sobre el contenido de la web: &lt;a href=&quot;https://creativecommons.org/licenses/by-sa/3.0/es/&quot;&gt;(CC) BY-SA 3.0&lt;/a&gt;&lt;br&gt;
Sobre las fotos: Son propiedad de sus respectivos autores.&lt;br&gt;
Sobre las fuentes de letra: &lt;a href=&quot;https://fonts.google.com/&quot;&gt;Google Fonts&lt;/a&gt;&lt;br&gt;
Sobre los iconos: &lt;a href=&quot;https://heroicons.com/&quot;&gt;Heroicons&lt;/a&gt;&lt;br&gt;
Material usado sin ánimo de lucro bajo criterios didácticos y formativos.&lt;/p&gt;
&lt;h3 id=&quot;acceder-a-la-aplicación&quot;&gt;Acceder a la aplicación&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/JavGuerra/tienda-8-bits/0d3d3a968787a438379d003fe31aaede91011e40/qrcode.svg&quot; alt=&quot;Código QR&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.badared.com/proyecto/tienda8bits/&quot;&gt;&lt;button&gt;Ir a la aplicación on-line&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://javguerra.badared.com/proyecto/tienda8bits/&quot;&gt;Aplicación on-line&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://api-tienda8bits.up.railway.app/&quot;&gt;Documentación de la API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/tienda-8-bits/blob/main/enunciado.pdf&quot;&gt;Enunciado de la práctica en PDF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/tienda-8-bits&quot;&gt;Repositorio en GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/XlswjqhxJZ8&quot;&gt;Video de la presentación en YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/tienda-8-bits/blob/main/presentacion.pdf&quot;&gt;Presentación en PDF&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Artículos informativos elaborados por el autor relacionados con esta práctica&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/populate-paginate-fitrado&quot;&gt;Usando populate con paginate y filtrando los resultados&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/rutas-dinamicas-imagenes-mongodb&quot;&gt;Generar enlaces dinámicos de imágenes almacenadas en MongoDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/ordenacion-react&quot;&gt;Ordenando resultados en React&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/spinner-loader-asincrono&quot;&gt;Spinner loader asíncrono&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/tienda-8-bits.BGpB2fQx_Znqyrs.webp"/><category>portfolio</category><category>web</category><category>formación</category><category>becas</category><category>node.js</category><category>express</category><category>react</category><category>mongodb</category><category>javascript</category><category>accesibilidad</category><category>responsive</category><author>JavGuerra</author></item><item><title>Cartelera DAW</title><link>https://javguerra.github.io/blog/cartelera-daw</link><guid isPermaLink="true">https://javguerra.github.io/blog/cartelera-daw</guid><description>Proyecto final de FPGS DAW con Java y Spring Boot</description><pubDate>Thu, 20 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/cartelera-daw.CwIRaY5E_xNKzt.webp&quot; alt=&quot;Logo cartelera DAW&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#java&lt;/em&gt;, &lt;em&gt;#spring boot&lt;/em&gt;, &lt;em&gt;#bootstrap&lt;/em&gt;, &lt;em&gt;#thymeleaft&lt;/em&gt;, &lt;em&gt;#spring security&lt;/em&gt;, &lt;em&gt;#accesibilidad&lt;/em&gt;, &lt;em&gt;#responsive&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Recientemente he presentado mi proyecto fin de estudios de Formación Profesional de Grado Superior DAW. Era algo que llevaba aparcado durante demasiado tiempo y finalmente esta etapa se ha cerrado.&lt;/p&gt;
&lt;p&gt;El proyecto  ha consistido en una aplicación web monolítica, desarrollada en Java, usando el framework Spring Boot, y ha sido desplegada en el servicio de Railway.com.&lt;/p&gt;
&lt;h2 id=&quot;el-proyecto&quot;&gt;El proyecto&lt;/h2&gt;
&lt;p&gt;El proyecto Cartelera DAW desarrolla una plataforma web para mostrar información cinematográfica cuyos usuarios potenciales son los espectadores y las distribuidoras de películas, cines y salas de proyección.&lt;/p&gt;
&lt;p&gt;La plataforma, que está basada en &lt;strong&gt;Java&lt;/strong&gt; y &lt;strong&gt;Spring Boot&lt;/strong&gt;, utiliza un patrón Modelo-Vista-Controlador y una arquitectura cliente-servidor, haciendo uso del IDE &lt;strong&gt;IntelliJ IDEA&lt;/strong&gt;, de &lt;strong&gt;Maven&lt;/strong&gt; para la gestión del proyecto, de &lt;strong&gt;Git&lt;/strong&gt; y &lt;strong&gt;GitHub&lt;/strong&gt; para el versionado de código, de &lt;strong&gt;MySQL&lt;/strong&gt; e &lt;strong&gt;Hibernate&lt;/strong&gt; para la gestión de la base de datos y de una &lt;strong&gt;configuración LAMP dockerizada&lt;/strong&gt; para las pruebas. Para el despliegue se utilizaron tecnologías como &lt;strong&gt;Docker&lt;/strong&gt; y metodologías &lt;strong&gt;CI/CD&lt;/strong&gt;. Para el frontend se ha empleado el gestor de plantillas &lt;strong&gt;Tymeleaft&lt;/strong&gt; y &lt;strong&gt;Bootstrap&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Adicionalmente se proponen una serie de estrategias comerciales para garantizar la sostenibilidad del modelo empresarial del proyecto.&lt;/p&gt;
&lt;p&gt;Se elaboró una memoria de 70 páginas y una presentación.&lt;/p&gt;
&lt;p&gt;El objetivo era aprender y usar tecnologías nuevas no estudiadas en DAW.&lt;/p&gt;
&lt;p&gt;La calificación final ha sido de 9 de 10, y se ha llevado a cabo en un periodo de tres semanas.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/JavGuerra/cartelera-daw/main/src/main/resources/static/img/banner.png&quot; alt=&quot;Pantalla Cartelera DAW&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://cartelera-daw.up.railway.app/&quot;&gt;&lt;button&gt;Ver Cartelera DAW en línea&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;la-formación-previa&quot;&gt;La formación previa&lt;/h2&gt;
&lt;p&gt;Pero el proyecto no partía de cero. Durante los meses de enero y febrero, y hasta el 9 de marzo de 2023, participé en un curso de especialización en Java + Spring de la Fundación Adecco dentro del Proyecto Digital School Erasmus+&lt;/p&gt;
&lt;p&gt;Se trataba de una formación mentorizada que incluía un trabajo en grupo para desarrollar una aplicación web. En mi grupo de trabajo me encargué de la coordinación del equipo mediante Trello y de la planificación de las funcionalidades de la aplicación y las propuesta de mejora de la app. El grupo se llamaba Cinéfilos, y Cartelera DAW bebe de la estructura simple de aquella práctica que me sirvió para entender cómo funciona el framework.&lt;/p&gt;
&lt;p&gt;El proyecto ahora presentado ha cambiado mucho desde aquella versión, tanto en su estructura como en su diseño. Partía de un código inconcluso donde sólo se habían implementado los CRUDs básicos, con fallos de integridad y sin funcionalidades mínimas, pero ahora la aplicación ha sido probada y revisada en profundidad, y cuenta con características que refuerzan sus funcionalidades.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/JavGuerra/cartelera-daw&quot;&gt;&lt;button&gt;Ir al repositorio del proyecto&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En el curso, así como en la práctica, obtuve una calificación de 10/10.&lt;/p&gt;
&lt;h2 id=&quot;características&quot;&gt;Características&lt;/h2&gt;
&lt;p&gt;Además de los requisitos solicitados para el MVP, en la app se ha implementado:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Seguridad de rutas&lt;/li&gt;
&lt;li&gt;Registros de usuario&lt;/li&gt;
&lt;li&gt;Validaciones de formularios&lt;/li&gt;
&lt;li&gt;Automatizaciones&lt;/li&gt;
&lt;li&gt;Documentación con JavaDoc&lt;/li&gt;
&lt;li&gt;Implementación de Logs&lt;/li&gt;
&lt;li&gt;Notificaciones&lt;/li&gt;
&lt;li&gt;Despliegue dockerizado&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cuenta con:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Portada dinámica&lt;/li&gt;
&lt;li&gt;Diseño responsive&lt;/li&gt;
&lt;li&gt;Diseño accesible&lt;/li&gt;
&lt;li&gt;Aviso legal y privacidad&lt;/li&gt;
&lt;li&gt;Aviso de cookies&lt;/li&gt;
&lt;li&gt;Ayuda en línea&lt;/li&gt;
&lt;li&gt;Spinner loader&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo Cartelera-DAW&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/cartelera-daw.svg&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;desarrollo-y-despliegue&quot;&gt;Desarrollo y despliegue&lt;/h2&gt;
&lt;p&gt;Tanto en el desarrollo como en el despliegue ha jugado un papel importante Docker.&lt;/p&gt;
&lt;p&gt;La BBDD MySQL y PHPMyAdmin han sido lanzados usando contenedores gestionados con la herramienta Portainer.&lt;/p&gt;
&lt;p&gt;El despliegue se lleva a cabo tomando el código fuente y, mediante un dockerfile, construyendo la imagen del contenedor que es lanzado en el servidor.&lt;/p&gt;
&lt;p&gt;Spring Boot contiene un servidor Tomcat encargado de servir las páginas de la aplicación.&lt;/p&gt;
&lt;h2 id=&quot;indicaciones-de-instalación&quot;&gt;Indicaciones de instalación&lt;/h2&gt;
&lt;p&gt;Tras clonar el repositorio, es necesario crear un usuario en la BBDD relacional llamado «cartelera-daw» con el password que deseemos. Estos datos, así como el puerto por defecto de la app (8082), pueden ser introducidos en el fichero «aplication.propieties», en la carpeta resources.&lt;/p&gt;
&lt;p&gt;Cada vez que se inicia la aplicación, esta recarga los datos en la BBDD.&lt;/p&gt;
&lt;p&gt;Una vez iniciada la aplicación en local, se puede acceder a ella en la dirección: &lt;code&gt;http://localhost:8082&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;El acceso al panel de administración requiere de usuario y contraseña. Por defecto, la aplicación tiene un usuario «admin» y su contraseña es «admin».&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ADVERTENCIA&lt;/strong&gt;: Se recomienda que, tras el primer acceso, la contraseña de admin sea cambiada o se cree una nueva cuenta de usuario desde la que eliminar la cuenta «admin».&lt;/p&gt;
&lt;h2 id=&quot;licencia&quot;&gt;Licencia&lt;/h2&gt;
&lt;p&gt;Sobre el código fuente: GNU GENERAL PUBLIC LICENSE Version 3&lt;/p&gt;
&lt;h2 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/JavGuerra/cartelera-daw/a79cd41c51299dd3897d989ea8e045ea5f894ac7/src/main/resources/static/img/qr-app.svg&quot; alt=&quot;QR enlace a la Aplicación&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://cartelera-daw.up.railway.app/&quot;&gt;Aplicación&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/cartelera-daw&quot;&gt;Repositorio&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/cartelera-daw.CwIRaY5E_xNKzt.webp"/><category>portfolio</category><category>web</category><category>java</category><category>spring boot</category><category>bootstrap</category><category>thymeleaft</category><category>spring security</category><category>accesibilidad</category><category>responsive</category><author>JavGuerra</author></item><item><title>Códice</title><link>https://javguerra.github.io/blog/codice</link><guid isPermaLink="true">https://javguerra.github.io/blog/codice</guid><description>Mi git-blog sobre programación y formación TIC</description><pubDate>Wed, 21 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/codice.CdsWx0aT_ZlfDvy.webp&quot; alt=&quot;Códice&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#astro&lt;/em&gt;, &lt;em&gt;#ssg&lt;/em&gt;, &lt;em&gt;#tailwind&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#typescript&lt;/em&gt;, &lt;em&gt;#zod&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#markdown&lt;/em&gt;, &lt;em&gt;#responsive&lt;/em&gt;, &lt;em&gt;#accesibilidad&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Hacia tiempo que quería darle un giro a mi anterior &lt;a href=&quot;/blog/hola-mundo&quot;&gt;git-blog elaborado con Jekill&lt;/a&gt;. Hace un mes me topé con &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;, un SSG en JavaScript/TypeScript bajo Node.js, que cuenta con una excelente documentación, y que además incluye un tutorial para hacer un blog. Esto terminó de decidirme para realizar el cambio que ahora presento.&lt;/p&gt;
&lt;h1 id=&quot;retos&quot;&gt;Retos&lt;/h1&gt;
&lt;p&gt;Para llevar a cabo el desarrollo de un nuevo blog personalizado, se me presentaban dos retos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Realizar la aplicación para que fuera operativa al menos con la mayoría de funcionalidades que ya tenía en el anterior blog.&lt;/li&gt;
&lt;li&gt;Migrar las entradas del blog anterior a la nueva estructura de la aplicación, lo que además implicaba repensar esta estructura.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;la-aplicación&quot;&gt;La aplicación&lt;/h2&gt;
&lt;p&gt;Elaborar la aplicación fue realmente sencillo. Siempre hay atascos, pero con la documentación, el tutorial, el Discord de Astro, los videos de YouTube y la IA, fueron subsanándose. El proyecto ha sido el mejor aprendizaje posible.&lt;/p&gt;
&lt;p&gt;Tres cosas me han llevado algo de tiempo:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Extender la colección de posts usando el esquema RSS.&lt;/li&gt;
&lt;li&gt;Utilizar el componente «Image» de Astro.&lt;/li&gt;
&lt;li&gt;JavaScript/TypeScript no funciona como se espera usando transiciones.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Lo relativo a la colección es lógico, porque estaba usando conceptos nuevos y aprendiendo a usar la &lt;a href=&quot;https://zod.dev/&quot;&gt;biblioteca Zod&lt;/a&gt; para definir y validar el esquema de los datos de las colección de entradas del blog. Zod permite validar el &lt;code&gt;frontmatter&lt;/code&gt; o cabecera de cada post para que no falte nada. La idea era partir del esquema &lt;code&gt;rssSchema&lt;/code&gt; y extenderlo para que incluyese algunos datos no contemplados, como por ejemplo el &lt;code&gt;coverImage&lt;/code&gt; o los &lt;code&gt;tags&lt;/code&gt; (&lt;em&gt;Ver fichero /src/content/config.ts&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Pero confieso que el uso del componente Image me ha dado algún quebradero de cabeza, posiblemente relacionado con el schema mencionado, pues no me ha sido posible usar indistintamente imágenes con rutas relativas o rutas absolutas en los encabezados de las entradas. El problema tiene que ver con el atributo &lt;code&gt;src&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Si bien Image permite indicar una ruta relativa (/public) o remota (https), cuando se trata de usar la carpeta /src/assets surgen los problemas. La solución pasa por importar las imágenes, pero ¿qué ocurre cuando se ha de importar una colección de imágenes, para, por ejemplo, el listado de los proyectos del portafolio?&lt;/p&gt;
&lt;p&gt;Mi opción consiste en crear un arreglo con todas las imágenes importadas usando &lt;code&gt;import.meta.glob()&lt;/code&gt;, y luego acceder a cada elemento del arreglo referenciado por su ruta, como se muestra aquí:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; portfolio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;@/content/_portfolio.json&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// proyectos con sus respectivas rutas de imagenes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; images&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;glob&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;@/assets/portfolio/*&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, { eager: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; projects&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; portfolio.projects.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;project&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; image&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; images[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`/src/assets/portfolio/${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;project&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;img&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Record&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;project, image }; &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// a cada proyecto se le añade la imagen importada&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;projects.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;project&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Image&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{project.image.default} &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;alt&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{project.alt} &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;inferSize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Este ejemplo simplificado mostrará la lista de imágenes asociadas a los proyectos.&lt;/p&gt;
&lt;h2 id=&quot;la-migración&quot;&gt;La migración&lt;/h2&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Códice versión Jekill&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/codice-jekill.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Versión previa del blog en Jekill&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Tras conseguir que todo funcionase, llegó el turno de la migración, que pensaba que sería complicada, pero sólo fue laboriosa.&lt;/p&gt;
&lt;p&gt;Haciendo uso del filtrado de contenido del IDE fui cambiando los enlaces de Jekill de las referencias entre las distintas entradas, y creando el nuevo encabezado (&lt;code&gt;frontmatter&lt;/code&gt;) de cada entrada escrita en Markdown.&lt;/p&gt;
&lt;p&gt;A medida que este cambio se iba realizando fue necesario ir adaptando los estilos de texto haciendo uso de &lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind&lt;/a&gt; y su plugin &lt;a href=&quot;https://github.com/tailwindlabs/tailwindcss-typography&quot;&gt;Typography&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Por último, como decidí incluir las transiciones de Astro, me topé con un problema curioso. Para activar o desactivar el menú hamburguesa uso JavaScript. La primera vez que se usa, funciona, pero en los siguientes casos, deja de hacerlo. Lo mismo ocurre con el botón «Volver».&lt;/p&gt;
&lt;p&gt;He tenido que hacer una comprobación para recargar siempre el evento click en ambos casos. Ver /src/components/Hamburger.astro y /src/components/ButtonLink.astro respectivamente.&lt;/p&gt;
&lt;p&gt;Lo mejor de todo es que ha sido divertido hacerlo, y conocer Astro, esta nueva y muy potente herramienta que creo que va a dar mucho juego. Quedan por delante innumerables mejoras y actualizaciones, por lo que la diversión continúa.&lt;/p&gt;
&lt;h1 id=&quot;características&quot;&gt;Características&lt;/h1&gt;
&lt;p&gt;La aplicación cuenta con las siguientes secciones: portada, sobre mi, porfolio, blog, temas y enlaces recomendados. Hace uso de las características avanzadas de Astro, y también:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Incluye RSS de contenidos&lt;/li&gt;
&lt;li&gt;Enlaza con la API de Mastodon&lt;/li&gt;
&lt;li&gt;Implementa sitemap para SEO&lt;/li&gt;
&lt;li&gt;Incluye estadísticas del sitio&lt;/li&gt;
&lt;li&gt;Integra Disqus para comentarios&lt;/li&gt;
&lt;li&gt;Implementa un buscador&lt;/li&gt;
&lt;li&gt;Usa tema de color claro/oscuro automático&lt;/li&gt;
&lt;li&gt;Realiza transiciones de página&lt;/li&gt;
&lt;li&gt;Es accesible&lt;/li&gt;
&lt;li&gt;Es responsive&lt;/li&gt;
&lt;li&gt;Usa TypeScript&lt;/li&gt;
&lt;li&gt;Contiene etiquetado Open Graph&lt;/li&gt;
&lt;li&gt;Es compatible con PWA&lt;/li&gt;
&lt;li&gt;Consigue una calificación de carbono «A» (&lt;a href=&quot;https://www.websitecarbon.com/website/javguerra-github-io/&quot;&gt;ver&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;licencias&quot;&gt;Licencias&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Sobre los contenidos (entradas del blog): &lt;a href=&quot;https://creativecommons.org/licenses/by-sa/4.0/deed.es&quot;&gt;CC BY-SA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Sobre el código fuente: &lt;a href=&quot;https://github.com/JavGuerra/tienda-8-bits/blob/main/LICENSE&quot;&gt;GNU GENERAL PUBLIC LICENSE Version 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Iconos: &lt;a href=&quot;https://www.svgrepo.com/collection/solar-linear-icons/&quot;&gt;Solar Linear Icons&lt;/a&gt; en SVG Repo&lt;/li&gt;
&lt;li&gt;Tipografía: &lt;a href=&quot;https://www.fontsquirrel.com/fonts/blogger-sans&quot;&gt;Blogger_Sans-Medium&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;saber-más&quot;&gt;Saber más&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/api-mastodon&quot;&gt;Accediendo a la API de Mastodon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/javguerra.github.io&quot;&gt;Repositorio en GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/hola-mundo&quot;&gt;git-blog anterior elaborado con Jekill&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://es.wikipedia.org/wiki/Generador_de_sitios_est%C3%A1ticos&quot;&gt;SSG&lt;/a&gt;, &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt; y &lt;a href=&quot;https://es.wikipedia.org/wiki/Astro_(framework)&quot;&gt;Astro en Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind&lt;/a&gt; y &lt;a href=&quot;https://github.com/tailwindlabs/tailwindcss-typography&quot;&gt;Typography&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zod.dev/&quot;&gt;Biblioteca Zod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.astro.build/es/tutorial/0-introduction/&quot;&gt;Construye tu primer blog con Astro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/sOXW0ZnJxbQ?si=yLRwfY4lyOMaHypc&quot;&gt;Curso de Astro, por Fazt, en Youtube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;ir-a-la-página&quot;&gt;Ir a la página&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/&quot;&gt;&lt;img src=&quot;/assets/img/qr.svg&quot; alt=&quot;Código QR&quot;&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://javguerra.github.io/&quot;&gt;https://javguerra.github.io/&lt;/a&gt;&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/codice.CdsWx0aT_ZlfDvy.webp"/><category>portfolio</category><category>web</category><category>código</category><category>astro</category><category>ssg</category><category>tailwind</category><category>javascript</category><category>typescript</category><category>zod</category><category>node.js</category><category>markdown</category><category>responsive</category><category>accesibilidad</category><author>JavGuerra</author></item><item><title>Recursos TIC</title><link>https://javguerra.github.io/blog/recursos-tic</link><guid isPermaLink="true">https://javguerra.github.io/blog/recursos-tic</guid><description>Proyecto final del curso de Java, Spring Boot y testing.</description><pubDate>Wed, 11 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/recursos-tic.DMmpqNPg_ZqU5V8.webp&quot; alt=&quot;Banner Recursos TIC&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#java&lt;/em&gt;, &lt;em&gt;#spring boot&lt;/em&gt;, &lt;em&gt;#bootstrap&lt;/em&gt;, &lt;em&gt;#thymeleaft&lt;/em&gt;, &lt;em&gt;#spring security&lt;/em&gt;, &lt;em&gt;#accesibilidad&lt;/em&gt;, &lt;em&gt;#responsive&lt;/em&gt;, &lt;em&gt;#selenium&lt;/em&gt;, &lt;em&gt;#api&lt;/em&gt;, &lt;em&gt;#swagger&lt;/em&gt;, &lt;em&gt;#javadoc&lt;/em&gt;, &lt;em&gt;#junit&lt;/em&gt;, &lt;em&gt;#mockito&lt;/em&gt;, &lt;em&gt;#docker&lt;/em&gt;, &lt;em&gt;#jacoco&lt;/em&gt;, &lt;em&gt;#github actions&lt;/em&gt;, &lt;em&gt;#ci-cd&lt;/em&gt;, &lt;em&gt;#sonarqube&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Recientemente he cursado una formación con Adecco, y este es mi proyecto fin de estudios, que ha consistido en desarrollar una aplicación que permita gestionar recursos TIC y listas de recursos, para realizar los tests correspondientes, aplicando los conocimientos aprendidos, y que ha sido desplegada en el servicio de Railway.com.&lt;/p&gt;
&lt;h2 id=&quot;el-proyecto&quot;&gt;El proyecto&lt;/h2&gt;
&lt;p&gt;La plataforma, que está basada en &lt;strong&gt;Java&lt;/strong&gt; y &lt;strong&gt;Spring Boot&lt;/strong&gt;, utiliza un patrón Modelo-Vista-Controlador y una arquitectura cliente-servidor, haciendo uso del IDE &lt;strong&gt;IntelliJ IDEA&lt;/strong&gt;, de &lt;strong&gt;Maven&lt;/strong&gt; para la gestión del proyecto, de &lt;strong&gt;Git&lt;/strong&gt; y &lt;strong&gt;GitHub&lt;/strong&gt; para el versionado de código, de &lt;strong&gt;MySQL&lt;/strong&gt;, &lt;strong&gt;H2&lt;/strong&gt; y el ORM &lt;strong&gt;Hibernate&lt;/strong&gt; para la gestión de la base de datos y de una &lt;strong&gt;configuración LAMP dockerizada&lt;/strong&gt; para las pruebas.&lt;/p&gt;
&lt;p&gt;Para el frontend se ha empleado el gestor de plantillas &lt;strong&gt;Tymeleaft&lt;/strong&gt; y &lt;strong&gt;Bootstrap&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Para los tests se ha usado &lt;strong&gt;JUnit&lt;/strong&gt;, &lt;strong&gt;Mockito&lt;/strong&gt;, &lt;strong&gt;Selenium&lt;/strong&gt;. la API se ha probado con &lt;strong&gt;Swagger&lt;/strong&gt; y las estadísticas se han generado con &lt;strong&gt;JaCoCo&lt;/strong&gt; y &lt;strong&gt;SonarQube&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Para el despliegue se utilizaron tecnologías como &lt;strong&gt;Docker&lt;/strong&gt; y metodologías &lt;strong&gt;CI/CD&lt;/strong&gt; con &lt;strong&gt;GitHub Actions&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;La planificación y codificación se han llevado a cabo usando &lt;strong&gt;Trello&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://recursos-tic.up.railway.app&quot;&gt;&lt;button&gt;Ver Recursos TIC en línea&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;destacados&quot;&gt;Destacados&lt;/h2&gt;
&lt;p&gt;Además de los requisitos del MVP, se han incluido las siguientes funcionalidades:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Diseño responsive, “mobile first”&lt;/li&gt;
&lt;li&gt;Web accesible AA. Testada con WAVE&lt;/li&gt;
&lt;li&gt;Seguridad por diseño&lt;/li&gt;
&lt;li&gt;Confirmaciones de borrado&lt;/li&gt;
&lt;li&gt;Implementación de login de usuarios&lt;/li&gt;
&lt;li&gt;Integra el editor TinyMCE&lt;/li&gt;
&lt;li&gt;Provee API REST e interfaz Swagger&lt;/li&gt;
&lt;li&gt;Incluye aviso legal, privacidad y cookies&lt;/li&gt;
&lt;li&gt;Documentación la aplicación con JavaDoc&lt;/li&gt;
&lt;li&gt;Usa el protocolo OpenGraph para RR.SS.&lt;/li&gt;
&lt;li&gt;Manifest para móviles (PWA)&lt;/li&gt;
&lt;li&gt;Desarrollada con Linux + Docker LAMP&lt;/li&gt;
&lt;li&gt;Despliegue&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;video&quot;&gt;Video&lt;/h1&gt;
&lt;p&gt;El proyecto fue presentado a empresas de tecnología, y se puede ver en el vídeo de la presentación del proyecto aquí:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/d_SeaUuKrMg&quot;&gt;&lt;button&gt;Video de la presentación&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;indicaciones-de-uso&quot;&gt;Indicaciones de uso&lt;/h1&gt;
&lt;h2 id=&quot;requisitos&quot;&gt;Requisitos&lt;/h2&gt;
&lt;p&gt;Para ejecutar el proyecto se requiere:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Java 23 o superior&lt;/li&gt;
&lt;li&gt;Maven&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;configuración&quot;&gt;Configuración&lt;/h2&gt;
&lt;p&gt;Actualmente la aplicación se ejecuta localmente en el puerto 8082.&lt;/p&gt;
&lt;p&gt;Puede construirse un contenedor Docker con la imagen de la aplicación ejecutando el fichero &lt;code&gt;docker.sh&lt;/code&gt; que hace uso de docker-compose para lanzar la aplicación y la BBDD que requiere.&lt;/p&gt;
&lt;p&gt;Para generar un informe de cobertura de testing, se puede ejecutar el comando &lt;code&gt;mvn site&lt;/code&gt; y acceder a él en el directorio &lt;code&gt;target/site/jacoco/index.html&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;autores&quot;&gt;Autores&lt;/h1&gt;
&lt;p&gt;Desarrollado por &lt;a href=&quot;https://github.com/JavGuerra&quot;&gt;Javier&lt;/a&gt; y &lt;a href=&quot;https://github.com/kevinzamoraa&quot;&gt;Kevin&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;licencia&quot;&gt;Licencia&lt;/h2&gt;
&lt;p&gt;Sobre el código fuente: GNU GENERAL PUBLIC LICENSE Version 3&lt;/p&gt;
&lt;h2 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/JavGuerra/recursos-tic-testing/refs/heads/main/src/main/resources/static/img/qr.svg&quot; alt=&quot;QR enlace a la Aplicación&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://recursos-tic.up.railway.app&quot;&gt;Aplicación&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://recursos-tic.up.railway.app/swagger-ui/index.html&quot;&gt;API REST&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/recursos-tic-testing&quot;&gt;Repositorio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/d_SeaUuKrMg&quot;&gt;Ver el vídeo de la presentación del proyecto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://recursos-tic.up.railway.app/doc/presentacion-recursos_tic.pdf&quot;&gt;Ver el PDF de la presentación&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://javguerra.github.io/blog/loader-thymeleaft/&quot;&gt;Spinner loader en Thymeleaft&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/recursos-tic.DMmpqNPg_ZqU5V8.webp"/><category>portfolio</category><category>web</category><category>java</category><category>spring boot</category><category>bootstrap</category><category>thymeleaft</category><category>spring security</category><category>accesibilidad</category><category>responsive</category><category>selenium</category><category>api</category><category>swagger</category><category>javadoc</category><category>junit</category><category>mockito</category><category>docker</category><category>jacoco</category><category>github actions</category><category>ci-cd</category><category>sonarqube</category><author>JavGuerra</author></item><item><title>Batman para QL</title><link>https://javguerra.github.io/blog/batman-ql</link><guid isPermaLink="true">https://javguerra.github.io/blog/batman-ql</guid><description>Web del lanzamiento de un remake para QL del conocido juego de los 80.</description><pubDate>Fri, 06 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/batmanql.DQI2tAmB_ZOVqUQ.webp&quot; alt=&quot;Banner del lanzamiento de Batman para QL&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#sinclair ql&lt;/em&gt;, &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;El 10 de mayo de 2025 fue lanzado «Batman QL», un remake del «Batman» de 1986 de Jon Ritman y Bernie Drummond para el retro-ordenador &lt;a href=&quot;/blog/sinclair-ql&quot;&gt;Sinclair QL&lt;/a&gt; a cargo de Joan Gayón. Yo hice mi parte elaborando la landing page del lanzamiento que presento en esta entrada.&lt;/p&gt;
&lt;p&gt;Joan es un compañero de nuestro grupo de aficionados en torno a esta máquina, y su juego ha causado sensación, siendo, hoy por hoy, la mejor versión de este clásico para un ordenador de los 80, y el mejor juego para QL de todos los tiempos, tanto por su jugabilidad como por sus gráficos.&lt;/p&gt;
&lt;h1 id=&quot;la-página-de-lanzamiento&quot;&gt;La página de lanzamiento&lt;/h1&gt;
&lt;p&gt;Visita la página para conocer más sobre este juego.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://badared.com/badaman/ql/batman&quot;&gt;&lt;button&gt;Acceder a la página web&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;características&quot;&gt;Características&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multiidioma&lt;/strong&gt;. La web está disponible tanto en español como inglés. Un fichero index.php determina, en función del navegador, si el visitante habla español o no, y redirige a una u otra página.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;En sintonía con el aspecto del juego&lt;/strong&gt;. El menú de la página simula el menú del juego, y el colorido y la temática son afines.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Responsive&lt;/strong&gt;, Se adapta a distintos dispositivos como móviles (&lt;em&gt;movile first&lt;/em&gt;), tabletas y pantallas de ordenador.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Accesible&lt;/strong&gt;. funciona en lectores de pantalla por voz.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Icono para moviles&lt;/strong&gt;. Es compatible con &lt;em&gt;Progessive Web Aplication&lt;/em&gt; (&lt;a href=&quot;https://developer.mozilla.org/es/docs/Web/Progressive_web_apps&quot;&gt;PWA&lt;/a&gt;) a través de fichero &lt;a href=&quot;https://developer.mozilla.org/es/docs/Web/Manifest&quot;&gt;manifest.json&lt;/a&gt;, por lo que la página puede ser instalada en dispositivos móviles como una web app.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Información para redes sociales&lt;/strong&gt;, Implementa el protocolo &lt;a href=&quot;https://ogp.me/&quot;&gt;Open Graph&lt;/a&gt; para la correcta inserción de la web en redes sociales.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sin frameworks&lt;/strong&gt;. No emplea frameworks de JavaScript o CSS, sino código propio, haciendo más liviana la carga.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Estadísticas&lt;/strong&gt;. La web enlaza un servicio de estadísticas de visitas.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;la-presentación&quot;&gt;La presentación&lt;/h1&gt;
&lt;p&gt;Además de en las redes sociales, tanto el juego como la página fueron presentados el día 17 de mayo de 2025 en el &lt;a href=&quot;/blog/mhc&quot;&gt;Museo de Historia de la Computación&lt;/a&gt;, con un significativo alcance para lo que supone una comunidad como esta.&lt;/p&gt;
&lt;p&gt;Se hicieron eco del lanzamiento las principales web del sector, como Amigawave, Indie Retro News, El Mundo del Spectrum, Computer Emuzone, Spectrum Computing, El Spectrumero, Retroinvaders, Perfect Pixel, Vintage is the new old, spectrumandretronews, Modern Retro Gaming News, De Vuego, Retro8bitshop, Planet Sinclair, entre otras.&lt;/p&gt;
&lt;p&gt;En la primera semana se recibieron más de 1.200 visitas al Blog y la web desde 42 países, más de 3.300 visitas a los posts en foros retro, y se contabilizaron más de 700 descargas.&lt;/p&gt;
&lt;p&gt;Ver la &lt;a href=&quot;/assets/doc/Batman-presenta.pdf&quot;&gt;presentación del juego en PDF&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;el-juego&quot;&gt;El juego&lt;/h1&gt;
&lt;p&gt;Puedes obtener información sobre el juego, sus características y modo de uso en su &lt;a href=&quot;https://badared.com/badaman/ql/batman&quot;&gt;web&lt;/a&gt; o en su &lt;a href=&quot;https://badared.com/badaman/ql/batman/assets/doc/Batman-es.pdf&quot;&gt;manual&lt;/a&gt; disponible para descarga, y también en el artículo &lt;a href=&quot;https://sinclairqles.wordpress.com/2025/05/10/batmanql-joan-gayon-2025/&quot;&gt;Batman, Joan Gayón (2025)&lt;/a&gt; en nuestro blog sobre QL.&lt;/p&gt;
&lt;p&gt;Te adelanto que se trata de una copia fiel pixel a pixel del original, mejorada con mayor colorido, Si autor lo ha llevado a cabo como un reto personal y un homenaje que ha presentado grandes desafíos técnicos.&lt;/p&gt;
&lt;p&gt;Dispones de una versión preparada para emulador en Windows que puedes descargar.&lt;/p&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://badared.com/badaman/ql/batman&quot;&gt;Acceder a la página web del juego&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://batmanql.goatcounter.com/&quot;&gt;Estadísticas de acceso público&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/assets/doc/Batman-presenta.pdf&quot;&gt;Presentación del juego en PDF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/sinclair-ql&quot;&gt;Info sobre Sinclair QL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/batmanql.DQI2tAmB_ZOVqUQ.webp"/><category>sinclair ql</category><category>portfolio</category><category>web</category><category>código</category><category>html</category><category>css</category><category>javascript</category><author>JavGuerra</author></item></channel></rss>