Centralizando valores repetidos para distintos idiomas en un solo lugar
Motivación
Este sitio es multi-lenguaje y tiene muchos parámetros en el front-matter, muchos de ellos se repiten entre las páginas en distintos lenguajes, viendo esa tendencia se me ocurrió encontrar la manera de compartir estos valores entre las páginas dentro de su propio page-bundle, para así evitar que un cambio se multiplique por la cantidad de lenguajes disponibles, y también para evitar errores no forzados en el proceso.
En este momento el sitio tiene dos lenguajes, pero planeo tener más, y tengo variables personalizadas en el front-matter que van en ascenso.
Limitaciones
No se puede aplicar valores compartidos para variables nativas de Hugo, por ejemplo las variables de taxonomy (tags, categories). Estas necesitan estar previamente en el documento para que hugo procese las taxonomies y no pueden ser utilizadas en el documento compartido.
¿Qué es un page-bundle?
Page bundle es una forma de organizar el contenido en Hugo, consta de una carpeta que contiene distintos tipos de archivos, idiomas de la página, por ejemplo:
Más información: Hugo docs - Page-bundles
Creando el archivo compartido
Se añade un archivo al page-bundle, este va a ser el archivo compartido, puede tener cualquier nombre, el mio se llama shared.md
siguiendo el ejemplo anterior sería:
En este archivo se agregan en el front-matter los valores que se van a compartir entre las páginas de distintos lenguajes:
---
headless: true
compartido1: 1
compartido2: "2"
compartido3: "tres"
---
Es muy importante agregar headless: true
, esto le va a indicar a hugo que esta página no debe ser mostrada como un single page, sino que solo puede ser accedida a través de otras páginas indirectamente.
Actualizando single.html
Una vez agregados los valores dentro del archivo shared.md
vamos a hacer modificaciones dentro del single.html
, para poder leer los valores compartidos en las páginas que son parte del bundle.
{{ $sharedParams := slice }}
{{ with .Page.Resources }}
{{ with .Match "shared.md" }}
{{ $sharedPage := index . 0 }}
{{ $sharedParams = $sharedPage.Params }}
{{ end }}
{{ end }}
{{ $params := collections.Merge .Page.Params $sharedParams }}
Se inicializa un array vacío para sharedParams
, luego usando .Page.Resources
obtenemos la lista de resources que están disponible dentro del page bundle, usando Match
se filtra el archivo que se necesita, y como match devuelve una lista, utilizamos index . 0
para obtener el primer elemento. Por último, se unen las dos listas.
Los valores compartidos sólo se muestran en el idioma principal.
Para mostrar los valores compartidos todos los idiomas, hay que buscar los recursos del idioma principal, desde el resto de los idiomas. Para ello necesitamos modificar el código:
{{ $sharedParams := slice }}
{{ $page := .Page }}
{{ with .Page.Resources }}
{{ with .Match "shared.md" }}
{{ $sharedPage := index . 0 }}
{{ $sharedParams = $sharedPage.Params }}
{{ else }}
{{ with $page.Translations }}
{{ range where . "Lang" "en" }}
{{ with .Resources.Match "shared.md" }}
{{ $sharedPage = index . 0}}
{{ $sharedParams = $sharedPage.Params }}
{{ end }}
{{ end }}
{{ end }}
{{ end }}
{{ end }}
{{ $params := collections.Merge .Page.Params $sharedParams }}
En caso de que la búsqueda inicial no encuentre resultados, buscamos la página en idioma principal, y a través de los resources buscamos nuestro archivo shared.md
para acceder a los valores compartidos.
A partir de aquí puedes hacer uso de los parámetros compartidos, y en vez de usar .Page.Params
deberías usar $params
.
Agradecimientos
Gracias a @Jmooring, del Discourse de Hugo tus palabras me ayudaron a ir por la dirección correcta
Gracias por leer!
Namaste.