Primera tarea tras arrancar tu blog con Ghost y NGINX: el SITEMAP.

Este mes estamos de estreno.

Hemos migrado nuestro blog albertomorales.eu de Wordpress a Ghost

siguiendo las excelentes instrucciones de CarlosAzaustre.

Motivación

Las principales razón para tomar esta decisión ha sido la rapidez de la plataforma. La anterior web era infinitamente más lenta, empobreciendo la experiencia de usuario y penalizando por tanto los resultados SEO. Ya fuera por la tecnología PHP que utiliza Wordpress, o por la plantilla que teníamos instalada, los tiempos de respuesta eran totalmente inaceptables.

La segunda razón, no menos importante, es la simplicidad. Wordpress es un CMS que aunque se utiliza mayoritariamente para bloguear, es de propósito general, y esto aunque puede verse como una ventaja, en el caso de un blog, no lo es, ya que es necesario instalar un sinnúmero de plugins para que haga las cosas como queremos. Sitemaps, SEO, Analytics, etc... se maneja todo a base de "extras". Ghost no es un CMS de propósito general, sino una plataforma de blogging, y esto lo hace de forma notable, sin necesidad de plugins, todo lo necesario para bloguear viene "de serie". Y no solo simplicidad en el mantenimiento, sino también en la edición. Ya estaba harto de los editores de Wordpress. Ghost lo hace todo más simple, soporta Markdown, y esto hace que editar un post y darle formato, sea un juego de niños. Zapatero a tus zapatos. Si vas a crear contenido, quieres invertir el tiempo en eso, en el contenido, no batallando con la tecnología que soporta el blog.

Por otro lado y sacando nuestro perfil mas tech, PHP es una tecnología con la que nunca nos hemos identificado, sin embargo Node.js lo estamos utilizando tanto para proyectos personales como profesionalmente, por lo tanto nos encontramos cómodos con él. Y al cambiar el hosting a DigitalOcean para hospedar Ghost y NGINX nos permitirá hacer algo que teníamos previsto, aprovechar el mismo proveedor de hosting para hospedar proyectos personales desarrollados con Node.js a modo de portfolio.

Qué fácil es todo cuando utilizas la tecnología adecuada.

Por ejemplo, tener NGINX como proxy inverso "delante" de Ghost nos ha permitido configurar redirecciones de las URL's antiguas a las nuevas de forma simple. Esto debido a que las URL's antiguas eran del estilo albertomorales.eu/titulo-del-post y ahora las hemos cambiado a albertomorales.eu/blog/titulo-del-post. Esto para las entradas nuevas no es un problema, pero para todo el contenido antiguo indexado o enlazado desde el exterior era un problema. Con NGINX la redirección se configura de forma sencilla, en el archivo de configuración del site, por ejemplo:

    location /how-to-deal-with-a-legacy-schema-when-using-oracle-before-insert-trigger-for-id-generation-in-hibernate {
    return 301 /blog/how-to-deal-with-a-legacy-schema-when-using-oracle-before-insert-trigger-for-id-generation-in-hibernate ;
}

vemos como se le antepone /blog/ a una de las URL's (de un post antiguo) de forma que no se pierda tráfico entrante.

La estructura del sitio WEB:

