Blog>

Roi Sánchez
03 May 2022

Como montar un proyecto de WordPress + Angular

Tiempo de lectura 9 minutos
  • angular
  • angular universal
  • ssr
  • web
  • WordPress

Sumario Detallamos los puntos cruciales para ser capaces de montar un proyecto Angular que se alimente completamente de un back end en WordPress

Queríamos intentar montar un proyecto usando Wordpress y Angular. La potencia de Angular para el Front End y la potencia de un CMS para la administración del portal. Nuestra primera opción fue buscar un CMS en Node, pero realmente no encontramos ningún CMS que nos convenciera. Por ello, pensamos en tirar por lo seguro, y pensando que sería Marketing quien tendría que mantener el portal, nos decantamos por WordPress. Es un sistema lo suficientemente estándar y seguro como para confiar en él y saber que se mantiene al día. 

Respecto al Front End, teníamos claro que queríamos usar Angular. El conocimiento que tenemos internamente sobre esta tecnología y las previsiones que teníamos de nuevas funcionalidades hacen que no tuviéramos ninguna duda en cuanto a la elección del Front End.

WordPress como headless CMS

Para hacer funcionar Wordpress y Angular, necesitamos usar WordPress como headless CMS, pero ¿qué esto del headless CMS? 

Headless CMS

Se trata de un sistema de Back End que solo gestiona el contenido, sirviendo ese contenido via servicios Rest. Por lo tanto, un headless CMS solo se centra en la gestión del contenido y el workflow de publicación. 

Como todo en esta vida tiene sus pros y sus contras. 

Ventajas:

Desventajas 

Tenéis un buen artículo explicando todo esto aquí: https://dzone.com/articles/headless-cms-as-a-microservice

Convertir WordPress en un Headless CMS

Una vez entendido qué es un headless CMS, nos ponemos manos a la obra en convertir WordPress en uno de ellos, ya que, por defecto no lo es. 

Esto lo tendréis en detalle en un próximo artículo de nuestro blog, pero básicamente lo que tenemos que hacer son varias cosas: 

Adicionalmente, tenemos que configurar la edición de las páginas, campos, Custom post types, etc, según nuestras necesidades como en cualquier otro proyecto WordPress. 

Es importante para conseguir un buen rendimiento usar un plugin de caché, nosotros usamos WP Rest Cache para cachear todas las llamadas API.

Una vez que tenemos claro qué es un Headless CMS, podemos seguir con el proceso de montar una web usando Wordpress y Angular.

Uso de Angular como tecnología de Front 

En el caso del Front End en principio sería un proyecto Angular normal y corriente, simplemente recuperando el contenido de las páginas desde un api. Eso es lo que puede parecer en un primer momento, pero realmente tiene algo más de complicación. Por un lado, en el momento de cargar la aplicación, no podemos saber qué páginas tenemos en nuestro sitio, por lo que parece que no podemos cargar un routing por defecto. Además, si queremos aprovechar la capacidad de programación orientada a componentes más el sistema de bloques de WordPress, nos encontramos con que no sabemos la estructura de la página y qué componentes tenemos que cargar hasta que pedimos el contenido de la misma. También tenemos que cargar ciertas configuraciones y tenemos que evitar los posibles problemas de CORS. Por tanto, no es tan sencillo montar el site con esta estructura como puede parecer en un principio. 

Routing de Angular desde WordPress 

En este artículo no vamos a entrar en detalles de la implementación de esta solución, para eso haremos una nueva entrada en breve, pero explicaremos las problemáticas que nos hemos encontrado y las soluciones por las que hemos optado. 

Por defecto, Angular necesita que el routing exista antes de arrancar la aplicación, ya que se basa en esto para enrutar las peticiones al componente correcto.  

Lo primero que pensamos fue en cargar la home, en ese momento cargar la lista de rutas disponibles, y que a partir de ese momento ya funcionaran todas las rutas de la aplicación. Sin embargo, esto tampoco nos vale, ya que la entrada a la aplicación puede ser a través de cualquier punto. Es decir, si un usuario localiza en Google la página de un squad en concreto y accede, es esta la que se debe visualizar, y además con su plantilla correcta. 

Por otro lado, también tenemos que tener en cuenta que las rutas deben permitir la construcción de migas de pan (breadcrumbs), por lo que tienen que tener un formato jerárquico. 

Al final la solución ha pasado por una serie de acciones:

Ahora nos queda por resolver otro problema. ¿Qué pasa si el administrador cambia las rutas de las páginas mientras un usuario está navegando? No pasa nada 😊 Primero, para entender la solución adoptada, tenemos que pensar que esta web no va a estar cambiando de estructura continuamente, sino que será relativamente raro. Lo que hacemos es tener un servicio de tipo cron que está actualizando en segundo plano el sitemap y el routing cada x segundos. Realmente este servicio lo que hace es solicitar el sitemap al back end, lo comprara con el último que tenga (lo guardamos en local storage) y si la fecha de modificación es posterior al suyo actualiza el routing. Por lo tanto, en el 99.99% de las veces no hace nada. 

