007. Renderizado Dinámico

En el capítulo anterior habíamos terminado de maquetar y programar la cabecera de nuestra SPA. En este capítulo vamos a programar la parte que va fuera de la cabecera, que es donde vamos a tener los posts que traeremos del sitio WordPress sobre el que estemos consumiendo los datos.

Crearemos un archivo denominado Posts.js, dentro de la carpeta components que traerá todos los posts. Se trata de un componente funcional, de presentación, es por ello que lo incluimos en dicha carpeta, y no en la de helpers. Vamos a mandar a llamar al archivo posts.js en el archivo App.js.

También vamos a trabajar con el componente PostCard.js que creamos en el capítulo anterior, y que va a cobrar protagonismo en este capítulo. Dicho archivo nos va a permitir imprimir una tarjeta por cada post que traigamos. Esta PostCard se va a generar en el DOM por cada post que haya recibido la petición. La sintaxis de nuestro archivo PostCard.js va a tener el siguiente código.

Sintaxis de PostCard.js.

export function PostCard(props) {
  let { date, slug, title, _embedded } = props;
  let dateFormat = new Date(date).toLocaleDateString(),
    urlPoster = _embedded["wp:featuredmedia"]
      ? _embedded["wp:featuredmedia"][0].source_url
      : "app/assets/favicon.png";

  return `
        <article class="post-card">
            <img src="${urlPoster}" alt="${title.rendered}" />
            <h2>${title.rendered}</h2>
            <p>
                <time datetime="${dateFormat}">${dateFormat}</time>
                <a href="#/${slug}">Ver publicación</a>
            </p>
        </article>
    `;
}

La sintaxis de nuestro archivo Posts.js sería el siguiente.

export function Posts() {
  const $posts = document.createElement("section");
  $posts.id = "posts";
  $posts.classList.add("grid-fluid");

  return $posts;
}

Asimismo hemos tenido que modificar el archivo App.js, que queda con la siguiente sintaxis.

import api from "./helpers/wp-api.js";
import { ajax } from "./helpers/ajax.js";
import { Header } from "./components/Header.js";
import { Loader } from "./components/Loader.js";
import { Posts } from "./components/Posts.js";
import { PostCard } from "./components/PostCard.js";

export function App() {
  const d = document,
    $root = d.getElementById("root");

  $root.appendChild(Header());
  $root.appendChild(Posts());
  $root.appendChild(Loader());

  ajax({
    url: api.POSTS,
    cbSuccess: (posts) => {
      console.log(posts);
      let html = "";
      posts.forEach((post) => {
        html += PostCard(post);
      });
      d.querySelector(".loader").style.display = "none";
      d.getElementById("posts").innerHTML = html;
    },
  });
}

También vamos a modificar el archivo style.css, que quedaría como sigue.

html {
  box-sizing: border-box;
  font-family: sans-serif;
  font-size: 16px;
}

*,
*::after,
*::before {
  box-sizing: inherit;
}

body {
  margin: 0;
  overflow-x: hidden;
}

a {
  color: #01579b;
  transition: color 0.3s ease;
}

a:hover {
  color: #00b00f;
}

h1 {
  text-align: center;
}

img {
  max-width: 100%;
  height: auto;
}

.error {
  padding: 1rem;
  font-size: 150%;
  font-weight: bold;
  text-align: center;
  color: #fff;
  background-color: #dc3545;
}

.form-search {
  margin: auto;
  text-align: center;
}

.form-search input {
  display: block;
  margin: auto;
  padding: 0.25rem;
  border-radius: 0.25rem;
  font-size: 1rem;
}

.grid-fluid {
  margin: 1rem auto;
  max-width: 90%;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

.header {
  padding: 0.5rem;
  position: sticky;
  top: 0;
  text-align: center;
  background-color: #fff;
}

.header > * {
  margin: 1rem auto;
}

.loader {
  margin: 1rem auto;
  display: block;
  width: 4rem;
  height: 4rem;
}

.post-card {
  margin: 1rem auto;
  padding: 1rem;
  width: 80%;
  background-color: #eceff1;
}

.post-card p {
  display: flex;
  justify-content: space-between;
}

En este capítulo comenzaremos a hacer peticiones asíncronas para ver que recogemos la información, y poder pintar cada una de las tarjetas.

Archivos

Los archivos que tenemos hasta este capítulo son los siguientes:

Scroll al inicio