<?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 «servidor»</title><description>Feed RSS de publicaciones etiquetadas con servidor</description><link>https://javguerra.github.io/</link><item><title>Docker LAMP</title><link>https://javguerra.github.io/blog/docker-lamp</link><guid isPermaLink="true">https://javguerra.github.io/blog/docker-lamp</guid><description>Linux, Apache, MySQL y PHP con Docker</description><pubDate>Wed, 11 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/docker-lamp.BGQIH6q5_9u8Ft.webp&quot; alt=&quot;Logos de Docker y LAMP&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;#bbdd&lt;/em&gt;, &lt;em&gt;#mysql&lt;/em&gt;, &lt;em&gt;#php&lt;/em&gt;, &lt;em&gt;#docker&lt;/em&gt;, &lt;em&gt;#servidor&lt;/em&gt;, &lt;em&gt;#apache&lt;/em&gt;, &lt;em&gt;#programación&lt;/em&gt;, &lt;em&gt;#internet&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Entre las herramientas de desarrollo web más comunes no falta el entorno de ejecución. Se hace lento desplegar los cambios al servidor con cada modificación del código que queremos probar. Para evitar esto se creó &lt;a href=&quot;https://es.wikipedia.org/wiki/LAMP&quot;&gt;LAMP&lt;/a&gt;, que es una combinación de Linux, Apache, MySQL (o MariaDB) y PHP que permite que se puedan ejecutar aplicaciones web en local. Este artículo pretende mostrar cómo se puede instalar y ejecutar este entorno de desarrollo web en un sistema Linux usando Docker.&lt;/p&gt;
&lt;p&gt;La principal ventaja de usar Docker es la de poder contar en el desarrollo con una infraestructura análoga a la del despliegue, con el mismo versionado y configuraciones de los servicios.&lt;/p&gt;
&lt;p&gt;Los contenedores son unidades ligeras y portátiles que empaquetan el código y todas sus dependencias para ejecutarse de forma independiente en cualquier sistema que soporte Docker.&lt;/p&gt;
&lt;p&gt;El lector debe conocer Docker para seguir correctamente este artículo, no obstante, siguiendo los pasos indicados aquí se podrá levantar un entorno de desarrollo web LAMP en un sistema Linux sin mayor inconveniente.&lt;/p&gt;
&lt;h1 id=&quot;instalación-de-docker-y-docker-compose&quot;&gt;Instalación de Docker y Docker Compose&lt;/h1&gt;
&lt;p&gt;Será necesario tener instalado &lt;a href=&quot;https://es.wikipedia.org/wiki/Docker&quot;&gt;Docker&lt;/a&gt; en el sistema para poder ejecutar el entorno de desarrollo web.&lt;/p&gt;
&lt;p&gt;Junto con Docker, vamos a instalar &lt;a href=&quot;https://docs.docker.com/compose/&quot;&gt;Docker Compose&lt;/a&gt;, una herramienta que permite ejecutar varios servicios de Docker a la vez.&lt;/p&gt;
&lt;p&gt;Una vez tengamos ambos instalados, necesitaremos crear un fichero de configuración llamado &lt;code&gt;docker-compose.yml&lt;/code&gt; que contendrá la configuración de los servicios que se va a desplegar, y accesoriamente, un fichero &lt;code&gt;Dockerfile&lt;/code&gt; que contendrá las configuraciones comple,entarias necesarias.&lt;/p&gt;
&lt;p&gt;Por último, veremos como ejecutar y parar el entorno de desarrollo web.&lt;/p&gt;
&lt;h2 id=&quot;docker&quot;&gt;Docker&lt;/h2&gt;
&lt;p&gt;Para instalar Docker, necesitaremos cumplir con algunas dependencias:&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;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; apt&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; apt-transport-https&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ca-certificates&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; curl&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; gnupg&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; lsb-release&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; software-properties-common&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Podemos seguir la &lt;a href=&quot;https://docs.docker.com/engine/install/&quot;&gt;documentación oficial&lt;/a&gt; o usar el meta-paquete docker-ce, la última versión de Docker:&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;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; apt-get&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; docker-io&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Posteriormente se añade nuestro usuario al grupo docker. Esto nos permitirá ejecutar comandos de Docker sin necesidad de tener permisos de superusuario:&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;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; usermod&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -aG&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; docker&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $USER&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Una vez instalado, se puede comprobar que se está ejecutando Docker usando el siguiente comando:&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;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;docker-compose&quot;&gt;Docker Compose&lt;/h2&gt;
&lt;p&gt;Para instalar Docker Compose se puede usar el siguiente comando:&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;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; apt&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; docker-compose&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Luego se puede comprobar que se está ejecutando Docker Compose usando el siguiente comando:&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;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;docker-compose&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ya tenemos todo lo necesario para instalar el entorno de desarrollo web LAMP.&lt;/p&gt;
&lt;h1 id=&quot;stack-lamp-con-docker&quot;&gt;Stack LAMP con Docker&lt;/h1&gt;
&lt;p&gt;Para facilitar su despliegue, uso un fichero llamado &lt;code&gt;docker-compose.yml&lt;/code&gt; que contiene la configuración de los servicios que se va a desplegar.&lt;/p&gt;
&lt;h2 id=&quot;contenido-del-fichero-docker-composeyml&quot;&gt;Contenido del fichero docker-compose.yml&lt;/h2&gt;
&lt;p&gt;Mediante el siguiente fichero se configuran y lanzan los diferentes contenedores, volúmenes y redes del entorno para tres servicios: &lt;code&gt;www&lt;/code&gt;, &lt;code&gt;db&lt;/code&gt; y &lt;code&gt;phpmyadmin&lt;/code&gt;.&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;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;version&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;3.1&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;services&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:#85E89D&quot;&gt;    www&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:#85E89D&quot;&gt;        build&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        ports&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;            - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;8081:80&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        volumes&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;            - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;www:/var/www/html&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        depends_on&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;            - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;db&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        networks&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;            - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;default&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    db&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:#85E89D&quot;&gt;        image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;mysql&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        ports&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;            - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;3306:3306&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        command&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;--default-authentication-plugin=mysql_native_password&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        environment&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:#85E89D&quot;&gt;            MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;example&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:#85E89D&quot;&gt;        volumes&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;            - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;./dump:/docker-entrypoint-initdb.d&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 style=&quot;color:#9ECBFF&quot;&gt;./conf:/etc/mysql/conf.d&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 style=&quot;color:#9ECBFF&quot;&gt;persistent:/var/lib/mysql&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        networks&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;            - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;default&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    phpmyadmin&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:#85E89D&quot;&gt;        image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;phpmyadmin/phpmyadmin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        depends_on&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;            - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;db&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        ports&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;            - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;8080:80&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;volumes&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:#85E89D&quot;&gt;    persistent&lt;/span&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 fichero está escrito en formato &lt;a href=&quot;https://es.wikipedia.org/wiki/YAML&quot;&gt;YAML&lt;/a&gt;, que es un lenguaje de marcado de datos, que permite definir la estructura de un fichero de configuración de forma legible y fácil de entender. Como en Python, los espacios son importantes aquí.&lt;/p&gt;
&lt;p&gt;El contenedor &lt;code&gt;www&lt;/code&gt; será el encargado de gestionar el servidor web, y PHP. Por su parte, el contenedor &lt;code&gt;db&lt;/code&gt; se ocupará de la base de datos MySQL y &lt;code&gt;phpmyadmin&lt;/code&gt; lo hará del entorno de administración de la BBDD.&lt;/p&gt;
&lt;p&gt;Por cada servicio, se detallan algunos valores de configuración, como los puertos o las claves de acceso. En el caso de &lt;code&gt;www&lt;/code&gt; es destacable que se hace uso de un fichero dockerfile externo con:&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;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;build&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El volumen (&lt;em&gt;volumes&lt;/em&gt;) almacena y gestiona datos persistentes generados por los contenedores, permitiendo que los datos cruciales de la aplicación no se pierdan durante operaciones rutinarias, estando disponibles aunque los contenedores dejen de estar operativos, compartiendo los datos entre uno o varios contenedores.&lt;/p&gt;
&lt;p&gt;Las redes (&lt;em&gt;networks&lt;/em&gt;) permiten la comunicación entre contenedores y con el mundo exterior, facilitando la conexión entre contenedores en la misma red o con servicios externos, y proporcionando un entorno aislado para la red de contenedores.&lt;/p&gt;
&lt;h2 id=&quot;contenido-del-fichero-dockerfile&quot;&gt;Contenido del fichero Dockerfile&lt;/h2&gt;
&lt;p&gt;Para su completo despliegue, el servicio &lt;code&gt;www&lt;/code&gt; hace uso de un fichero Dockerfile que añade las configuraciones necesarias para obtener PHP, MySQL y varios compresores:&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;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;FROM&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; php:8.0.0-apache&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;ARG&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; DEBIAN_FRONTEND=noninteractive&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;RUN&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; docker-php-ext-install&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; mysqli&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;RUN&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; apt-get&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; update&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;amp;&amp;amp; &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;apt-get&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -y&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; libzip-dev&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;amp;&amp;amp; &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;apt-get&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -y&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zlib1g-dev&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;amp;&amp;amp; &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;rm&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -rf&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /var/lib/apt/lists/&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;amp;&amp;amp; &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;docker-php-ext-install&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zip&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;RUN&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; a2enmod&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; rewrite&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lo guardo con el nombre &lt;code&gt;Dockerfile&lt;/code&gt;. Tanto el fichero &lt;code&gt;docker-compose.yml&lt;/code&gt; como el &lt;code&gt;Dockerfile&lt;/code&gt; han de estar en la misma ruta.&lt;/p&gt;
&lt;h2 id=&quot;ejecución-del-entorno-de-desarrollo-web&quot;&gt;Ejecución del entorno de desarrollo web&lt;/h2&gt;
&lt;p&gt;Para poder probar su correcto funcionamiento uso:&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;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;docker-compose&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; up&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esto levantará los contenedores. Si todo ha ido bien, se habrán descargado las imágenes correspondientes y lanzado los contenedores necesarios para disponer del entorno. Se puede obtener un listado de los contenedores levantados con:&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;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;docker-compose&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ps&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para probar su correcto funcionamiento, podemos copiar aquello que deseemos mostrar en el navegador a la carpeta &lt;code&gt;www&lt;/code&gt; en la carpeta actual donde están los dos scripts, o bien podemos crear un fichero &lt;code&gt;index.php&lt;/code&gt; con sólo el código siguiente:&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;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;php&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; phpinfo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;( ); &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ahora debemos acceder al contenido mediante el navegador con la ruta:&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;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;localhost 8001&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;8001 es el puerto descrito en el fichero &lt;code&gt;docker-compose.yml&lt;/code&gt; para el servidor web, pero podemos cambiarlo en el mismo fichero.&lt;/p&gt;
&lt;p&gt;Una vez ejecutado, si podemos ver la información en el navegador, es que Apache y PHP están funcionando adecuadamente.&lt;/p&gt;
&lt;p&gt;Para comprobar si MySQL y PHPMyAdmin están activos, accedemos a la misma dirección localhost pero por el puerto 8080:&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;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;localhost:8080&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para acceder podemos usar &lt;code&gt;root&lt;/code&gt; como usuario y &lt;code&gt;example&lt;/code&gt; como contraseña.&lt;/p&gt;
&lt;p&gt;Cuando terminemos, podemos detener los contenedores mediante:&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;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;docker-compose&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; stop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;usando-docker-lamp-en-nuestros-desarrollos&quot;&gt;Usando Docker LAMP en nuestros desarrollos&lt;/h2&gt;
&lt;p&gt;Ahora podemos levantar y detener los contenedores mediante simples comandos y ubicar estos script y el contenido que estemos desarrollando en la carpeta &lt;code&gt;www&lt;/code&gt; de la misma manera que lo hicimos antes, y podemos mover toda esta estructura de ficheros a donde nos resulte más conveniente, o configurar el fichero &lt;code&gt;docker-compose.yml&lt;/code&gt; para que sepa encontrar la carpeta &lt;code&gt;www&lt;/code&gt; allá donde se ubique.&lt;/p&gt;
&lt;h1 id=&quot;bonus-portainer&quot;&gt;BONUS: Portainer&lt;/h1&gt;
&lt;p&gt;Para una gestión más cómoda de los contenedores y su monitorización, se puede usar &lt;a href=&quot;https://www.portainer.io/&quot;&gt;Portainer&lt;/a&gt;, un front end web local que se levanta como un contenedor más mediante:&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;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; docker&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -itd&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -p&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; 9443:9443&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --name=portainer&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --restart=always&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -v&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -v&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /docker/portainer:/data&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; portainer/portainer-ce&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Es posible acceder a él mediante la dirección localhost y el puerto 9443:&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;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;localhost:9443&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Portainer&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/portainer.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;Mediante este entorno se puede hacer una gestión de los contenedores y su monitorización, como se ve en la imagen.&lt;/p&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;https://es.wikipedia.org/wiki/LAMP&quot;&gt;LAMP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://es.wikipedia.org/wiki/Docker&quot;&gt;Docker&lt;/a&gt; y &lt;a href=&quot;https://docs.docker.com/compose/&quot;&gt;Docker Compose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://es.wikipedia.org/wiki/YAML&quot;&gt;YAML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://es.wikipedia.org/wiki/MySQL&quot;&gt;MySQL&lt;/a&gt;, &lt;a href=&quot;https://es.wikipedia.org/wiki/PHP&quot;&gt;PHP&lt;/a&gt; y &lt;a href=&quot;https://es.wikipedia.org/wiki/Apache_HTTP_Server&quot;&gt;Apache&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://es.wikipedia.org/wiki/XAMPP&quot;&gt;XAMPP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.portainer.io/&quot;&gt;Portainer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/docker-lamp.BGQIH6q5_9u8Ft.webp"/><category>bbdd</category><category>mysql</category><category>php</category><category>docker</category><category>servidor</category><category>apache</category><category>programación</category><category>internet</category><author>JavGuerra</author></item><item><title>Accediendo a la API de Mastodon</title><link>https://javguerra.github.io/blog/api-mastodon</link><guid isPermaLink="true">https://javguerra.github.io/blog/api-mastodon</guid><description>Cómo obtener y mostrar las publicaciones de esta red social</description><pubDate>Wed, 18 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/mastodon.Dc7cm57i_1rPUNx.webp&quot; alt=&quot;Logo Mastodon&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;#javascript&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#api&lt;/em&gt;, &lt;em&gt;#servidor&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;En este artículo vamos a ver cómo se puede acceder a la API de Mastodon, un servicio que nos permite, entre otras cosas, obtener las últimas publicaciones de un usuario concreto.&lt;/p&gt;
&lt;p&gt;Recientemente la he usado para mostrar, en el apartado &lt;a href=&quot;/social&quot;&gt;social&lt;/a&gt; de esta página, las publicaciones que escribo en la red social, empleando JavaScript del lado del cliente en Astro, es decir, que en una página .astro he incluido un script que lee y muestra las publicaciones actualizadas de mi cuenta de Mastodon.&lt;/p&gt;
&lt;p&gt;Me centraré en la parte de JavaScript y no tanto en la integración con Astro, ya que, de esta forma, será posible aprovechar la información para que pueda ser usada en otros frameworks o aplicaciones propias.&lt;/p&gt;
&lt;p&gt;El lector debe conocer las funciones avanzadas de JavaScript como asincronía y llamadas a APIs para seguir correctamente esta entrada.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;note&quot;&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Este artículo ha sido publicado también en &lt;a href=&quot;https://ifgeekthen.nttdata.com/s/post/accediendo-a-la-api-de-mastodon-MCKLT5EQTUINBVBMVGH7W6S2MYXM&quot;&gt;IfGeekThen&lt;/a&gt;, el blog de NTT Data, el 18 de marzo de 2026.&lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;api-de-mastodon&quot;&gt;API de Mastodon&lt;/h1&gt;
&lt;p&gt;Realizaré la consulta a la &lt;a href=&quot;https://docs.joinmastodon.org/api/&quot;&gt;API de Mastodon&lt;/a&gt; mediante la función &lt;code&gt;fetch&lt;/code&gt; de JavaScript.&lt;/p&gt;
&lt;p&gt;Las consultas a la API no requieren autenticación (aunque es posible), por lo que podemos acceder a ella sin ningún tipo de token, pero voy a necesitar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;La url de la instancia de Mastodon, es decir el servidor.&lt;/li&gt;
&lt;li&gt;El id de la cuenta de usuario que quiero consultar.&lt;/li&gt;
&lt;li&gt;El número que indique la cantidad de publicaciones que quiero obtener.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cuando tengamos estos datos, podremos construir el &lt;code&gt;endpoint&lt;/code&gt; o url de la API de Mastodon, que será la siguiente:&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;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;https://&amp;lt;server&amp;gt;/api/v1/accounts/&amp;lt;accountId&amp;gt;/statuses?limit=&amp;lt;limit&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Donde:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;server&amp;gt;&lt;/code&gt; es el nombre de dominio de la instancia de Mastodon, por ejemplo &lt;code&gt;mastodon.social&lt;/code&gt; o la de tu propia instancia.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;accountId&amp;gt;&lt;/code&gt; es el id de la cuenta que queremos consultar, por ejemplo &lt;code&gt;1234567890&lt;/code&gt;. Este id se obtendría de la url de la cuenta, ej.: &lt;code&gt;https://mastodon.social/@usuario&lt;/code&gt;, como se verá enseguida.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;limit&amp;gt;&lt;/code&gt; es el número de publicaciones que queremos consultar, por ejemplo &lt;code&gt;10&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Para obtener el id de la cuenta, debo usar la siguiente url:&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;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;https://&amp;lt;server&amp;gt;/api/v1/accounts/lookup?acct=&amp;lt;username&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Donde hay que sustituir &lt;code&gt;&amp;lt;server&amp;gt;&lt;/code&gt; por el nombre de la instancia de Mastodon y &lt;code&gt;&amp;lt;username&amp;gt;&lt;/code&gt; por el nombre de usuario de la cuenta que queremos consultar.&lt;/p&gt;
&lt;p&gt;Obtengo un json con el id de la cuenta, entre otros datos, como por ejemplo:&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;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&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:#79B8FF&quot;&gt;  &quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1234567890&quot;&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:#79B8FF&quot;&gt;  &quot;username&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;usuario&quot;&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:#FDAEB7;font-style:italic&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;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si queremos consultar las 10 últimas publicaciones de la cuenta ficticia &lt;code&gt;@usuario&lt;/code&gt;, que tiene el id ficticio: &lt;code&gt;1234567890&lt;/code&gt;, en la instancia de Mastodon &lt;code&gt;mastodon.social&lt;/code&gt;, tendríamos que usar la siguiente url:&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;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;https://mastodon.social/api/v1/accounts/1234567890/statuses?limit=10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;fetch&quot;&gt;Fetch&lt;/h2&gt;
&lt;p&gt;Ya tenemos formado el endpoint de la API de Mastodon, y, para llevar a cabo la consulta, usaré la función &lt;code&gt;fetch&lt;/code&gt; de JavaScript, que permite realizar peticiones HTTP, y obtener el resultado como un objeto &lt;code&gt;json&lt;/code&gt;.&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;js&quot;&gt;&lt;code&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; server&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;https://mastodon.social&apos;&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; profileId&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;1234567890&apos;&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; limit&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 10&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; route&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;server&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/api/v1/accounts/${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;profileId&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/statuses?limit=${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;limit&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&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;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getLatestPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;route&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;  try&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; response&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fetch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(route);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&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;response.ok) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(response.statusText);&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:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;json&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;  } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (error) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(error);&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&gt;
&lt;span class=&quot;line&quot;&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;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como se aprecia, se trata de una función asíncrona con una estructura de lo más común, que se ejecutará de manera independiente, y cuando se haya terminado de ejecutar, me permitirá seguir con la ejecución del código.&lt;/p&gt;
&lt;p&gt;Para llamar a la función, uso:&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;js&quot;&gt;&lt;code&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; posts&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getLatestPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(route);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;await&lt;/code&gt;, se espera a que la función &lt;code&gt;getLatestPosts&lt;/code&gt; termine de ejecutarse, y luego es posible usar el array &lt;code&gt;posts&lt;/code&gt; para mostrar las publicaciones en nuestra página, siempre que no se haya producido ningún error.&lt;/p&gt;
&lt;h2 id=&quot;mostrando-las-publicaciones&quot;&gt;Mostrando las publicaciones&lt;/h2&gt;
&lt;p&gt;Allí donde vamos a mostrar las publicaciones, voy a usar un elemento &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; con el &lt;code&gt;id=&quot;posts&quot;&lt;/code&gt; para definir una lista de publicaciones, un &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;, y un elemento &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; para cada publicación.&lt;/p&gt;
&lt;p&gt;Incluyo el siguiente código HTML en la página:&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;html&quot;&gt;&lt;code&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:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;posts&quot;&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;  Cargando...&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:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Y luego, mediante el script de JavaScript, sustituiré el contenido del elemento &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; con las publicaciones obtenidas y formateadas:&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;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; displayPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;posts&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; postsElement&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;posts&apos;&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;  if&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;posts &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; posts.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&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;    postsElement.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&amp;lt;p&amp;gt;No se encontraron posts.&amp;lt;/p&amp;gt;&apos;&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;    return&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;  }&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;  postsElement.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;lt;h2&amp;gt;Últimas publicaciones&amp;lt;/h2&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;lt;ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;posts&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;post&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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; isReblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;reblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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; originalPost&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; isReblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;reblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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; contentIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;replace&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#DBEDFF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;gt;]&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#DBEDFF&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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; hasMedia&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;media_attachments&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;media_attachments&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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; multimediaLink&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hasMedia&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&amp;lt;small&amp;gt;Incluye contenido multimedia &amp;lt;a href=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&amp;gt;👁️ Ver en origen →&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;&amp;lt;br /&amp;gt;`&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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;      return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &amp;lt;li class=&quot;post&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;isReblog&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &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 style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} &amp;lt;small&amp;gt;♻️ Republicado &amp;lt;/small&amp;gt;`&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 style=&quot;color:#E1E4E8&quot;&gt; contentIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hasMedia&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 style=&quot;color:#E1E4E8&quot;&gt; multimediaLink&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 style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; multimediaLink&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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:#9ECBFF&quot;&gt;          &amp;lt;a href=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &amp;lt;small&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;              📢 ${&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Date&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;created_at&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;es-ES&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;, {dateStyle: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;medium&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;, timeStyle: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;short&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;})&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &amp;lt;/small&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          &amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &amp;lt;/li&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;      }).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&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&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;Vamos por partes.&lt;/p&gt;
&lt;p&gt;Primero obtengo el elemento &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; con el id &lt;code&gt;posts&lt;/code&gt; del DOM, y lo guardo en una variable &lt;code&gt;postsElement&lt;/code&gt; para poder referirme a él en el script.&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;js&quot;&gt;&lt;code&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; postsElement&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;posts&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Compruebo que hay publicaciones y que el array &lt;code&gt;posts&lt;/code&gt; no esté vacío. Si no es así, defino el contenido del elemento &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; con el siguiente código:&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;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;postsElement.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&amp;lt;p&amp;gt;No se encontraron posts.&amp;lt;/p&amp;gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si hemos obtenidos publicaciones, hago uso de la siguiente estructura:&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;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;postsElement.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;lt;h2&amp;gt;Últimas publicaciones&amp;lt;/h2&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;lt;ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;posts&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;post&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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:#9ECBFF&quot;&gt;        // código para mostrar cada publicación&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:#9ECBFF&quot;&gt;    `&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&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&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con la función &lt;code&gt;map&lt;/code&gt; puedo iterar sobre cada elemento del objeto &lt;code&gt;posts&lt;/code&gt; y acceder a cada una de las publicaciones, y luego puedo juntar todos los elementos formateados en una cadena de texto mediante la función &lt;code&gt;join&lt;/code&gt;. El resultado se incluirá en el elemento &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; con el id &lt;code&gt;posts&lt;/code&gt; mediante el método &lt;code&gt;innerHTML&lt;/code&gt; de &lt;code&gt;postElement&lt;/code&gt;. Es decir, obtengo cada publicación, esta se formatea, y se concatena o añade a la cadena de texto que conforma el contenido del elemento &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;; las publicaciones.&lt;/p&gt;
&lt;h2 id=&quot;pintando&quot;&gt;Pintando…&lt;/h2&gt;
&lt;p&gt;Para formatear las publicaciones, voy a usar una estructura de elementos &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; por cada publicación, como dije, y un elemento &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; para enlazar a la publicación original. Lo que quiero conseguir se parece a esto:&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;html&quot;&gt;&lt;code&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:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;post&quot;&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;  Este es un ejemplo de una publicación en Mastodon.&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:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; href&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;https://mastodon.social/@usuario/109292343224519197&quot;&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;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;small&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;18 sep 2024, 1:23:45&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;small&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;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&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;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;De cada publicación obtengo el contenido de la publicación, y el enlace a la publicación. Con esta información defino una serie de variables:&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;js&quot;&gt;&lt;code&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; isReblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post.reblog &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&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; originalPost&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; isReblog &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post.reblog &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post;&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; contentIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost.content &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost.content.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;replace&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#DBEDFF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;gt;]&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#DBEDFF&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&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:#9ECBFF&quot;&gt; &apos;&apos;&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; hasMedia&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost.media_attachments &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost.media_attachments.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&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; multimediaLink&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hasMedia &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&amp;lt;small&amp;gt;Incluye contenido multimedia &amp;lt;a href=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&amp;gt;👁️ Ver en origen →&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;&amp;lt;br /&amp;gt;`&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como las publicaciones pueden ser republicaciones, es decir, publicaciones compartidas de otros usuarios o propias, compruebo si este es el caso.&lt;/p&gt;
&lt;p&gt;Si es una republicación, obtengo su contenido, sino, obtengo el contenido de la publicación original.&lt;/p&gt;
&lt;p&gt;Compruebo si el texto de la publicación está verdaderamente vacío, es decir, si no contiene, por ejemplo, alguna etiqueta HTML.&lt;/p&gt;
&lt;p&gt;Compruebo también si la publicación tiene contenido multimedia.&lt;/p&gt;
&lt;p&gt;Por último, si la publicación tiene contenido multimedia, preparo el enlace a la publicación original, y si no lo tiene, dejo el aviso vacío.&lt;/p&gt;
&lt;p&gt;Seguidamente, formateo el texto de la publicación mediante el siguiente código:&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;js&quot;&gt;&lt;code&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:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;post&quot;&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;    ${isReblog &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 style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} &amp;lt;small&amp;gt;♻️ Republicado &amp;lt;/small&amp;gt;`&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 style=&quot;color:#E1E4E8&quot;&gt; contentIsEmpty &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hasMedia&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 style=&quot;color:#E1E4E8&quot;&gt; multimediaLink&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 style=&quot;color:#E1E4E8&quot;&gt; originalPost.content &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; multimediaLink}&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;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; href&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;${originalPost.url}&quot;&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;      &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;small&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 style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Date&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(originalPost.created_at).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;es-ES&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, {dateStyle: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;medium&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, timeStyle: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;short&apos;&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:#85E89D&quot;&gt;small&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;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&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;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;¿Se trata de una republicación?, entonces publico el texto de la republicación con el aviso de &lt;code&gt;♻️ Republicado&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;En caso contrario, compruebo si el texto de la publicación está vacío y si tiene contenido multimedia.&lt;/p&gt;
&lt;p&gt;Si ambas condiciones se cumplen, entonces publico el aviso de ver &lt;code&gt;👁️ Ver en origen →&lt;/code&gt; con su enlace, ya que será una publicación sin texto pero con video o imagen…&lt;/p&gt;
&lt;p&gt;Si no se cumple alguna o ambas condiciones, entonces publico el contenido de la publicación y el aviso de ver &lt;code&gt;👁️ Ver en origen →&lt;/code&gt; con su enlace, pues o bien la publicación tiene contenido, tiene texto y contenido multimedia o sólo texto.&lt;/p&gt;
&lt;p&gt;Para mostrar la fecha, uso la función &lt;code&gt;toLocaleString&lt;/code&gt; de JavaScript, que me permite obtener la fecha en formato local.&lt;/p&gt;
&lt;p&gt;Es posible llamar a la función &lt;code&gt;displayPosts&lt;/code&gt; mediante:&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;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;displayPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(posts);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Siendo &lt;code&gt;posts&lt;/code&gt; el objeto de publicaciones en json obtenido de la API de Mastodon.&lt;/p&gt;
&lt;h2 id=&quot;una-advertencia&quot;&gt;Una advertencia&lt;/h2&gt;
&lt;p&gt;Si bien las instancias de Mastodon se encargan de limpiar las publicaciones de los usuarios ante potenciales peligros, no estaría de más implementar una función propia que se ocupe de limpiar el contenido de las publicaciones antes de hacer uso de &lt;code&gt;originalPost.content&lt;/code&gt; para evitar sorpresas por la inclusión de etiquetas o atributos dañinos que pudieran llegar de publicaciones de instancias de Mastodon poco confiables.&lt;/p&gt;
&lt;h1 id=&quot;el-código-completo&quot;&gt;El código completo&lt;/h1&gt;
&lt;p&gt;El código siguiente incluye el contenido mostrado hasta ahora en el artículo:&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;html&quot;&gt;&lt;code&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:#85E89D&quot;&gt;DOCTYPE&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; html&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;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; lang&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;es&quot;&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;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&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;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; charset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;UTF-8&quot;&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;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;viewport&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;width=device-width, initial-scale=1.0&quot;&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;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Publicaciones de Mastodon&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&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;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; rel&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; href&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;style.css&quot;&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;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&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;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&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;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Mastodon&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h1&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&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:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;posts&quot;&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;        Cargando...&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:#85E89D&quot;&gt;div&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&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:#85E89D&quot;&gt;script&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:#6A737D&quot;&gt;    // Sustituye los valores siguientes para adaptarlo a tu propio uso&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; server&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;https://mastodon.social&apos;&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; profileId&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;1234567890&apos;&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; limit&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 10&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; route&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;server&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/api/v1/accounts/${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;profileId&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/statuses?limit=${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;limit&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&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;    async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getLatestPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;route&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;        try&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; response&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fetch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(route);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&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;response.ok) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(response.statusText);&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:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;json&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;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (error) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(error);&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&gt;
&lt;span class=&quot;line&quot;&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;    }&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;    function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; displayPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;posts&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; postsElement&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;posts&apos;&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;      if&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;posts &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; posts.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&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;        postsElement.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&amp;lt;p&amp;gt;No se encontraron posts.&amp;lt;/p&amp;gt;&apos;&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;        return&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;      }&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;      postsElement.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &amp;lt;h2&amp;gt;Últimas publicaciones&amp;lt;/h2&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &amp;lt;ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;posts&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;post&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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; isReblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;reblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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; originalPost&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; isReblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;reblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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; contentIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;replace&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#DBEDFF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;gt;]&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#DBEDFF&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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; hasMedia&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;media_attachments&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;media_attachments&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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; multimediaLink&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hasMedia&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&amp;lt;small&amp;gt;Incluye contenido multimedia &amp;lt;a href=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&amp;gt;👁️ Ver en origen →&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;&amp;lt;br /&amp;gt;`&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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;          return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &amp;lt;li class=&quot;post&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;              ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;isReblog&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &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 style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} &amp;lt;small&amp;gt;♻️ Republicado &amp;lt;/small&amp;gt;`&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 style=&quot;color:#E1E4E8&quot;&gt; contentIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hasMedia&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 style=&quot;color:#E1E4E8&quot;&gt; multimediaLink&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 style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; multimediaLink&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&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:#9ECBFF&quot;&gt;              &amp;lt;a href=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &amp;lt;small&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                  📢 ${&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Date&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;created_at&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;es-ES&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;, {dateStyle: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;medium&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;, timeStyle: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;short&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;})&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &amp;lt;/small&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;              &amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &amp;lt;/li&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          }).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&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&gt;
&lt;span class=&quot;line&quot;&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:#E1E4E8&quot;&gt;    document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;DOMContentLoaded&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &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; posts&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getLatestPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(route);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;      displayPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(posts);&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;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&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&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:#85E89D&quot;&gt;body&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;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No olvides sustituir los valores de &lt;code&gt;server&lt;/code&gt;, &lt;code&gt;profileId&lt;/code&gt; y &lt;code&gt;limit&lt;/code&gt; con los que correspondan a tu propio perfil de Mastodon o el del perfil que desees consultar.&lt;/p&gt;
&lt;h1 id=&quot;cargando-las-publicaciones&quot;&gt;Cargando las publicaciones&lt;/h1&gt;
&lt;p&gt;Aquí confluye todo. Mediante el evento asociado a la carga de la página &lt;code&gt;DOMContentLoaded&lt;/code&gt;, que se incluye al final del script, se inicia la petición asíncrona a la API de Mastodon con &lt;code&gt;getLatestPosts(route)&lt;/code&gt; y se muestran las publicaciones con &lt;code&gt;displayPosts(posts)&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;estilos&quot;&gt;Estilos&lt;/h1&gt;
&lt;p&gt;Para que el contenido se vea correctamente, es recomendable definir algunos estilos en el archivo &lt;code&gt;style.css&lt;/code&gt;. Un ejemplo:&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;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.invisible&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:#79B8FF&quot;&gt;  display&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;inline-block&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:#79B8FF&quot;&gt;  font-size&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&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:#79B8FF&quot;&gt;  height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&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:#79B8FF&quot;&gt;  line-height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&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:#79B8FF&quot;&gt;  position&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;absolute&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:#79B8FF&quot;&gt;  width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&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;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.invisible&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt; img&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:#B392F0&quot;&gt;.invisible&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt; svg&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:#79B8FF&quot;&gt;  border&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !important&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:#79B8FF&quot;&gt;  height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !important&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:#79B8FF&quot;&gt;  margin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !important&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:#79B8FF&quot;&gt;  padding&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !important&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:#79B8FF&quot;&gt;  width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !important&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;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.ellipsis:after&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:#79B8FF&quot;&gt;  content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;…&quot;&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;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Los estilos aquí mostrados son los que usa el propio Mastodon para presentar las publicaciones en su página.&lt;/p&gt;
&lt;p&gt;La clase &lt;code&gt;.invisible&lt;/code&gt; se aplica a los elementos que quiero que no se vean. Esto es necesario para evitar saltos de línea y espacios en blanco en el contenido de las publicaciones debido a su formateo original.&lt;/p&gt;
&lt;p&gt;Se incluye también la clase &lt;code&gt;.invisible&lt;/code&gt; para imágenes y vectores SVG. Si bien no se usa en este ejemplo, pueden ser de utilidad si decides mostrar el contenido multimedia de las publicaciones.&lt;/p&gt;
&lt;p&gt;Por su parte, la clase &lt;code&gt;.ellipsis&lt;/code&gt; se usa para mostrar puntos suspensivos &lt;code&gt;…&lt;/code&gt; al final de los enlaces acortados.&lt;/p&gt;
&lt;p&gt;A partir de estos estilos es posible aplicar estilos propios al contenido mostrado.&lt;/p&gt;
&lt;h1 id=&quot;experimenta-por-tu-cuenta&quot;&gt;Experimenta por tu cuenta&lt;/h1&gt;
&lt;p&gt;Como has podido comprobar a lo largo de este artículo, acceder a la API de Mastodon es un proceso sencillo que nos permite integrar el contenido de una cuenta en nuestros propios proyectos mediante código JavaScript. Desde la construcción del endpoint y la gestión de la respuesta asíncrona con fetch, hasta el formateo final de los datos considerando casos como las republicaciones o el contenido multimedia, has visto los fundamentos para crear tu propio visor de publicaciones.&lt;/p&gt;
&lt;p&gt;Te animo a que tomes el código completo, lo adaptes con tus propios datos y experimentes modificando la lógica de displayPosts y el css para personalizar aún más la presentación. Y si te surgen dudas o mejoras, no dudes en explorar la documentación oficial de la API, donde encontrarás muchas más posibilidades.&lt;/p&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;https://es.wikipedia.org/wiki/Mastodon_(red_social)&quot;&gt;Mastodon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.joinmastodon.org/api/&quot;&gt;Mastodon API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ejemplo de uso: &lt;a href=&quot;/social&quot;&gt;Social&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/mastodon.Dc7cm57i_1rPUNx.webp"/><category>javascript</category><category>código</category><category>api</category><category>servidor</category><author>JavGuerra</author></item><item><title>Museos de computación en Londres</title><link>https://javguerra.github.io/blog/museos-computacion-londres</link><guid isPermaLink="true">https://javguerra.github.io/blog/museos-computacion-londres</guid><description>Un paseo por Bletchley Park, The National Museum Of Computing y The Science Museum</description><pubDate>Fri, 27 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/TNMOC_IBM_PC.RzqfNVsY_1kj0xJ.webp&quot; alt=&quot;IBM PC&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;#algoritmia&lt;/em&gt;, &lt;em&gt;#computación&lt;/em&gt;, &lt;em&gt;#historia&lt;/em&gt;, &lt;em&gt;#londres&lt;/em&gt;, &lt;em&gt;#museo&lt;/em&gt;, &lt;em&gt;#criptografía&lt;/em&gt;, &lt;em&gt;#fotografía&lt;/em&gt;, &lt;em&gt;#internet&lt;/em&gt;, &lt;em&gt;#retro&lt;/em&gt;, &lt;em&gt;#servidor&lt;/em&gt;, &lt;em&gt;#sinclair ql&lt;/em&gt;, &lt;em&gt;#tic&lt;/em&gt;, &lt;em&gt;#viaje&lt;/em&gt;, &lt;em&gt;#enigma&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Recientemente he estado de viaje familiar en Londres y creo que he aprovechado bien el tiempo. En esta entrada cuento brevemente la visita a distintos museos relacionados con la informática en la ciudad.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.badared.com/galeria/?dir=2024-12-COMPUTER-LONDON&quot;&gt;&lt;button&gt;Ver galería de fotos&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Reino Unido es el país que vio nacer la informática como la conocemos hoy y de esto tiene mucha culpa la Segunda Guerra Mundial y &lt;a href=&quot;https://es.wikipedia.org/wiki/Bletchley_Park&quot;&gt;Bletchley Park&lt;/a&gt;, la base donde &lt;code&gt;Alan Turing&lt;/code&gt; y las mujeres de inteligencia del ejercito descifraron el código de Enigma y Lorenz. Allí pude ver estas máquinas y las que se usaron para descifrarlas.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/Bletchley_Park_Turing.jpg&quot;&gt;&lt;img src=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/Bletchley_Park_Turing.jpg&quot; alt=&quot;Alan Turing&quot; width=&quot;200&quot;/&gt;&lt;/a&gt;
&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/Bletchley_Park_Turing.jpg&quot;&gt;Alan Turing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/Bletchley_Park_Enigma.jpg&quot;&gt;&lt;img src=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/Bletchley_Park_Enigma.jpg&quot; alt=&quot;Enigma&quot; width=&quot;200&quot;/&gt;&lt;/a&gt;
&lt;a href=&quot;ttps://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/Bletchley_Park_Enigma.jpg&quot;&gt;Enigma&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hablando de códigos, en el Museo Británico está la original piedra de Rosetta, que también pude ver.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/Rosetta_British_Museum.jpg&quot;&gt;&lt;img src=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/Rosetta_British_Museum.jpg&quot; alt=&quot;Piedra de Rosetta&quot; width=&quot;200&quot;/&gt;&lt;/a&gt;
&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/Rosetta_British_Museum.jpg&quot;&gt;Piedra de Rosetta&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Justo detrás de Bletchley Park, a escasos metros, está &lt;a href=&quot;https://www.tnmoc.org/&quot;&gt;The National Museum Of Computing&lt;/a&gt;. Esta es una visita que no debes perderte, pues cuenta con grandes sorpresas, como una versión operativa de &lt;code&gt;The Bombe&lt;/code&gt; reconstruida, asi como las reconstrucciones de la máquina &lt;code&gt;Tunny&lt;/code&gt; y del no menos famoso &lt;code&gt;Colossus&lt;/code&gt; que ayudaron a romper los códigos del ejercito alemán en la WWII.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/TNMOC_Bombe.jpg&quot;&gt;&lt;img src=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/TNMOC_Bombe.jpg&quot; alt=&quot;The Bombe&quot; width=&quot;300&quot;/&gt;&lt;/a&gt;
&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/TNMOC_Bombe.jpg&quot;&gt;The Bombe&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/TNMOC_Colossus.jpg&quot;&gt;&lt;img src=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/TNMOC_Colossus.jpg&quot; alt=&quot;Colossus&quot; width=&quot;300&quot;/&gt;&lt;/a&gt;
&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/TNMOC_Colossus.jpg&quot;&gt;Colossus&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;También allí puede encontrarse la máquina &lt;code&gt;WITCH&lt;/code&gt;, que tiene el mérito de ser el ordenador de primera generación más antiguo aún en funcionamiento, y junto a él, está el ordenador &lt;code&gt;EDSAC&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Además de mainframes, un par de ordenadores &lt;code&gt;CRAY&lt;/code&gt;’s, de una buena colección de PCs, discos, válvulas y calculadoras, encontré, como no, un &lt;code&gt;Sinclair QL&lt;/code&gt; y sus dos hermanos, el &lt;code&gt;OPD&lt;/code&gt; y el &lt;code&gt;Merlin TONTO&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/TNMOC_OPD.jpg&quot;&gt;&lt;img src=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/TNMOC_OPD.jpg&quot; alt=&quot;OPD&quot; width=&quot;300&quot;/&gt;&lt;/a&gt;
&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/TNMOC_OPD.jpg&quot;&gt;OPD&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/TNMOC_Merlin_TONTO.jpg&quot;&gt;&lt;img src=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/TNMOC_Merlin_TONTO.jpg&quot; alt=&quot;Merlin TONTO&quot; width=&quot;300&quot;/&gt;&lt;/a&gt;
&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/TNMOC_Merlin_TONTO.jpg&quot;&gt;Merlin TONTO&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Este museo es muy pequeño, pero tiene voluntarios que explican con pasión lo que allí se encuentra, y merece la pena dedicarle el tiempo necesario para apreciar todo lo que tiene en tan poco espacio. Salí algo desencantado de allí por estacuestión, pensando qué mejor aprovechamiento podría hacerse de la exposición con más terreno, porque uno no es conciente de las maravillas que ese museo guarda.&lt;/p&gt;
&lt;p&gt;Se puede visitar en un &lt;a href=&quot;https://www.tnmoc.org/3d-virtual-tour-2026&quot;&gt;tour 3D online&lt;/a&gt; y ver todo con detalle. Y su página web está muy bien organizada.&lt;/p&gt;
&lt;p&gt;Antes de regresar, después de ver los dinosaurios del Museo de Historia Natural, visitamos lo poco que pudimos ver del Museo de la Ciencia, por falta de tiempo, donde además de cosas del espacio, encontramos máquinas tan interesantes como lo que queda del &lt;code&gt;LEO&lt;/code&gt; de Lyons, el primer ordenador comercial, un &lt;code&gt;PDP 10&lt;/code&gt;, un &lt;code&gt;IBM 360&lt;/code&gt; o un &lt;code&gt;Control Data 6600&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/Science_Museum_LEO_Lyons_computer.jpg&quot;&gt;&lt;img src=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/Science_Museum_LEO_Lyons_computer.jpg&quot; alt=&quot;LEO&quot; width=&quot;300&quot;/&gt;&lt;/a&gt;
&lt;a href=&quot;https://javguerra.badared.com/galeria/photos/2024-12-COMPUTER-LONDON/Science_Museum_LEO_Lyons_computer.jpg&quot;&gt;LEO&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si viajáis a Londres, ya tenéis plan turístico retro.&lt;/p&gt;
&lt;h2 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://javguerra.badared.com/galeria/?dir=2024-12-COMPUTER-LONDON&quot;&gt;Galería de fotos completa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bletchleypark.org.uk/&quot;&gt;Bletchley Park&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://es.wikipedia.org/wiki/Mujeres_en_Bletchley_Park&quot;&gt;Mujeres en Bletchley Park&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.tnmoc.org/&quot;&gt;The National Museum Of Computing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sciencemuseum.org.uk/home&quot;&gt;Museo de la Ciencia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/TNMOC_IBM_PC.RzqfNVsY_1kj0xJ.webp"/><category>algoritmia</category><category>computación</category><category>historia</category><category>londres</category><category>museo</category><category>criptografía</category><category>fotografía</category><category>internet</category><category>retro</category><category>servidor</category><category>sinclair ql</category><category>tic</category><category>viaje</category><category>enigma</category><author>JavGuerra</author></item><item><title>Acceder a BBDD Oracle con DBeaver</title><link>https://javguerra.github.io/blog/oracle-dbeaver</link><guid isPermaLink="true">https://javguerra.github.io/blog/oracle-dbeaver</guid><description>Configuración de la aplicación con los drivers originales</description><pubDate>Wed, 10 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/oracle-dbeaver.S-D27cKr_Z2a51YS.webp&quot; alt=&quot;Pantalla de ordenador con DBeaver conectado a BBDD Oracle&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;#herramienta&lt;/em&gt;, &lt;em&gt;#servidor&lt;/em&gt;, &lt;em&gt;#bbdd&lt;/em&gt;, &lt;em&gt;#software libre&lt;/em&gt;, &lt;em&gt;#oracle&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;https://dbeaver.io/&quot;&gt;DBeaver&lt;/a&gt; es una herramienta de gestión de bases de datos multiplataforma y de código abierto que permite conectarse y trabajar con distintos sistemas como Oracle, MySQL, PostgreSQL o SQL Server desde una única interfaz. Ofrece funcionalidades como ejecución de consultas SQL, exploración de estructuras, edición de datos y administración de conexiones, destacando por su flexibilidad y compatibilidad con múltiples drivers. En esta te explico cómo instalar los drivers originales de Oracle en DBeaver.&lt;/p&gt;
&lt;h2 id=&quot;descargando-dbeaver&quot;&gt;Descargando DBeaver&lt;/h2&gt;
&lt;p&gt;Puedes descargar la última versión de la aplicación desde:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://dbeaver.io/download/&quot;&gt;Download DBeaver Community&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hay disponibles versiones para Windows, macOS y Linux.&lt;/p&gt;
&lt;p&gt;Si vas a descargar la versión de Windows, dispones también de un fichero &lt;code&gt;.zip&lt;/code&gt; que no requiere instalación en el sistema. Tan sólo descomprimes la carpeta en el lugar que decidas y la aplicación estará lista para usarse.&lt;/p&gt;
&lt;h2 id=&quot;el-problema&quot;&gt;El problema&lt;/h2&gt;
&lt;p&gt;Elegí esta herramienta porque, como otras, me permite acceder a la BBDD desde mi entorno local, pero empleando los drivers originales de Oracle, con lo que consigo la máxima compatibilidad, con un software versátil y abierto. Pero al seguir los pasos para descargar automáticamente los drivers:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Abrir DBeaver.&lt;/li&gt;
&lt;li&gt;Ir a &lt;code&gt;Database&lt;/code&gt; → &lt;code&gt;Driver Manager&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Buscar &lt;code&gt;Oracle&lt;/code&gt; en la lista y seleccionarlo.&lt;/li&gt;
&lt;li&gt;Pulsar &lt;code&gt;Edit&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Ir a la pestaña &lt;code&gt;Libraries&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Y pulsar &lt;code&gt;Download/Update&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Obtuve un error. Ocurre que Oracle no permite la descarga automática directa en muchos casos, así que DBeaver falla.&lt;/p&gt;
&lt;h2 id=&quot;la-alternativa&quot;&gt;La alternativa&lt;/h2&gt;
&lt;p&gt;Descargar los drivers directamente desde la página de Oracle:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.oracle.com/database/technologies/appdev/jdbc-downloads.html&quot;&gt;Oracle Database JDBC driver and Companion Jars Downloads&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Deberás seleccionar los drivers adecuados. En mi caso decidí descargar el fichero &lt;code&gt;ojdbc11-full.tar.gz&lt;/code&gt; bajo el título &lt;code&gt;Zipped JDBC driver (ojdbc11.jar) and Companion Jars&lt;/code&gt; que viene con todos los ficheros necesarios y está certificado para las versiones JDK 11 de Java (en mi caso) y versiones superiores.&lt;/p&gt;
&lt;p&gt;Una vea descargado, hay que descomprimir el contenido en la carpeta que desees. También puedes descomprimirlo en la carpeta &lt;code&gt;pluggins&lt;/code&gt; dentro de la carpeta de DBeaver.&lt;/p&gt;
&lt;h2 id=&quot;instalando-los-drivers&quot;&gt;Instalando los drivers&lt;/h2&gt;
&lt;p&gt;El siguiente paso es instalar los drivers en la aplicación. Por defecto, DBeaver carga cuatro de ellos.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ojdbc11.jar&lt;/code&gt; (la versión para mi JDK.) Obligatorio. El driver JDBC principal de Oracle que permite la conexión a BBDD.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;orai18n.jar&lt;/code&gt; Recomendado. Es el soporte de internacionalización (i18n) que permite manejar caracteres especiales, codificaciones (UTF-8, etc.) y distintos idiomas correctamente.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xdb.jar&lt;/code&gt; Opcional. Librería para XML DB de Oracle si se trabaja con XML almacenado en la base de datos y se requieren funcionalidades avanzadas tipo XMLType.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xmlparserv2.jar&lt;/code&gt; Opcional. Parser XML de Oracle para procesar XML internamente y dar soporte a funcionalidades de xdb.jar.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Para ello debes estar en la pestaña &lt;code&gt;libraries&lt;/code&gt; del driver Oracle en la en la opción &lt;code&gt;Driver manager&lt;/code&gt; del menú &lt;code&gt;Database&lt;/code&gt;. Ver pasos para llegar más arriba. Y una vez allí:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Pulsamos &lt;code&gt;Add File&lt;/code&gt;, seleccionamos cada fichero mencionado, y le damos a &lt;code&gt;Open&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Repetimos la opción por cada fichero.&lt;/li&gt;
&lt;li&gt;Una vez tenemos todos los drivers abiertos, ya no necesitamos los drivers que aparecen por defecto. Los quitamos con &lt;code&gt;Delete&lt;/code&gt; para que no den problemas.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;conectar-a-la-bbdd&quot;&gt;Conectar a la BBDD&lt;/h2&gt;
&lt;p&gt;Ahora ya podemos ver si todo ha ido bien.&lt;/p&gt;
&lt;p&gt;En el menú &lt;code&gt;Database&lt;/code&gt;, hacemos clic en la opción &lt;code&gt;New connection&lt;/code&gt; e introducimos los datos de la conexión. La nueva conexión a BBDD aparecerá en el espacio de conexiones de la izquierda.&lt;/p&gt;
&lt;h2 id=&quot;tips&quot;&gt;TIPs&lt;/h2&gt;
&lt;p&gt;Podemos arrastrar el nombre de la BBDD a &lt;code&gt;Bookmarks&lt;/code&gt; (Favoritos) en la lista de abajo, a la izquierda, para poder acceder de forma fácil a ella.&lt;/p&gt;
&lt;p&gt;También podemos poner DBeaver en español. Para esto iremos a &lt;code&gt;Windows&lt;/code&gt;, luego &lt;code&gt;Preferences&lt;/code&gt;, y en la opción &lt;code&gt;User Interface&lt;/code&gt; elegiremos el idioma español.&lt;/p&gt;
&lt;p&gt;Para más información sobre el uso de DBeaver, puedes consultar la documentación en el Wiki:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/dbeaver/dbeaver/wiki&quot;&gt;About DBeaver&lt;/a&gt;&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://dbeaver.io/&quot;&gt;DBeaver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/dbeaver/dbeaver/wiki&quot;&gt;About DBeaver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dbeaver.io/download/&quot;&gt;Download DBeaver Community&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.oracle.com/database/technologies/appdev/jdbc-downloads.html&quot;&gt;Oracle Database JDBC driver and Companion Jars Downloads&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/oracle-dbeaver.S-D27cKr_Z2a51YS.webp"/><category>herramienta</category><category>servidor</category><category>bbdd</category><category>software libre</category><category>oracle</category><author>JavGuerra</author></item></channel></rss>