Drupal & Astro
Drupal es una herramienta de gestión de contenidos de código abierto.
Requisitos previos
Sección titulada “Requisitos previos”Para empezar, necesitarás lo siguiente:
-
Un proyecto de Astro - Si aún no tienes un proyecto de Astro, nuestra guía de instalación te pondrá en marcha en poco tiempo.
-
Un sitio de Drupal - Si no has configurado un sitio de Drupal, puedes seguir las directrices oficiales de instalación de Drupal.
Integrar Drupal con Astro
Sección titulada “Integrar Drupal con Astro”Instalar el módulo JSON:API de Drupal
Sección titulada “Instalar el módulo JSON:API de Drupal”Para poder obtener contenido de Drupal, necesitas habilitar el módulo JSON:API de Drupal.
- Navega a la página de extensiones
admin/modulesa través del menú de administración Manage. - Localiza el módulo JSON:API y marca la casilla que se encuentra a su lado
- Haz clic en Install para instalar el nuevo módulo
Ahora puedes realizar solicitudes GET a tu aplicación de Drupal a través de JSON:API.
Añadir la URL de Drupal en .env
Sección titulada “Añadir la URL de Drupal en .env”Para añadir la URL de tu sitio de Drupal a Astro, crea un archivo .env en la raíz de tu proyecto (si no existe ya uno) y añade la siguiente variable:
DRUPAL_BASE_URL="https://drupal.ddev.site/"Reinicia el servidor de desarrollo para usar esta variable de entorno en tu proyecto de Astro.
Configurar credenciales
Sección titulada “Configurar credenciales”Por defecto, el endpoint JSON:API de Drupal es accesible para solicitudes externas de obtención de datos sin necesidad de autenticación. Esto te permite obtener datos para tu proyecto de Astro sin credenciales, pero no permite que los usuarios modifiquen tus datos o la configuración del sitio.
Sin embargo, si deseas restringir el acceso y requerir autenticación, Drupal proporciona varios métodos de autenticación, incluyendo:
- Autenticación básica
- Autenticación basada en clave de API
- Autenticación basada en tokens de acceso/OAuth
- Autenticación basada en token JWT
- Autenticación de tokens de proveedores externos
Puedes añadir tus credenciales a tu archivo .env.
DRUPAL_BASIC_USERNAME="editor"DRUPAL_BASIC_PASSWORD="editor"DRUPAL_JWT_TOKEN="abc123"....env en Astro.
Tu directorio raíz ahora debería incluir estos nuevos archivos:
- .env
- astro.config.mjs
- package.json
Instalación de dependencias
Sección titulada "Instalación de dependencias"Las solicitudes y respuestas de JSON:API a menudo pueden ser complejas y estar profundamente anidadas. Para simplificar el trabajo con ellas, puedes usar dos paquetes de npm que agilizan tanto las solicitudes como la gestión de las respuestas:
JSONA: Serializador y deserializador de la especificación JSON API v1.0 para su uso en el servidor y en el navegador.Drupal JSON-API Params: Este módulo proporciona una clase auxiliar para crear la consulta requerida. Al hacerlo, también intenta optimizar la consulta utilizando la forma corta siempre que sea posible.
npm install jsona drupal-jsonapi-paramspnpm add jsona drupal-jsonapi-paramsyarn add jsona drupal-jsonapi-paramsObtener datos de Drupal
Sección titulada “Obtener datos de Drupal”Tu contenido se obtiene desde una URL de JSON:API.
Estructura de la URL de JSON:API de Drupal
Sección titulada “Estructura de la URL de JSON:API de Drupal”La estructura básica de la URL es: /jsonapi/{entity_type_id}/{bundle_id}
La URL siempre está precedida por jsonapi.
- El
entity_type_idse refiere al tipo de entidad, como node, block, user, etc. - El
bundle_idse refiere a los paquetes de entidad. En el caso de un tipo de entidad Node, el bundle podría ser article. - En este caso, para obtener la lista de todos los artículos, la URL será
[DRUPAL_BASE_URL]/jsonapi/node/article.
Para recuperar una entidad individual, la estructura de la URL será /jsonapi/{entity_type_id}/{bundle_id}/{uuid}, donde uuid es el UUID de la entidad. Por ejemplo, la URL para obtener un artículo específico será de la forma /jsonapi/node/article/2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e.
Recuperar solo ciertos campos
Sección titulada “Recuperar solo ciertos campos”Recupera solo ciertos campos añadiendo el campo Query String a la solicitud.
GET: /jsonapi/{entity_type_id}/{bundle_id}?field[entity_type]=field_list
Ejemplos:
/jsonapi/node/article?fields[node--article]=title,created/jsonapi/node/article/2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e?fields[node--article]=title,created,body
Filtrar
Sección titulada “Filtrar”Añade un filtro a tu solicitud agregando el filtro Query String.
El filtro más simple y común es un filtro de clave-valor:
GET: /jsonapi/{entity_type_id}/{bundle_id}?filter[field_name]=value&filter[field_other]=value
Ejemplos:
/jsonapi/node/article?filter[title]=Testing JSON:API&filter[status]=1/jsonapi/node/article/2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e?fields[node--article]=title&filter[title]=Testing JSON:API
Puedes encontrar más opciones de consulta en la documentación de JSON:API.
Crear una consulta de Drupal
Sección titulada “Crear una consulta de Drupal”Los componentes de Astro pueden obtener datos de tu sitio de Drupal utilizando el paquete drupal-jsonapi-params para construir la consulta.
El siguiente ejemplo muestra un componente con una consulta para un tipo de contenido “article” que tiene un campo de texto para un título y un campo de texto enriquecido para el contenido:
---import {Jsona} from "jsona";import {DrupalJsonApiParams} from "drupal-jsonapi-params";import type {TJsonApiBody} from "jsona/lib/JsonaTypes";
// Get the Drupal base URLexport const baseUrl: string = import.meta.env.DRUPAL_BASE_URL;
// Generate the JSON:API Query. Get all title and body from published articles.const params: DrupalJsonApiParams = new DrupalJsonApiParams();params.addFields("node--article", [ "title", "body", ]) .addFilter("status", "1");// Generates the query string.const path: string = params.getQueryString();const url: string = baseUrl + '/jsonapi/node/article?' + path;
// Get the articlesconst request: Response = await fetch(url);const json: string | TJsonApiBody = await request.json();// Initiate Jsona.const dataFormatter: Jsona = new Jsona();// Deserialise the response.const articles = dataFormatter.deserialize(json);---<body> {articles?.length ? articles.map((article: any) => ( <section> <h2>{article.title}</h2> <article set:html={article.body.value}></article> </section> )): <div><h1>No Content found</h1></div> }</body>Puedes encontrar más opciones de consulta en la documentación de JSON:API de Drupal
Crear un blog con Astro y Drupal
Sección titulada “Crear un blog con Astro y Drupal”Con la configuración anterior, ahora puedes crear un blog que use Drupal como CMS.
Requisitos previos
Sección titulada “Requisitos previos”-
Un proyecto de Astro con
JSONAyDrupal JSON-API Paramsinstalados. -
Un sitio de Drupal con al menos una entrada - Para este tutorial, recomendamos comenzar con un nuevo sitio de Drupal con una instalación estándar.
En la sección Content de tu sitio de Drupal, crea una nueva entrada haciendo clic en el botón Add. Luego, elige Article y completa los campos:
- Title:
My first article for Astro! - Alias:
/articles/first-article-for astro - Descripción:
¡Este es mi primer artículo de Astro! ¡Veamos cómo se verá!
Haz clic en Save para crear tu primer artículo. Siéntete libre de añadir tantos artículos como desees.
- Title:
Mostrar una lista de artículos
Sección titulada "Mostrar una lista de artículos"-
Crea
src/types.tssi aún no existe y añade dos nuevas interfaces llamadasDrupalNodeyPathcon el siguiente código. Estas interfaces coincidirán con los campos de tu tipo de contenido article en Drupal y los campos de Path. Las usarás para tipar la respuesta de tus entradas de artículos.src/types.ts export interface Path {alias: stringpid: numberlangcode: string}export interface DrupalNode extends Record<string, any> {id: stringtype: stringlangcode: stringstatus: booleandrupal_internal__nid: numberdrupal_internal__vid: numberchanged: stringcreated: stringtitle: stringdefault_langcode: booleansticky: booleanpath: Path}Tu directorio src ahora debería incluir el nuevo archivo:
- .env
- astro.config.mjs
- package.json
Directoriosrc/
- types.ts
-
Crea un nuevo archivo llamado
drupal.tsbajosrc/apiy añade el siguiente código:src/api/drupal.ts import {Jsona} from "jsona";import {DrupalJsonApiParams} from "drupal-jsonapi-params";import type {DrupalNode} from "../types.ts";import type {TJsonApiBody} from "jsona/lib/JsonaTypes";// Get the Drupal Base Url.export const baseUrl: string = import.meta.env.DRUPAL_BASE_URL;Esto importará las bibliotecas requeridas como
Jsonapara deserializar la respuesta,DrupalJsonApiParamspara formatear la URL de la solicitud y los tipos Node y Jsona. También obtendrá labaseUrldel archivo.env.Tu directorio src/api ahora debería incluir el nuevo archivo:
- .env
- astro.config.mjs
- package.json
Directoriosrc/
Directorioapi/
- drupal.ts
- types.ts
-
En ese mismo archivo, crea la función
fetchUrlpara realizar la solicitud fetch y deserializar la respuesta.src/api/drupal.ts import {Jsona} from "jsona";import {DrupalJsonApiParams} from "drupal-jsonapi-params";import type {DrupalNode} from "../types.ts";import type {TJsonApiBody} from "jsona/lib/JsonaTypes";// Get the Drupal Base Url.export const baseUrl: string = import.meta.env.DRUPAL_BASE_URL;/*** Fetch url from Drupal.** @param url** @return Promise<TJsonaModel | TJsonaModel[]> as Promise<any>*/export const fetchUrl = async (url: string): Promise<any> => {const request: Response = await fetch(url);const json: string | TJsonApiBody = await request.json();const dataFormatter: Jsona = new Jsona();return dataFormatter.deserialize(json);} -
Crea la función
getArticles()para obtener todos los artículos publicados.src/api/drupal.ts import {Jsona} from "jsona";import {DrupalJsonApiParams} from "drupal-jsonapi-params";import type {DrupalNode} from "../types.ts";import type {TJsonApiBody} from "jsona/lib/JsonaTypes";// Get the Drupal Base Url.export const baseUrl: string = import.meta.env.DRUPAL_BASE_URL;/*** Fetch url from Drupal.** @param url** @return Promise<TJsonaModel | TJsonaModel[]> as Promise<any>*/export const fetchUrl = async (url: string): Promise<any> => {const request: Response = await fetch(url);const json: string | TJsonApiBody = await request.json();const dataFormatter: Jsona = new Jsona();return dataFormatter.deserialize(json);}/*** Get all published articles.** @return Promise<DrupalNode[]>*/export const getArticles = async (): Promise<DrupalNode[]> => {const params: DrupalJsonApiParams = new DrupalJsonApiParams();params.addFields("node--article", ["title","path","body","created",]).addFilter("status", "1");const path: string = params.getQueryString();return await fetchUrl(baseUrl + '/jsonapi/node/article?' + path);}Ahora puedes usar la función
getArticles()en un componente.astropara obtener todos los artículos publicados con los datos de cada título, cuerpo, ruta y fecha de creación. -
Ve a la página de Astro donde obtendrás los datos de Drupal. El siguiente ejemplo crea una página de inicio de artículos en
src/pages/articles/index.astro.Importa las dependencias necesarias y obtén todas las entradas de Drupal con un tipo de contenido de
articleusandogetArticles()mientras pasas la interfazDrupalNodepara tipar tu respuesta.src/pages/articles/index.astro ---import {Jsona} from "jsona";import {DrupalJsonApiParams} from "drupal-jsonapi-params";import type {TJsonApiBody} from "jsona/lib/JsonaTypes";import type { DrupalNode } from "../../types";import {getArticles} from "../../api/drupal";// Get all published articles.const articles = await getArticles();---Esta llamada de obtención utilizando getArticles() devolverá un array tipado de entradas que se pueden utilizar en la plantilla de tu página.
Tu directorio
src/pages/ahora debería incluir el nuevo archivo, si usaste el mismo archivo de página:- .env
- astro.config.mjs
- package.json
Directoriosrc/
Directorioapi/
- drupal.ts
Directoriopages/
Directorioarticles/
- index.astro
- types.ts
-
Añade contenido a tu página, como un título. Usa
articles.map()para mostrar tus entradas de Drupal como elementos en una lista.src/pages/articles/index.astro ---import {Jsona} from "jsona";import {DrupalJsonApiParams} from "drupal-jsonapi-params";import type {TJsonApiBody} from "jsona/lib/JsonaTypes";import type { DrupalNode } from "../types";import {getArticles} from "../api/drupal";// Get all published articles.const articles = await getArticles();---<html lang="en"><head><title>My news site</title></head><body><h1>My news site</h1><ul>{articles.map((article: DrupalNode) => (<li><a href={article.path.alias.replace("internal:en/", "")}><h2>{article.title}</h2><p>Published on {article.created}</p></a></li>))}</ul></body></html>
Generación de publicaciones de blog individuales
Sección titulada “Generación de publicaciones de blog individuales”Utiliza el mismo método para obtener tus datos de Drupal que se muestra arriba, pero esta vez, en una página que creará una ruta de página única para cada artículo.
Este ejemplo utiliza el modo estático predeterminado de Astro y crea un archivo de página de enrutamiento dinámico con la función getStaticPaths(). Esta función se llamará en el momento de la construcción para generar la lista de rutas que se convierten en páginas.
-
Crea un nuevo archivo
src/pages/articles/[path].astroe importa la interfazDrupalNodeygetArticle()desrc/api/drupal.ts. Obtén tus datos dentro de una funcióngetStaticPaths()para crear rutas para tu blog.src/pages/articles/[path].astro ---import {Jsona} from "jsona";import {DrupalJsonApiParams} from "drupal-jsonapi-params";import type {TJsonApiBody} from "jsona/lib/JsonaTypes";import type { DrupalNode } from "../../types";import {getArticles} from "../../api/drupal";// Get all published articles.export async function getStaticPaths() {const articles = await getArticles();}---Tu directorio src/pages/articles ahora debería incluir el nuevo archivo:
- .env
- astro.config.mjs
- package.json
Directoriosrc/
Directorioapi/
- drupal.ts
Directoriopages/
Directorioarticles/
- index.astro
- [path].astro
- types.ts
-
En el mismo archivo, mapea cada entrada de Drupal a un objeto con una propiedad
paramsy otraprops. La propiedadparamsse utilizará para generar la URL de la página y los valores depropsse pasarán al componente de la página como propiedades (props).src/pages/articles/[path].astro ---import {Jsona} from "jsona";import {DrupalJsonApiParams} from "drupal-jsonapi-params";import type {TJsonApiBody} from "jsona/lib/JsonaTypes";import type { DrupalNode } from "../../types";import {getArticles} from "../../api/drupal";// Get all published articles.export async function getStaticPaths() {const articles = await getArticles();return articles.map((article: DrupalNode) => {return {params: {// Choose `path` to match the `[path]` routing valuepath: article.path.alias.split('/')[2]},props: {title: article.title,body: article.body,date: new Date(article.created).toLocaleDateString('en-EN', {day: "numeric",month: "long",year: "numeric"})}}});}---La propiedad dentro de
paramsdebe coincidir con el nombre de la ruta dinámica. Dado que el nombre del archivo es[path].astro, el nombre de la propiedad pasada aparamsdebe serpath.En nuestro ejemplo, el objeto
propspasa tres propiedades a la página:title: una cadena de texto (string), que representa el título de tu publicación.body: una cadena de texto (string), que representa el contenido de tu entrada.date: una marca de tiempo (timestamp), basada en la fecha de creación de tu archivo.
-
Usa las
propsde la página para mostrar tu publicación de blog.src/pages/articles/[path].astro ---import {Jsona} from "jsona";import {DrupalJsonApiParams} from "drupal-jsonapi-params";import type {TJsonApiBody} from "jsona/lib/JsonaTypes";import type { DrupalNode } from "../../types";import {getArticles} from "../../api/drupal";// Get all published articles.export async function getStaticPaths() {const articles = await getArticles();return articles.map((article: DrupalNode) => {return {params: {path: article.path.alias.split('/')[2]},props: {title: article.title,body: article.body,date: new Date(article.created).toLocaleDateString('en-EN', {day: "numeric",month: "long",year: "numeric"})}}});}const {title, date, body} = Astro.props;---<html lang="en"><head><title>{title}</title></head><body><h1>{title}</h1><time>{date}</time><article set:html={body.value} /></body></html> -
Navega a la vista previa del servidor de desarrollo y haz clic en una de tus publicaciones para asegurarte de que tu ruta dinámica esté funcionando.
Publicando tu sitio
Sección titulada "Publicando tu sitio"Para desplegar tu sitio web, visita nuestras guías de despliegue y sigue las instrucciones para tu proveedor de alojamiento preferido.
Recursos de la comunidad
Sección titulada "Recursos de la comunidad"Si encontraste (¡o creaste!) un video o una publicación de blog útil sobre el uso de Drupal con Astro, ¡añádelo a esta lista!
Más guías de CMS
Socios de CMS destacados
-
CloudCannon
CMS basado en Git creado para mayor velocidad, seguridad y cero dolores de cabeza.