Lecciones aprendidas al portar desde Jekyll
Sep 19, 2021
Reading time: 6 minutes
En los últimos 6 años he construido unas 30 webs con Jekyll al año. Hace poco me pasé por completo a Hugo y he portado varios sitios web de Jekyll a Hugo. Por el camino aprendí unas cuantas cosas que tú también necesitarás saber cuando des el paso de Jekyll a Hugo. Me ha costado bastante aprender Hugo, pero al final ha merecido la pena, sobre todo por los bajos tiempos de construcción y la conversión de imágenes integrada que he ganado.
Ten en cuenta que este va a ser un documento vivo, así que asegúrate de volver más adelante para consultarlo de nuevo.
Estructura de directorios
Colecciones
En Hugo las ‘colecciones’ se llaman ‘secciones’. Personalmente ese nombre no me gusta nada, pero hay que vivir con ello. Una sección es un directorio de primer nivel dentro del directorio ‘content’ O un directorio que contenga un archivo ‘_index.md’. Un directorio con un archivo ‘index.md’ NO es una sección (sino un ‘page bundle’). Cuando creas un sitio web multilingüe usas los directorios de primer nivel para los idiomas y los de segundo nivel para las secciones/colecciones.
Layouts
Puedes tener layouts que nombres en tu front matter, pero esos layouts deben vivir en el directorio de su sección dentro del directorio ’layouts’. Para las páginas ese debería ser el directorio ‘page’.
Archivos de contenido
Mientras que Jekyll da por hecho que todos los archivos .md son contenido, Hugo te obliga a usar un directorio de contenido (‘content’ por defecto) y poner tus archivos .md en él.
Archivos estáticos
Jekyll asume que todos los archivos son estáticos. Ese no es el caso en Hugo. Cuando tienes archivos estáticos, como hojas de estilo o imágenes, debes ponerlos en el directorio ‘static’.
Data
‘data’ es el único directorio que es igual en Jekyll y en Hugo. Puedes renombrar tus ‘.yml’ a ‘.yaml’ para que sean compatibles con versiones antiguas de Hugo.
Construcciones
Jekyll construye tu web en el directorio ‘_site’ con cada actualización. Hugo solo construye tu web cuando ejecutas el comando hugo (en lugar de ‘hugo server’). Hugo construye tu web en un directorio llamado ‘public’.
Resources
Hugo es capaz de redimensionar imágenes. Esas imágenes redimensionadas acaban en el directorio ‘resources’, dentro de la carpeta ‘gen’. Jekyll no tiene ese directorio ni esa funcionalidad.
Ajustes de configuración
Sobre el archivo de configuración
En Jekyll el archivo de configuración se llama ‘_config.yml’. En Hugo es ‘hugo.yaml’. Ten en cuenta que en versiones modernas de Hugo también puedes usar la extensión ‘yml’. Otra cosa llamativa es que Jekyll te obliga a listar tus colecciones en el archivo de configuración. Hugo no tiene ese requisito.
Evitar la salida
Cuando quieres evitar la salida de una sección/colección, en el archivo de configuración de Jekyll puedes escribir ‘output: false’. Eso no es posible en Hugo. La solución alternativa es crear un ‘page.html’ vacío en el directorio ’layouts’, dentro de la carpeta correspondiente a la sección/colección a la que quieres aplicarlo. Hay otro truco que funciona, que es este.
Definir permalinks
En Jekyll me encanta usar ‘permalinks: pretty’ y luego algunos valores por defecto específicos para cada colección. En Hugo esto funciona un poco distinto. Hugo te permite simplemente listar todas las secciones bajo la clave ‘permalinks’ en el archivo de configuración. Un par clave-valor lógico (bajo esa clave) sería ‘sectionname: /desiredpath/:filename’. La última parte (:filename) representa el nombre del archivo sin extensión. Otro ejemplo es ‘posts: /:year/:month/:title/’. Esto convierte el título en slug y añade el año y el mes para evitar colisiones de URL.
Variables de sitio personalizadas
Las variables de sitio personalizadas no se escriben como hijas de la raíz, sino como hijas de la clave ‘params’ en el archivo de configuración. Se pueden invocar usando ‘.Site.Params.customvariable’, donde ‘customvariable’ es el nombre de tu variable personalizada.
Trucos y consejos
Redimensionar todas las imágenes del usuario
Para poder usar todas las imágenes del usuario como recursos, basta con añadir ‘assetDir: static’ a tu archivo de configuración. Después puedes redimensionar imágenes invocando:
((resources.GetMatch .Params.image).Fit "600x600 jpg Center q50").RelPermalink.
Obtener el slug de la página
No existe nada como page.slug. En su lugar tienes que usar .File.BaseFileName.
Cache busting de tu style.css
Usa <link href='/css/style.css?version={{ now }}' rel='stylesheet' type='text/css'> para hacer cache busting de tu archivo CSS.
Una relación de muchos a muchos
Si por ejemplo quieres que un ‘coche’ tenga un array de ‘características’ compartidas entre coches, normalmente estás ante una relación de muchos a muchos. Un coche tiene muchas características y una característica pertenece a muchos coches. Puedes modelar esto creando una página para tu coche con un array de características en el front matter. En lugar de escribir la característica completa en tu front matter, solo pones el slug de la característica. Después creas una sección aparte de características que coincidan con esas claves. Esas claves te permiten encontrar el elemento/página correspondiente en la sección de características. El código para esto es bastante compacto y se ve así:
{{- range .Params.features -}}
{{ with $.Site.GetPage (print "/features/" . ".md") }}
{{ .Title }}
{{ end }}
{{ end }}
Nombre del archivo de la página de inicio
El nombre del archivo de tu página de inicio DEBE ser ‘_index.md’. De lo contrario tus secciones no funcionarán correctamente. Fíjate en el guion bajo.
Formatear fechas
Para formatear fechas automáticamente deberías añadir lo siguiente a tu archivo de configuración:
defaultContentLanguage: nl
languageCode: nl_NL
Después puedes usar este comando para mostrar una fecha específica del idioma: {{ .Date | time.Format ":date_long" }}.
Configuración multilingüe
Cuando quieres una configuración multilingüe tienes que usar defaultContentLanguage: nl en el nivel raíz de tu archivo hugo.yaml. Además necesitas una variable ’languages’, que se ve más o menos así:
languages:
en:
languageName: English
title: Website title
description: Website description in English
contentDir: content/english
permalinks:
posts: /news/:filename/
weight: 2
nl:
languageName: Nederlands
title: Website titel
description: Website beschrijving in het Nederlands
contentDir: content/nederlands
permalinks:
posts: /nieuws/:filename/
weight: 1
Ten en cuenta que lo anterior define una carpeta de contenido nueva para cada idioma. Eso significa que tienes que crear una carpeta ’english’ y otra ’nederlands’ dentro de tu carpeta de contenido, que contendrán tus secciones.
Además necesitas traducciones de cadenas de texto. Esto se resuelve fácilmente creando una carpeta ‘i18n’ en la raíz de tu proyecto. Esta carpeta contiene un archivo ’en.yaml’ y otro ’nl.yaml’, cada uno parecido a esto (donde ‘other’ contiene la traducción):
other_news:
other: Overige nieuwsberichten
recent_news:
other: Recent nieuws
Invocar una de esas cadenas es tan fácil como escribir: {{ i18n "other_news" }}. En la plantilla también tendrás disponible la variable .Language, que devuelve la clave del idioma (’en’ o ’nl’ en este caso).
Dividir el contenido principal
Cuando quieras dividir tu contenido principal en varias partes puedes separarlas fácilmente, por ejemplo, por la etiqueta ‘h2’. En el código de abajo ves el comando ‘print’, que une varias cadenas en una sola, y el comando ‘| safeHTML’, que permite la salida de HTML.
{{ $content := split .Content "<h2" }}
<div class="part1">
{{ print "<h2" (index $content 1) | safeHTML }}
</div>
<div class="part2">
{{ print "<h2" (index $content 2) | safeHTML }}
</div>
Fenix