"Delante" NGINX:

  • sirviendo el contenido estático (la URL /index.html es estática, y en un futuro cercano habrá más)
  • encargándose de las redirecciones de los post antiguos (como hemos explicado antes, a las URL's de las entradas antiguas se les antepone ahora /blog/) y
  • haciendo de proxy inverso, de forma que todas las peticiones a /blog se redirijan a Ghost , que escucha en otro puerto.

albertomorales.eu architecture

Una vez puestos en contexto vamos a hablar del tema de este post:

El sitemap.xml.

Un sitemap o mapa del sitio es el que contiene toda la información de todas las páginas del blog.
Es importante crear y mantener al día un mapa del sitio para las mejores prácticas SEO. Al fin y al cabo, si escribimos un post es para que lo lean, y para ello éste debe poder ser descubierto. Por esa razón es conveniente enviar el sitemap a Google y demás motores de búsqueda para que le facilitamos a los robots toda la información del blog y conozcan todas las páginas que hay en él, así a los robots les será más fácil indexar nuestro sitio; y un sitio bien indexado tiene mayores posibilidades de posicionamiento en la Web.

Ghost ya genera "de serie" su sitemap.xml

(recién instalado, sin ningún añadido), de forma que /blog/sitemap.xml responde:

http://albertomorales.eu/blog/sitemap-pages.xml
    (apunta a) ==> http://albertomorales.eu/blog/
http://albertomorales.eu/blog/sitemap-posts.xml
http://albertomorales.eu/blog/sitemap-authors.xml
http://albertomorales.eu/blog/sitemap-tags.xml

El contenido del blog está cubierto por este sitemap dinámico (como no podía ser de otra forma, Ghost lo tiene "todo"). Unicamente falta que el sitemap responda en la raiz del sitio (/sitemap.xml), y que referencie tanto al blog, como al contenido estático. En un primer intento, situamos en la raiz del sitio web (servido por NGINX) un archivo /sitemap.xml con el siguiente contenido:

http://albertomorales.eu/sitemap-static.xml
    (apunta a) http://albertomorales.eu/index.html (y demás)
http://albertomorales.eu/blog/sitemap.xml

De esta forma el /sitemap.xml cubre el contenido estático, y redirige al /blog/sitemap.xml, que genera Ghost. ¿Se entiende hasta aquí? Cual fue la sorpresa cuando, tras enviar el sitemap a Google, nos indica (con buen criterio) que tenemos un error de referencia cíclica:

http://albertomorales.eu/sitemap-static.xml
    (apunta a) http://albertomorales.eu/index.html (y demás)
http://albertomorales.eu/blog/sitemap.xml <==
http://albertomorales.eu/blog/sitemap-pages.xml
    (apunta a) http://albertomorales.eu/blog/ <==
http://albertomorales.eu/blog/sitemap-posts.xml
http://albertomorales.eu/blog/sitemap-authors.xml
http://albertomorales.eu/blog/sitemap-tags.xml

Hay dos entradas apuntando a http://albertomorales.eu/blog (las dos que hemos marcado con <==). Para evitar esto,

Tuvimos que hacer un pequeño "truco".

Salvamos en un archivo (/sitemap-blog.xml) el contenido del /blog/sitemap.xml, y eliminamos la primera línea:

http://albertomorales.eu/blog/sitemap-pages.xml
(apunta a) http://albertomorales.eu/blog/
http://albertomorales.eu/blog/sitemap-posts.xml
http://albertomorales.eu/blog/sitemap-authors.xml
http://albertomorales.eu/blog/sitemap-tags.xml

Adicionalmente le decimos a NGINX que, cuando llegue una petición de /blog/sitemap.xml, sirva este archivo (/sitemap-blog.xml) en vez de pasarle la petición a Ghost. Esto con NGINX nuevamente se configura de forma sencilla, en el archivo de configuración del site:

location /blog/sitemap.xml {
    return 301 /sitemap-blog.xml;
}

location /blog {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host       $http_host;
    proxy_pass     http://ghost;
    proxy_redirect   off;
}

Con este pequeño workaround, el sitemap queda:

http://albertomorales.eu/sitemap-static.xml
    (apunta a) http://albertomorales.eu/index.html (y demás)
http://albertomorales.eu/blog/sitemap.xml (/sitemap-blog.xml)
    http://albertomorales.eu/blog/sitemap-posts.xml
    http://albertomorales.eu/blog/sitemap-authors.xml
    http://albertomorales.eu/blog/sitemap-tags.xml

que ya no da ningún problema cuando lo remitimos a Google.

Espero que esta información pueda guiarte en tus primeros pasos. Queda mucho por hacer, por ejemplo construir una plantilla para el blog que no desentone con la página raíz. Pero eso ya es otra historia.