Carga de componentes en función de navegación 

Como decimos en el punto anterior, en función de la navegación se carga un componente u otro. Lo que hemos hecho para tener diferentes plantillas de página es hacer algo parecido a como lo gestiona WordPress. En el back end a cada página le asociamos una plantilla. Esta plantilla asociada la mandamos en el sitemap como metadato adjunto al elemento de navegación. Por tanto, al cargar el routing le asociamos su componente de Angular específico. Después al construir nuestra aplicación Angular tenemos los componentes que hemos decidido para cada plantilla con su maquetación específica. 

Carga de contenido en bloques 

Uno de los grandes objetivos que teníamos era conseguir montar todo este tinglado en Angular, con buen rendimiento, pero sin perder la potencia de gestión de contenidos de WordPress. Y en esta gestión de contenidos de WordPress una de las grandes bazas era mantener los bloques de Gütemberg. 

Para conseguir este objetivo lo que hemos hecho es, por un lado mantener los bloques de Gütemberg, pero creando nosotros bloques específicos usando ACF Pro, de forma que podamos controlar como se renderizan, e incluso permitiendo añadir de forma anidada los bloques estándar de WordPress dentro de nuestros bloques personalizados. 

Por otro lado, también en el back end creamos una serie de WS que devuelven el contenido de una página concreta, y básicamente lo que devuelve es la configuración y/o contenido de los bloques. 

En Angular tenemos un módulo que contiene un componente específico para cada uno de los bloques que hemos creado en WordPress y además otro componente para los bloques genéricos del core de WordPress. Por tanto, cuando procesamos el WS de contenido de la página lo que hacemos es analizar cada bloque que nos llega, asociarle el componente correcto, pasarle los datos que le corresponden y añadirlo a la pila de visualización. 

Configuración del site 

Hay cierta información que debemos mostrar en la web o que necesitamos para diferentes módulos que no tienen que ver con la carga de una página. Alguno de estos datos podría ser la información para mostrar el banner de cookies o información de metadatos generales. 

La estrategia en este caso es muy similar a lo que ya hemos visto. Esta información se maneja en pantallas de configuración en WordPress, se sirve vía un WS de configuración que se procesa asíncronamente en Angular y se utiliza vía servicios y componentes. 

Proxy 

Ya que tenemos dos sitios web diferentes sirviendo el contenido (WS y media) en WordPress y estáticos en Angular podríamos tener ciertos problemas de CORS. Esto simplemente lo hemos resuelto con una configuración de proxy inverso en nuestro nginx. 

Angular Universal SSR 

Angular para webs públicas tiene 2 problemas que no son fáciles de solucionar a primera vista. Por un lado que los robots y crawlers de los buscadores no ejecutan javascript, por lo que no pueden indexar el contenido de la web y segundo que el rendimiento de la primera carga no es el mejor al tener que inicializar un montón de procesos. 

Respecto a que los crawlers de los buscadores no ejecutan js, esto es una verdad a medias: no lo hacían. En estos momentos el crawler de Google ya lo hace (realmente es el que nos importa), pero por ejemplo Bing no lo hace y aunque en menor medida, también nos interesa. Respecto al rendimiento es una verdad como un templo 😉 

La solución a estos dos punto es convertir la aplicación a Angular Universal para usarla como SSR (Server side rendering), es decir, hacer una versión que se renderiza en servidor y la desplegamos vía Node en un express. De esta forma se carga más rápido porque ya hay renderizada una primera versión en html en el servidor, y en el tiempo en que se descarga y se muestra se inicializan todos los elementos de Angular en el cliente. De esta forma, el usuario la puede visualizar más rápido y como el tiempo de inicialización también es corto puede interactuar con la aplicación sin problemas. 

La mayor complicación es que no se puede acceder a nada del api del navegador, datos de aplicación en cliente, cookies, etc. Esto lo solucionamos con un observable, de forma que ciertas cosas solo lo hacemos cuando tengamos ejecución en cliente. 

Infraestructura

A nivel de infraestructura al final lo que necesitamos es: 

Esperamos que este artículo os haya servido y que a partir de ahora, sepáis como realizar un proyecto de Wordpress y Angular.

Autor

Roi Sánchez
Roi Sánchez

Desarrollador en dev&del

Capitán en Hello, World!

Capaz de gestionar un proyecto informático E2E (de principio a fin).

Los discos de vinilo y los tatuajes son dos de sus mayores pasiones.

¿Estás interesado?

Déjanos tus datos y contactaremos contigo lo antes posible