{"id":1643,"date":"2024-08-02T10:51:57","date_gmt":"2024-08-02T08:51:57","guid":{"rendered":"https:\/\/blog.sutilweb.eu\/?page_id=1643"},"modified":"2024-08-02T10:51:58","modified_gmt":"2024-08-02T08:51:58","slug":"10-wordpress-rest-api-y-fetch","status":"publish","type":"page","link":"https:\/\/sutilweb.eu\/index.php\/lenguajes\/javascript\/javascript-practico\/17-ejercicios-con-ajax\/10-wordpress-rest-api-y-fetch\/","title":{"rendered":"10. WordPress REST API y Fetch"},"content":{"rendered":"\n<p>En el cap\u00edtulo de hoy vamos a trabajar con la <strong>API REST<\/strong> que ofrece <strong>WordPress<\/strong>. Si tenemos acceso a un sitio hecho con <strong>WordPress<\/strong>, podemos crear un <strong>frontend<\/strong> absolutamente con las caracter\u00edsticas que necesitemos, muy al estilo de como hacen los generadores de sitios est\u00e1ticos como <a href=\"https:\/\/www.gatsbyjs.com\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Gatsby<\/strong><\/a>, <a href=\"https:\/\/jekyllrb.com\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Jekyll<\/strong><\/a>, <a href=\"https:\/\/gohugo.io\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Hugo<\/strong><\/a>, <a href=\"https:\/\/vuepress.vuejs.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">VuePress<\/a>, <a href=\"https:\/\/getpelican.com\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Pelican<\/strong><\/a>&#8230;&nbsp; Para ello lo primero que vamos a hacer es ir a la p\u00e1gina oficial de <strong>WordPress<\/strong>, <a href=\"https:\/\/wordpress.org\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/wordpress.org<\/a>, nos vamos a la documentaci\u00f3n, hay un concepto denominado <strong>the loop<\/strong> (<strong><em>The_Loop<\/em><\/strong>), que de hecho es la funci\u00f3n que tiene <strong>WordPress<\/strong> para traer la informaci\u00f3n de cada uno de las p\u00e1ginas o entradas de nuestro sitio. Es muy importante comprender qu\u00e9 es lo que ofrece esta <strong>funci\u00f3n<\/strong>. El enlace directo es <a href=\"https:\/\/codex.wordpress.org\/The_Loop\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/codex.wordpress.org\/The_Loop<\/a>. Todo lo que podamos <strong>modificar<\/strong>, <strong>insertar<\/strong>, <strong>eliminar<\/strong>&#8230; en definitiva, todo el <strong>CRUD<\/strong> que podemos hacer desde la interfaz de <strong>WordPress<\/strong>, lo podemos hacer desde la <strong>API REST<\/strong>.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Para consumir la informaci\u00f3n no son necesarias credenciales, va a depender de la seguridad que implementemos a nuestro <strong>WordPress<\/strong>, y si permitimos peticiones de tipo <strong>REST<\/strong>.<\/p>\n\n\n\n<p>En este ejercicio consumiremos tan s\u00f3lo informaci\u00f3n de tipo <strong>REST<\/strong>, no vamos a hacer peticiones para insertar una nueva entrada o un nuevo usuario, pero s\u00ed que podr\u00edamos publicar <strong>entradas<\/strong>, modificar <strong>categor\u00edas<\/strong>, hacer login con nuestro usuario&#8230; es decir, acceder a los dem\u00e1s verbos adicionales del m\u00e9todo <strong>GET<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">La funci\u00f3n The_Loop<\/h2>\n\n\n\n<p>Esta funci\u00f3n tiene la caracter\u00edstica de traer informaci\u00f3n de cada una de las entradas o p\u00e1ginas de nuestro blog. Informaci\u00f3n que nos puede dar son el t\u00edtulo de la publicaci\u00f3n (<strong><em>the_title()<\/em><\/strong>), la fecha en la cual fue creada (<strong><em>the_time()<\/em><\/strong>), la lista de categor\u00edas (<strong><em>the_cathegory()<\/em><\/strong>), la URL del art\u00edculo que estamos leyendo (<strong><em>the_permalink()<\/em><\/strong>), un peque\u00f1o contenido (<strong><em>the_excerp()<\/em><\/strong>), el contenido (<strong><em>the_content()<\/em><\/strong>) que es lo que escribimos en el editor de texto de <strong>WordPress<\/strong>, o en el editor de bloques <strong>Gutemberg<\/strong> si estamos trabajando a partir de la versi\u00f3n 5, la <strong>lista de etiquetas<\/strong>, el <strong>nombre del autor<\/strong>, incluso el <strong>avatar<\/strong> (imagen) del autor.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Nota<\/strong>: Son varias las p\u00e1ginas escritas en <strong>WordPress<\/strong>, como son <a href=\"https:\/\/css-tricks.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/css-tricks.com\/<\/a>, la web de la <strong>Casa Blanca<\/strong> en EEUU, la web de <strong>jQuery<\/strong>, la web de <strong>WordPress.org<\/strong>&#8230;<\/p>\n<\/blockquote>\n\n\n\n<p>Podemos acceder a los <strong>endpoints<\/strong> desde el enlace <a href=\"https:\/\/developer.wordpress.org\/rest-api\/reference\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/developer.wordpress.org\/rest-api\/reference\/<\/a>. De todo lo que podemos hacer con <strong>WordPress<\/strong>, en este cap\u00edtulo aprenderemos a consumir los <strong>posts<\/strong>, para lo cual comenzamos a trabajar creando el archivo <em>wp-api-rest.html<\/em>, el cual tendr\u00e1 la siguiente sintaxis.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Nota<\/strong>: cuando instalamos un sitio <strong>WordPress<\/strong>, por defecto tenemos el acceso libre para consumir el contenido. Existen varias rutas (<strong>endpoints<\/strong>) hacia la <strong>API WordPress<\/strong> que nos permiten acceder a <strong>posts<\/strong>, <strong>pages<\/strong>, <strong>users<\/strong>, <strong>categories<\/strong>. <strong>tags<\/strong>&#8230; del <strong>WordPress<\/strong><\/p>\n<\/blockquote>\n\n\n\n<p>Vamos a trabajar una t\u00e9cnica para guardar los <strong>endpoints<\/strong> que vayamos a consumir. La sintaxis que tenemos en nuestro archivo <em>wp-api-rest.html<\/em> es la siguiente<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"en\"&gt;\n&nbsp; &lt;head&gt;\n&nbsp; &nbsp; &lt;meta charset=\"UTF-8\" \/&gt;\n&nbsp; &nbsp; &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \/&gt;\n&nbsp; &nbsp; &lt;title&gt;Wordpress REST API&lt;\/title&gt;\n&nbsp; &nbsp; &lt;link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\" \/&gt;\n&nbsp; &nbsp; &lt;link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin \/&gt;\n&nbsp; &nbsp; &lt;link\n&nbsp; &nbsp; &nbsp; href=\"https:\/\/fonts.googleapis.com\/css2?family=Raleway:wght@100;700&amp;display=swap\"\n&nbsp; &nbsp; &nbsp; rel=\"stylesheet\"\n&nbsp; &nbsp; \/&gt;\n&nbsp; &nbsp; &lt;style&gt;\n&nbsp; &nbsp; &nbsp; html {\n&nbsp; &nbsp; &nbsp; &nbsp; box-sizing: border-box;\n&nbsp; &nbsp; &nbsp; &nbsp; font-family: \"Raleway\", sans-serif;\n&nbsp; &nbsp; &nbsp; &nbsp; font-size: 16px;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; *,\n&nbsp; &nbsp; &nbsp; *::after,\n&nbsp; &nbsp; &nbsp; *::before {\n&nbsp; &nbsp; &nbsp; &nbsp; box-sizing: inherit;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; a {\n&nbsp; &nbsp; &nbsp; &nbsp; color: #01579b;\n&nbsp; &nbsp; &nbsp; &nbsp; transition: all 0.3s ease-out;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; a:hover {\n&nbsp; &nbsp; &nbsp; &nbsp; opacity: 0.75;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; img {\n&nbsp; &nbsp; &nbsp; &nbsp; max-width: 100%;\n&nbsp; &nbsp; &nbsp; &nbsp; height: auto;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; h1 {\n&nbsp; &nbsp; &nbsp; &nbsp; text-align: center;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; hr {\n&nbsp; &nbsp; &nbsp; &nbsp; border: thin solid #01579b;\n&nbsp; &nbsp; &nbsp; &nbsp; margin: 3rem auto;\n&nbsp; &nbsp; &nbsp; &nbsp; width: 80%;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; .site {\n&nbsp; &nbsp; &nbsp; &nbsp; margin: 1rem auto;\n&nbsp; &nbsp; &nbsp; &nbsp; padding: 1rem;\n&nbsp; &nbsp; &nbsp; &nbsp; max-width: 50%;\n&nbsp; &nbsp; &nbsp; &nbsp; text-align: center;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; .post {\n  &nbsp; &nbsp; &nbsp; margin: 1rem auto;\n&nbsp; &nbsp; &nbsp; &nbsp; padding: 1rem;\n&nbsp; &nbsp; &nbsp; &nbsp; border-radius: 0.5rem;\n&nbsp; &nbsp; &nbsp; &nbsp; max-width: 80%;\n&nbsp; &nbsp; &nbsp; &nbsp; text-align: center;\n&nbsp; &nbsp; &nbsp; &nbsp; background-color: #eceff1;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; .post-author img {\n&nbsp; &nbsp; &nbsp; &nbsp; border-radius: 50%;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; .post-date {\n&nbsp; &nbsp; &nbsp; &nbsp; margin: 1rem auto;\n&nbsp; &nbsp; &nbsp; &nbsp; display: block;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; .post-excerpt,\n&nbsp; &nbsp; &nbsp; .post-categories,\n&nbsp; &nbsp; &nbsp; .post-tags,\n&nbsp; &nbsp; &nbsp; .post-content {\n&nbsp; &nbsp; &nbsp; &nbsp; text-align: left;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; .post-content summary {\n&nbsp; &nbsp; &nbsp; &nbsp; font-size: 1.5rem;\n&nbsp; &nbsp; &nbsp; &nbsp; font-weight: bold;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; .post-content &gt; article {\n&nbsp; &nbsp; &nbsp; &nbsp; padding: 1rem;\n&nbsp; &nbsp; &nbsp; &nbsp; background-color: #e3f2fd;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; .post-content img {\n&nbsp; &nbsp; &nbsp; &nbsp; display: block;\n&nbsp; &nbsp; &nbsp; &nbsp; margin: auto;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; .loader {\n&nbsp; &nbsp; &nbsp; &nbsp; display: none;\n&nbsp; &nbsp; &nbsp; &nbsp; margin: 2rem auto;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &lt;\/style&gt;\n&nbsp; &lt;\/head&gt;\n&nbsp; &lt;body&gt;\n&nbsp; &nbsp; &lt;h1&gt;Wordpress REST API&lt;\/h1&gt;\n&nbsp; &nbsp; &lt;article id=\"site\" class=\"site\"&gt;&lt;\/article&gt;\n&nbsp; &nbsp; &lt;section id=\"posts\" class=\"posts\"&gt;&lt;\/section&gt;\n&nbsp; &nbsp; &lt;img src=\"loader.svg\" alt=\"Cargando\" class=\"loader\" \/&gt;\n&nbsp; &nbsp; &lt;template id=\"post-template\"&gt;\n&nbsp; &nbsp; &nbsp; &lt;article class=\"post\"&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;img class=\"post-image\" \/&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;aside&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;h2 class=\"post-title\"&gt;&lt;\/h2&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;figure class=\"post-author\"&gt;&lt;\/figure&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;small class=\"post-date\"&gt;&lt;\/small&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;a target=\"_blank\" class=\"post-link\"&gt;Ver publicaci\u00f3n original&lt;\/a&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;p class=\"post-excerpt\"&gt;&lt;\/p&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=\"post-categories\"&gt;&lt;\/div&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=\"post-tags\"&gt;&lt;\/div&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;details class=\"post-content\"&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;summary&gt;Ver contenido de la publicaci\u00f3n&lt;\/summary&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;article&gt;&lt;\/article&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/details&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;\/aside&gt;\n&nbsp; &nbsp; &nbsp; &lt;\/article&gt;\n&nbsp; &nbsp; &nbsp; &lt;hr \/&gt;\n&nbsp; &nbsp; &lt;\/template&gt;\n&nbsp; &nbsp; &lt;script&gt;\n&nbsp; &nbsp; &nbsp; \/\/ Declaramos las variables que vamos a utilizar\n&nbsp; &nbsp; &nbsp; const d = document,\n&nbsp; &nbsp; &nbsp; &nbsp; w = window,\n&nbsp; &nbsp; &nbsp; &nbsp; $site = d.getElementById(\"site\"),\n&nbsp; &nbsp; &nbsp; &nbsp; $posts = d.getElementById(\"posts\"),\n&nbsp; &nbsp; &nbsp; &nbsp; $loader = d.querySelector(\".loader\"),\n&nbsp; &nbsp; &nbsp; &nbsp; $template = d.getElementById(\"post-template\").content,\n&nbsp; &nbsp; &nbsp; &nbsp; $fragment = d.createDocumentFragment();\n\n&nbsp; &nbsp; &nbsp; \/\/ Creaci\u00f3n de constantes ya que no se van a modificar los datos\n&nbsp; &nbsp; &nbsp; const DOMAIN = \"https:\/\/sutilweb.eu\",\n&nbsp; &nbsp; &nbsp; &nbsp; SITE = `${DOMAIN}\/wp-json`,\n&nbsp; &nbsp; &nbsp; &nbsp; API_WP = `${SITE}\/wp\/v2`,\n&nbsp; &nbsp; &nbsp; &nbsp; POSTS = `${API_WP}\/posts?_embed`,\n&nbsp; &nbsp; &nbsp; &nbsp; PAGES = `${API_WP}\/pages`,\n&nbsp; &nbsp; &nbsp; &nbsp; CATEGORIES = `${API_WP}\/categories`;\n\n&nbsp; &nbsp; &nbsp; let page = 1,\n&nbsp; &nbsp; &nbsp; &nbsp; perPage = 5;\n\n&nbsp; &nbsp; &nbsp; function getSiteData() {\n&nbsp; &nbsp; &nbsp; &nbsp; fetch(SITE)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .then((res) =&gt; (res.ok ? res.json() : Promise.reject(res)))\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .then((json) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(json);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $site.innerHTML = `\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;h3&gt;Sitio Web&lt;\/h3&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;h2&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;a href=\"${json.url}\" target=\"_blank\"&gt;${json.name}&lt;\/a&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/h2&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;p&gt;${json.description}&lt;\/p&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;p&gt;${json.timezone_string}&lt;\/p&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .catch((err) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(err);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let message = err.statusText || \"Ocurri\u00f3 un error\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $site.innerHTML = `&lt;p&gt;Error ${err.status}: ${message}&lt;\/p&gt;`;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; function getPost() {\n&nbsp; &nbsp; &nbsp; &nbsp; $loader.style.display = \"block\";\n&nbsp; &nbsp; &nbsp; &nbsp; fetch(`${POSTS}&amp;page=${page}&amp;per_page=${perPage}`)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .then((res) =&gt; (res.ok ? res.json() : Promise.reject(res)))\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .then((json) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(json);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; json.forEach((el) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/ Variables para recoger las categor\u00edas y las etiquetas\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let categories = \"\",\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tags = \"\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; el._embedded[\"wp:term\"][0].forEach(\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (el) =&gt; (categories += `&lt;li&gt;${el.name}&lt;\/li&gt;`)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; el._embedded[\"wp:term\"][1].forEach(\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (el) =&gt; (tags += `&lt;li&gt;${el.name}&lt;\/li&gt;`)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\".post-image\").src = el._embedded[\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \"wp:featuredmedia\"\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? el._embedded[\"wp:featuredmedia\"][0].source_url\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : \"\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\".post-image\").alt = el.title.rendered;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\".post-title\").innerHTML =\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; el.title.rendered;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\".post-author\").innerHTML = `\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;img src=\"${el._embedded.author[0].avatar_urls[\"48\"]}\" alt=\"${el._embedded.author[0].name}\"&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;figcaption&gt;${el._embedded.author[0].name}&lt;\/figcaption&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\".post-date\").innerHTML = new Date(\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; el.date\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ).toLocaleDateString();\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\".post-link\").href = el.link;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\".post-excerpt\").innerHTML =\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; el.excerpt.rendered;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\".post-categories\").innerHTML = `\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;p&gt;Categor\u00edas: &lt;\/p&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;ul&gt;${categories}&lt;\/ul&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\".post-tags\").innerHTML = `\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;p&gt;Etiquetas: &lt;\/p&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;ul&gt;${tags}&lt;\/ul&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\".post-content &gt; article\").innerHTML =\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; el.content.rendered;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let $clone = d.importNode($template, true);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $fragment.appendChild($clone);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $posts.appendChild($fragment);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $loader.style.display = \"none\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .catch((err) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(err);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let message = err.statusText || \"Ocurri\u00f3 un error\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $posts.innerHTML = `&lt;p&gt;Error ${err.status}: ${message}&lt;\/p&gt;`;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $loader.style.display = \"none\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; d.addEventListener(\"DOMContentLoaded\", (e) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; getSiteData();\n&nbsp; &nbsp; &nbsp; &nbsp; getPost();\n&nbsp; &nbsp; &nbsp; });\n\n&nbsp; &nbsp; &nbsp; w.addEventListener(\"scroll\", (e) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; const { scrollTop, clientHeight, scrollHeight } = d.documentElement;\n&nbsp; &nbsp; &nbsp; &nbsp; console.log(scrollTop, clientHeight, scrollHeight);\n&nbsp; &nbsp; &nbsp; &nbsp; if (scrollTop + clientHeight &gt;= scrollHeight) {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(\"Cargar mas posts\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; page++;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; getPost();\n&nbsp; &nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; });\n&nbsp; &nbsp; &lt;\/script&gt;\n&nbsp; &lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>En el cap\u00edtulo de hoy vamos a trabajar con la API REST que ofrece WordPress. Si tenemos acceso a un [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1609,"menu_order":9,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-1643","page","type-page","status-publish","hentry"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Sutil Web","author_link":"https:\/\/sutilweb.eu\/index.php\/author\/sutilweb\/"},"uagb_comment_info":0,"uagb_excerpt":"En el cap\u00edtulo de hoy vamos a trabajar con la API REST que ofrece WordPress. Si tenemos acceso a un [&hellip;]","_links":{"self":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/1643","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/comments?post=1643"}],"version-history":[{"count":2,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/1643\/revisions"}],"predecessor-version":[{"id":1645,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/1643\/revisions\/1645"}],"up":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/1609"}],"wp:attachment":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/media?parent=1643"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}