in

Cambiar de WordPress a Hugo

WordPress es un CMS fantástico que impulsa una gran cantidad de sitios web, que tienen características diferentes. Como resultado, tiene una arquitectura bastante robusta que puede parecer demasiado compleja para ejecutar un blog simple. Echemos un vistazo a cómo Hugo puede ayudarnos a crear un blog que sea simple y rápido.

Cuando se lanzó WordPress 5, estaba emocionado de hacer uso del editor de Gutenberg para crear bloques personalizados, ya que las publicaciones en mi blog personal tenían un par de características que podía convertir en un bloque, lo que facilitaba la configuración de mi contenido. Definitivamente fue algo genial a tener, pero todavía lo sentía como algo bastante complejo.

Casi al mismo tiempo, comencé a leer más y más sobre generadores de sitios estáticos y JAMstack (este artículo de Chris Ferdinandi me convenció). Con proyectos secundarios personales, puedes descartar este tipo de generadores por una amplia variedad de problemas, pero como profesional, debes asegurarte de producir la mejor calidad posible. El rendimiento, la seguridad y la accesibilidad se convierten en las primeras cosas en las que pensar. Definitivamente puedes optimizar WordPress para que sea bastante rápido, pero más rápido que un sitio estático en un CDN que no necesita consultar la base de datos ni generar tu página cada vez. No tan fácil.

Pensé que podría poner esto en práctica con un proyecto personal mío para aprender y luego poder usar esto para proyectos profesionales, y tal vez a algunos de vosotros también les gustaría saber cómo. En este artículo, repasaré cómo hice la transición de WordPress a un generador de sitios estáticos específico llamado Hugo.

Hugo está integrado en Go, que es un lenguaje bastante rápido y fácil de usar una vez que te acostumbras a la sintaxis, que explicaré más adelante. Todo se compila localmente para que puedas obtener una vista previa de tu sitio directamente en tu computadora. Luego, el proyecto se guarda en un repositorio privado. Además, teo guiaré a través de cómo alojarlo en Netlify y guardar las imágenes en un Git LFS (Almacenamiento de archivos grandes). Finalmente, veremos cómo podemos configurar un sistema de administración de contenido para agregar publicaciones e imágenes (similar al backend de WordPress) con Netlify CMS.

Ten en cuenta que todo esto es absolutamente gratis, lo cual es bastante sorprendente si me preguntas (aunque tendrás que pagar más si usa todo tu almacenamiento LFS o si el tráfico de tu sitio es intenso). Además, estoy escribiendo esto desde el punto de vista de un usuario de Bitbucket, ejecutándolo en un Mac. Algunos pasos pueden ser ligeramente diferentes, pero deberías poder seguirlos, independientemente de la configuración que utilices.

Deberás sentirte algo cómodo con HTML, CSS, JS, Git y el terminal de comandos. Tener algunas nociones con lenguajes de plantillas como Liquid también podría ser útil, pero revisaremos las plantillas de Hugo para comenzar. No obstante, proporcionaré tantos detalles como sea posible. Sé que parece mucho, y antes de empezar a investigar esto, también lo era para mí. Trataré de hacer que esta transición sea lo más sencilla posible para ti desglosando los pasos. No es muy difícil encontrar todos los recursos, pero hubo algunas conjeturas involucradas por mi parte, yendo de una documentación a otra.

Nota: Si tiene problemas con algunos de estos, házmelo saber en los comentarios e intentaré ayudarte, pero ten en cuenta que esto está destinado a aplicarse a un blog simple y estático que no tiene una docena de widgets o comentarios (puedes configurarlos más tarde), y no una web de empresa o un portafolio. Sin duda, podrías hacerlo, pero en aras de la simplicidad, me limitaré a un blog simple y estático.

Requisitos previos

Antes de hacer nada, creemos una carpeta de proyecto donde residirá todo, desde nuestras herramientas hasta nuestro repositorio local. Lo llamaré «WP2Hugo» (no dudes en llamarlo como quieras).

Este tutorial utilizará algunas herramientas online de comandos como npm y Git. Si aún no los tienes, instálalos en tu máquina:

Con esto instalado, ¡comenzamos!

1. Exportación del contenido de WordPress

En primer lugar, necesitaremos exportar el contenido de WordPress: publicaciones, páginas y cargas. Hay algunas herramientas disponibles que menciona Hugo pero personalmente, solo una de ellas funcionó: blog2md. Este funciona ejecutando un archivo JavaScript con Node.js en tu terminal de comandos. Toma los archivos XML exportados por WordPress y genera archivos Markdown con la estructura correcta, convirtiendo tu HTML a Markdown y agregando lo que se llama Front Matter, que es una forma de formatear metadatos al comienzo de cada archivo.

Ve a tu administrador de WordPress y abre el menú Herramientas, submenú Exportar. Puedes exportar lo que quieras desde allí. Me referiré al archivo exportado como YOUR-WP-EXPORT.xml.

Herramienta de exportación de WordPress (vista previa grande)

Puedes seleccionar exactamente qué datos deseas exportar desde tu blog de WordPress.

Dentro de nuestra carpeta WP2Hugo, recomiendo crear una nueva carpeta con el nombre blog2md en la que colocarás los archivos de la herramienta blog2md, así como tu exportación XML desde WordPress (YOUR-WP-EXPORT.xml). Además, crea una nueva carpeta allí llamada out donde irán tus publicaciones de Markdown. Luego, abre tu terminal de comandos y navega con el comando cd a tu carpeta «blog2md» recién creada (o escribe cd con un espacio y arrastra la carpeta al terminal).

Ahora puedes ejecutar los siguientes comandos para obtener tus publicaciones:

npm install
node index.js w YOUR-WP-EXPORT.xml out

Mira en el /WP2Hugo/blog2md/out directorio para verificar si todas tus publicaciones (y páginas potenciales) están allí. Si es así, puedes notar que hay algo sobre los comentarios en la documentación: tenía un blog sin comentarios, así que no necesitaba que se llevaran a cabo, pero Hugo ofrece varias opciones para los comentarios. Si tienes algún comentario sobre WordPress, puede exportarlo para tu posterior implementación con un servicio especializado como Disqus.

Si estás lo suficientemente familiarizado con JS, puedes modificar el archivo index.js para cambiar el resultado de tus archivos de publicación editando la función wordpressImport. Es posible que desees capturar la imagen destacada, eliminar el enlace permanente, cambiar el formato de fecha o establecer el tipo (si tiene publicaciones y páginas). Tendrás que adaptarlo a tus necesidades, pero has de saber que el bucle (posts.forEach(function(post){... })) recorre todas las publicaciones de la exportación, por lo que puedes verificar el contenido XML de cada publicación en ese bucle y personalizar tu Front Matter.

Además, si necesitas actualizar las URL contenidas en tus publicaciones (en mi caso, quería que los enlaces de imágenes fueran relativos en lugar de absolutos) o el formato de la fecha, este es un buen momento para hacerlo, pero no pierdas el sueño. Muchos editores de texto ofrecen edición masiva para que puedas insertar una expresión regular y realizar los cambios que desees en tus archivos. Además, puedes ejecutar el script blog2md tantas veces como sea necesario, ya que sobrescribirá cualquier archivo existente previamente en la carpeta de salida. Una vez que tenga tus archivos Markdown exportados, tu contenido estará listo.

El siguiente paso es preparar tu tema de WordPress para que funcione en Hugo.

2. Preparación del diseño de tu blog

Mi blog tenía un diseño típico con un encabezado, una barra de navegación, contenido y barra lateral, y un pie de página, bastante simple de configurar. En lugar de copiar partes de mi tema de WordPress, lo reconstruí todo desde cero para asegurarme de que no hubiera estilos superfluos o marcas inútiles. Este es un buen momento para implementar nuevas técnicas de CSS (pssst… Grid es bastante impresionante) y establecer una estrategia de nomenclatura más consistente (algo así como las pautas de CSS Wizardry). Puede hacer lo que quiera, pero recuerde que estamos tratando de optimizar nuestro blog, por lo que es bueno revisar lo que tenías y decidir si aún vale la pena conservarlo.

Comienza dividiendo tu blog en partes para que pueda ver claramente qué va y dónde. Esto te ayudará a estructurar tu marcado y tus estilos. Por cierto, Hugo tiene la capacidad incorporada de compilar Sass en CSS, ¡así que siéntete libre de dividir esos estilos en archivos más pequeños tanto como quieras!

Un diseño de blog muy simple. (Vista previa grande)

Cuando digo simple, me refiero a realmente simple. Alternativamente, puedes omitir completamente este paso por ahora y diseñar tu blog a medida que avanzas cuando tu sitio de Hugo esté configurado. También es una buena forma de ver qué funciona y qué no.

3. Configuración de un nuevo repositorio

Ahora que esto está en camino, necesitamos configurar un repositorio. Supongo que querrás crear un nuevo repositorio para esto, que será una gran oportunidad para usar Git LFS (Large File System). La razón por la que recomiendo hacer esto ahora es que implementar Git LFS cuando ya tienes cientos de imágenes no es tan sencillo. Lo hice, pero fue un dolor de cabeza que probablemente querrás evitar. Esto también proporcionará otros beneficios en el futuro con Netlify.

Si bien haré todo esto a través de Bitbucket y su GUI patentada de Git, Sourcetree, puedes hacerlo con GitHub y GitLab y tus propias herramientas de escritorio. También puedes hacerlo directamente en la terminal de comandos, pero me gusta automatizar y simplificar el proceso tanto como pueda, reduciendo el riesgo de cometer errores tontos.

Cuando hayas creado tu nuevo repositorio en la plataforma Git de tu elección, crea una carpeta vacía dentro de la carpeta de tu proyecto local (WP2Hugo), por ejemplo hugorepo, luego abre tu terminal de comandos o la herramienta GUI de Git e inicializa tu repositorio local de Git; luego, vincúlalo al repositorio remoto (por lo general, puedes encontrar el comando exacto para usar en el repositorio remoto recién creado).

Recomendaría crear una rama dev (o stage) para que tu rama principal se utilice estrictamente para implementaciones de producción. También limitará la generación de nuevas compilaciones solo cuando hayas terminado con una posible serie de cambios. La creación de una rama se puede realizar de forma local o en la página web remota de tu repositorio.

Cómo crear una nueva rama en GitHub, GitLab y Bitbucket. (Vista previa grande)

GitHub facilita la creación de una rama haciendo clic en el conmutador de rama y escribiendo un nuevo nombre. En GitLab, debes abrir el menú desplegable «Más» para acceder a la opción. Bitbucket requiere que abras el menú «Más» a la izquierda para abrir el menú deslizable y hacer clic en «Crear una rama» en la sección «Ponerse a trabajar».

4. Activación de Git LFS (opcional)

Git Large File System es una función de Git que te permite guardar archivos grandes de una manera más eficiente, como documentos de Photoshop, archivos ZIP y, en nuestro caso, imágenes. Dado que las imágenes pueden necesitar control de versiones, pero no son exactamente código, tiene sentido almacenarlas de manera diferente a los archivos de texto normales. La forma en que funciona es almacenando la imagen en un servidor remoto, y el archivo en tu repositorio será un archivo de texto que contiene un puntero a ese recurso remoto.

Por desgracia, no es una opción en la que simplemente hagas clic para habilitar. Debes configurar tu repositorio para activar LFS y esto requiere algo de trabajo localmente. Con Git instalado, necesita instalar una extensión Git-LFS:

git lfs install 

Si, como a mi, ese comando no te funciona, prueba la alternativa Homebrew (para macOS o Linux):

brew install git-lfs 

Una vez hecho esto, tendrás que especificar qué archivos rastrear en tu repositorio. Alojaré todas las imágenes que cargué en la carpeta /upload de WordPress en una carpeta con el mismo nombre en mi configuración de Hugo, excepto que esta carpeta estará dentro de una carpeta /static (que se resolverá en la raíz una vez compilada). Decide la estructura de tu carpeta y realiza un seguimiento de tus archivos en tu interior:

git lfs track "static/uploads/*" 

Esto rastreará cualquier archivo dentro de la carpeta /static/uploads. También puedes utilizar lo siguiente:

git lfs track "*.jpg" 

Esto rastreará todos y cada uno de los archivos JPG en tu repositorio. Puedes mezclar y combinar para rastrear solo JPG en una carpeta determinada, por ejemplo.

Con eso en su lugar, puedes enviar tus archivos de configuración LFS a tu repositorio y enviarlos a tu repositorio remoto. La próxima vez que confirmes localmente un archivo que coincida con la configuración de seguimiento de LFS, se «convertirá» en un recurso de LFS. Si estás trabajando en una rama de desarrollo, combina este compromiso en tu rama principal.

Echemos ahora un vistazo a Netlify.

5. Creación del sitio en Netlify

En este punto, tu repositorio está configurado, por lo que puedes continuar y crear una cuenta en Netlify. Incluso puede iniciar sesión con tu cuenta de GitHub, GitLab o Bitbucket si lo deseas. Una vez en el panel, haz clic en el botón «Nuevo sitio de Git» en la esquina superior derecha y crea tu nuevo sitio Netlify.

Nota: puedes dejar todas las opciones con sus valores predeterminados por ahora.

Nueva página de creación de sitios de Netlify. (Vista previa grande)

Selecciona tu proveedor de Git: esto abrirá una ventana emergente para autenticarlo. Cuando termines, la ventana se cerrará y verás una lista de repositorios en ese proveedor de Git al que tienes acceso. Selecciona tu repositorio recién creado y continúa. Se te preguntarán algunas cosas, la mayoría de las cuales puedes dejar de forma predeterminada, ya que todas las opciones se pueden editar más adelante.

Por ahora, en la Configuración del sitio, haz clic en «Cambiar el nombre del sitio» y asigna a tu sitio el nombre que desees; iré con wombat-snippetsboard-hugo-blog. Ahora podremos acceder al sitio a través de wombat-snippetsboard-hugo-blog.netlify.com: ¡una hermosa página 404!

6. Preparación para soportes grandes de Netlify (opcional)

Si configuras Git LFS y planeas usar Netlify, querrás seguir estos pasos. Es un poco más complicado, pero definitivamente vale la pena: ya que te permitirá establecer cadenas de consulta en URL de imágenes que se transformarán automáticamente.

Supongamos que tiene un enlace a portrait.jpg, que es una imagen de 900 × 1600 píxeles. Con Netlify Large Media, puedes llamar al archivo portrait.jpg?nf_resize=fit&w=420, que lo escalará proporcionalmente. Si defines ambos w y h, y establece nf_resize=smartcrop, cambiará de tamaño recortando para enfocarse en el punto de interés de la imagen (¡según lo determinado por un algoritmo automático, también conocido como robot brain magic!). Encuentro que esta es una excelente manera de tener miniaturas como las que genera WordPress, sin necesidad de varios archivos para una imagen en mi repositorio.

Si esto te parece atractivo, ¡configurémoslo!

El primer paso es instalar la interfaz de línea de comandos (CLI) de Netlify a través de npm:

npm install netlify-cli -g 

Si funcionó, ejecutar el comando netlify debería generar información sobre la herramienta.

Luego deberás asegurarte de estar en tu carpeta de repositorio local (que llamé «hugorepo» anteriormente), y ejecutar:

netlify login 

Autoriza el token. A continuación, tendremos que instalar el complemento Netlify Large Media. Correr:

netlify plugins:install
netlify-lm-plugin netlify lm:install 

Debería aparecer una línea de comando al final del mensaje resultante que debes copiar (que debería verse como /Users/YOURNAME/.netlify/helper/path.bash.inc en Mac) – ejecútala. Ten en cuenta que Keychain puede solicitarte la contraseña de administrador de tu máquina en macOS.

El siguiente paso es vincular Netlify:

netlify link 

Puedes proporcionar el nombre de tu sitio aquí (proporcioné el nombre wombat-snippetsboard-hugo-blog que le di anteriormente). Con esto en su lugar, solo necesitas configurar la función de Medios grandes ejecutando lo siguiente:

netlify lm:setup 

Confirma estos nuevos cambios en tu repositorio local y envíalos a la rama de desarrollo remoto. Tuve algunos errores con Sourcetree y Keychain en la línea de git "credential-netlify" is not a git command. Si este es tu caso, intenta presionar manualmente con estos comandos:

git add -A
git commit -m "Set up Netlify Large media"
git push

Si eso no funciona, es posible que debas instalar Netlify credential Helper. He aquí cómo hacerlo con Homebrew:

brew tap netlify/git-credential-netlify
brew install git-credential-netlify

Intenta hacerlo ahora (ya sea con tu GUI o terminal de comando): ¡debería funcionar!

Nota: Si cambia tu contraseña de Netlify, ejecute un netlify logout y netlify login otra vez.

Podrías preguntar: «¿Todo esto y aún no hemos inicializado nuestra compilación de Hugo?» Sí, lo sé, toma un tiempo, pero todos los preparativos para la transición están hechos. ¡Ahora podemos configurar nuestro blog de Hugo!

7. Configuración de Hugo en tu computadora

Primero deberás instalar Hugo en tu computadora con cualquiera de las opciones proporcionadas. Usaré Homebrew, pero los usuarios de Windows pueden usar Scoop o Chocolatey, o descargar un paquete directamente.

brew install hugo 

Luego, deberás crear un nuevo sitio de Hugo, pero no te gustará configurarlo en una carpeta que no esté vacía. Primera opción: puede crearlo en una nueva carpeta y mover tu contenido a la carpeta del repositorio local:

hugo new site your_temporary_folder 

Segunda opción: puede forzar que se instale en tu repositorio local con una bandera, solo asegúrate de ejecutarlo en la carpeta correcta:

hugo new site . --force 

Ahora tienes un sitio de Hugo, que puede activar con este comando:

hugo server 

Obtendrás una vista previa local en localhost. Lamentablemente, no tiene contenido ni tema propio. No te preocupes, lo configuraremos muy pronto.

Primero echemos un vistazo al archivo de configuración (config.toml en mi caso): configuremos el nombre del blog y la URL base (debe coincidir con la URL en tu panel de Netlify):

title = "Wombat’ SnippetsBoard Hugo Blog"
baseURL = "https://wombat-snippetsboard-hugo-blog.netlify.com"

Este enlace se sobrescribirá mientras desarrollas localmente, por lo que no deberías encontrarte con errores 404.

Démosle a Hugo nuestros artículos exportados en formato Markdown. Deben estar en la carpeta /WP2Hugo/blog2md/out desde el primer paso. En la carpeta Hugo (también conocida como el directorio del repositorio local), accede a la carpeta content y crea una subcarpeta llamada posts. Coloca tus archivos de Markdown allí, y luego configuremos un tema.

8. Creación de tu tema personalizado

Para este paso, recomiendo descargar el texto estándar de Saito, que es un tema con todos los parciales que necesitará para comenzar (y sin estilos), un punto de partida muy útil. Por supuesto, puedes mirar esta colección de temas listos para usar para Hugo si deseas omitir esta parte del proceso. ¡Todo depende de ti!

Desde la carpeta del repositorio local, clona el tema en themes/saito:

git submodule add https://github.com/hakuoku/saito-boilerplate.git themes/saito  

Puede cambiar el nombre de esta carpeta a cualquier cosa que desees, como cool-theme. Tendrás que decirle a tu configuración de Hugo qué tema deseas usar editando tu archivo config.toml/yaml/json. Edita el valor del tema a saito, o cool-theme, o cualquiera que sea el nombre de la carpeta de tu tema. Su vista previa ahora debería mostrar el título de tu blog junto con una línea de derechos de autor. Es un comienzo, ¿verdad?

Abre el tema desde el archivo layout/partials/home.html y editalo para mostrar tu contenido, lo que limita a los cinco primeros artículos que son de tipo posts (dentro de la carpeta content/posts/), con range, first y where:

<div class="container">
{{ range first 5 (where .Paginator.Pages "Type" "posts") }}
    <article class="post post--{{ .Params.class }}">
        <h2 class="post__title">{{ .Title }}</h2>
        <section class="post__content">
            {{ .Content }}
        </section>
    </article>
{{ end }}
</div>

Tu contenido ahora es visible, de la manera más básica. Es hora de que lo hagas tuyo, ¡vamos a sumergirnos!

Plantilla con Hugo

Primero puedes leer la Introducción a las plantillas de Hugo si lo deseas, pero intentaré repasar algunos conceptos que te ayudarán a comprender los conceptos básicos.

Todas las operaciones en Hugo se definen dentro de delimitadores: llaves dobles (p {{.Title }}. Ej.), Que deberían resultarte familiares si ya ha realizado algunas plantillas antes. Si no lo has hecho, considéralo como una forma de ejecutar operaciones o inyectar valores en un punto específico de tu marcado. Los bloques, terminan con la etiqueta {{ end }}, para todas las operaciones, excepto los códigos cortos.

Los temas tienen una carpeta layout que contiene las partes del diseño. La carpeta _default será el punto de partida de Hugo, siendo baseof.html la base de tu diseño. Llamará a cada componente, llamados «parciales» (más sobre esto en la documentación de Hugo sobre Partial Template), similar a cómo lo usaría include en PHP, que ya puedes haber visto en tu tema de WordPress. Los parciales pueden llamar a otros parciales, pero no lo conviertas en un bucle infinito.

Puede llamar a un parcial con la sintaxis {{ partial "file.html". }}. La seción partial es bastante sencilla, pero es posible que las otras dos necesiten una explicación. Es de esperar que tengas que escribir parciales/file.html, pero como todos los parciales deben estar en la carpeta «parciales», Hugo puede encontrar esa carpeta sin problemas. Por supuesto, puedes crear subcarpetas dentro de la carpeta «parciales» si necesitas más organización.

Es posible que hayas notado un punto perdido: este es el contexto que está pasando a tu parcial. Si tuviera un menú parcial y una lista de enlaces y etiquetas, podrías pasar esa lista al parcial para que solo pudiera acceder a esa lista, y nada más. Hablaré más sobre este punto difícil de alcanzar en la siguiente sección.

Tu archivo baseof.html es un shell que llama a todos los parciales necesarios para representar el diseño de tu blog. Debes tener HTML mínimo y muchos parciales:

<!DOCTYPE html>
<html lang="{{ .Site.LanguageCode }}">
    <head>
        <title>{{ block "title" . }}{{ .Site.Title }}{{ end }}</title>
        {{ partial "head.html" . }}
    </head>
    <body>
        {{ partial "header.html" . }}
        {{ partial "nav.html" . }}

        <main>
            {{ block "main" . }}{{ end }}
        </main>

        <aside>
            {{ partial "sidebar.html" . }}
        </aside>

        {{ partial "footer.html" . }}
    </body>
</html>

La línea {{ block "main". }}{{ end }} es diferente porque es un bloque que se define con una plantilla basada en el contenido de la página actual (página de inicio, página de publicación única, etc.) con {{ define "main" }}.

Hojas de estilo

En tu tema, crea una carpeta con nombre assets en la que colocaremos una carpeta css. Contendrá nuestros archivos SCSS o un archivo CSS de confianza. Ahora, debería haber un archivo css.html en la carpeta partials (que es llamado por head.html). Para convertir Sass/SCSS a CSS y minimizar la hoja de estilo, usaríamos esta serie de funciones (usando la sintaxis de Hugo Pipes en lugar de envolver las funciones entre sí):

{{ $style:= resources.Get "css/style.scss" | toCSS | minify | fingerprint }} 

Como beneficio adicional, ya que me costó encontrar una respuesta directa, si deseas usar Autoprefixer, Hugo también implementa PostCSS. Puede agregar una función pipe adicional entre toCSS y minify en la primera línea, así:

{{ $style := resources.Get "css/style.scss" | toCSS | postCSS | minify | fingerprint }} 

Crea un archivo «postcss.config.js» en la raíz de tu blog de Hugo y pase las opciones, como:

module.exports = {
    plugins: {
        autoprefixer: {
            browsers: [
                "> 1%",
                "last 2 versions"
            ]
        }
    },
}

¡Y listo! De Sass a CSS minificado y prefijado. La función pipe de «huella digital» es para asegurarse de que el nombre del archivo sea único, como style.c66e6096bdc14c2d3a737cff95b85ad89c99b9d1.min.css. Si cambias la hoja de estilo, la huella digital cambia, por lo que el nombre del archivo es diferente y, por lo tanto, obtiene una solución eficaz para eliminar la memoria caché.

9. Notas sobre la sintaxis de Hugo

Quiero asegurarme de que entiendes “el punto”, que es la forma en que Hugo analiza las variables (o, en mis propias palabras, proporciona una referencia contextual) que usarás en tus plantillas.

El punto y el alcance

El punto es como una variable de nivel superior que puedes usar en cualquier plantilla o código corto, pero su valor se ajusta a su contexto. El valor del punto en una plantilla de nivel superior como baseof.html es diferente del valor dentro de los bloques o with bloques de bucle.

Digamos que esto está en nuestra plantilla en nuestro head.html parcial:

{{ with.Site.Title }}{{. }}{{ end }} 

Aunque estamos ejecutando esto en el alcance principal, el valor de punto cambia según el contexto, que es .Site.Title en este caso. Entonces, para imprimir el valor, solo necesitas escribir . en lugar de volver a escribir el nombre de la variable nuevamente. Esto me confundió al principio, pero te acostumbras muy rápido y ayuda a reducir la redundancia ya que solo nombras la variable una vez. Si algo no funciona, normalmente se debe a que está intentando llamar a una variable de nivel superior dentro de un bloque con ámbito.

Entonces, ¿cómo se usa el alcance de nivel superior dentro de un bloque con alcance? Bueno, digamos que deseas verificar un valor pero usar otro. Puede usar el $ que siempre será el alcance de nivel superior:

{{ with .Site.Params.InfoEnglish }}{{ $.Site.Params.DescriptionEnglish }}{{ end }} 

Dentro de nuestra condición, el alcance es, .Site.Params.InfoEnglish pero aún podemos acceder a valores fuera de él $, donde el uso intuitivo .Site.Params.DescriptionEnglish no funcionaría porque intentaría resolver .Site.Params.InfoEnglish.Site.Params.DescriptionEnglish, arrojando un error.

Variables personalizadas

Puedes asignar variables utilizando la siguiente sintaxis:

{{ $customvar := "custom value" }} 

El nombre de la variable debe comenzar con $ y el operador de asignación debe ser := si es la primera vez que se asigna, de locontrario = así:

{{ $customvar = "updated value" }} 

El problema con el que puedes encontrarte es que esto no sucederá fuera del alcance, lo que me lleva al siguiente punto.

Scratch

La funcionalidad Scratch te permite asignar valores que están disponibles en todos los contextos. Supongamos que tienes una lista de películas en un archivo movies.json:

[
    {
        "name": "The Room",
        "rating": 4
    },
    {
        "name": "Back to the Future",
        "rating": 10
    },
    {
        "name": "The Artist",
        "rating": 7
    }
]

Ahora, deseas iterar sobre el contenido del archivo y almacenar tus favoritos para usarlo más tarde. Aquí es donde entra en juego Scratch:

{{ .Scratch.Set "favouriteMovie" "None" }}{{ /* Optional, just to get you to see the difference syntax based on the scope */ }}

{{ range .Site.Data.movies }}
        {{ if ge .rating 10 }}
            {{ /* We must use .Scratch prefixed with a $, because the scope is .Site.Data.movies, at the current index of the loop */ }}
            {{ $.Scratch.Set "favouriteMovie" .name }}
        {{ end }}
{{ end }}
[...]
My favourite movie is {{ .Scratch.Get "favouriteMovie" }}
<!-- Expected output => My favourite movie is Back to the Future -->

Con Scratch, podemos extraer un valor del interior del bucle y usarlo en cualquier lugar. A medida que tu tema se vuelve cada vez más complejo, probablemente te encontrarás con Scratch.

Nota: Este es simplemente un ejemplo, ya que este bucle se puede optimizar para generar este resultado sin Scratch, pero esto debería darte una mejor comprensión de cómo funciona.

Condicionales

La sintaxis de los condicionales es un poco diferente de lo que cabría esperar, desde una perspectiva de JavaScript o PHP. En esencia, hay funciones que toman dos argumentos (el paréntesis es opcional si llamas a los valores directamente):

{{ if eq .Site.LanguageCode "en-us" }}Welcome!{{ end }} 

Hay varias de estas funciones:

  • eq controles de igualdad.
  • ne verifica la desigualdad.
  • gt comprobar si es mayor que.
  • ge comprobar si es mayor o igual a.
  • lt cheques por menos de.
  • le cheques por menor o igual a.

Nota: Puedes aprender todo sobre las funciones que ofrece Hugo en la Referencia rápida de funciones de Hugo.

Espacio en blanco

Si eres tan exigente con la salida como yo, es posible que notes algunas líneas en blanco no deseadas. Esto se debe a que Hugo analizará tu marcado tal como está, dejando líneas en blanco alrededor de los condicionales que no se cumplieron, por ejemplo.

Digamos que tenemos este hipotético parcial:

{{ if eq .Site.LanguageCode "en-us" }}
<p>Welcome to my blog!</p>
{{ end }}
<img src="/uploads/portrait.jpg" alt="Blog Author">

Si el código de idioma del sitio no es en-us, esta será la salida HTML (ten en cuenta las tres líneas vacías antes de la etiqueta de la imagen):




<img src="/uploads/portrait.jpg" alt="Blog Author"> 

Hugo proporciona una sintaxis para abordar esto con un guión junto a las llaves en el interior del delimitador. {{-recortará el espacio en blanco antes de las llaves y -}} recortará el espacio en blanco después de las llaves. Puedes usar uno o ambos al mismo tiempo, pero asegúrate de que haya un espacio entre el guión y la operación dentro del delimitador.

Como tal, si tu plantilla contiene lo siguiente:

{{- if eq .Site.LanguageCode "en-us" -}}
<p>Welcome to my blog!</p>
{{- end -}}
<img src="/uploads/portrait.jpg" alt="Blog Author">

… entonces el marcado dará como resultado esto (sin líneas vacías):

<img src="/uploads/portrait.jpg" alt="Blog Author"> 

Esto puede ser útil para otras situaciones, como elementos display: inline-block que no deberían tener espacios en blanco entre ellos. Por el contrario, si deseas asegurarte de que cada elemento está en tu propia línea en el marcado (por ejemplo, en un bucle {{ range }}), tendrás que colocar con cuidado los guiones para evitar el recorte de espacios en blanco «codicioso».

El ejemplo anterior daría como resultado lo siguiente si el código de idioma del sitio coincide con » en-us» (no más saltos de línea entre las etiquetas p e img):

<p>Welcome to my blog!</p><img src="/uploads/portrait.jpg" alt="Blog Author"> 

10. Contenido y número de datos 

Tu contenido se almacena como archivos Markdown, pero también puede usar HTML. Hugo lo renderizará correctamente cuando construya tu sitio.

Tu página de inicio llamará al diseño _default/list.html, que podría verse así:

{{ define "main" }}
    {{ partial "list.html" . }}
{{ end }}

El bloque principal llama al list.html parcial con el contexto de ., también conocido como el nivel superior. El list.html parcial puede verse así:

{{ define "main" }}
<ol class="articles">
    {{ range .Paginator.Pages }}
        <li>
            <article>
                <a href="{{ .URL }}">
                    <h2>{{ .Title }}</h2>
                    <img src="{{ .Params.featuredimage }}" alt="">
                    <time datetime="{{ .Date.Format "2006-01-02" }}">
                        {{ .Date.Format "January 2 2006" }}
                    </time>
                </a>
            </article>
        </li>
    {{ end }}
</ol>
{{ partial "pagination.html" . }}
{{ end }}

¡Ahora tenemos una lista básica de nuestros artículos, que puedes diseñar como desees! El número de artículos por página se define en el archivo de configuración, con paginate = 5 (en TOML).

Es posible que estés tan confundido como yo con el formato de fechas en Hugo. Cada vez que la unidad se asigna a un número (primer mes, segundo día, tercera hora, etc.) tenía mucho más sentido para mí una vez que vi la explicación visual a continuación que proporciona la documentación del idioma de Go, lo cual es un poco extraño, ¡Pero también un poco inteligente!

 Jan 2 15:04:05 2006 MST
=> 1 2  3  4  5    6  -7

Ahora todo lo que queda por hacer es mostrar tu publicación en una sola página. Puedes editar el parcial post.html para personalizar el diseño de tu artículo:

<article>
    <header>
        <h1>{{ .Title }}</h1>
        <p>
            Posted on <time datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "2006. 1. 2" }}</time>
        </p>
    </header>
    <section>
        {{ .Content }}
    </section>
</article>

¡Y así es como se muestra tu contenido!

Si deseas personalizar la URL, actualiza tu archivo de configuración agregando una opción [permalinks] (TOML), que en este caso hará que las URL se vean como my-blog.com/post-slug/:

[permalinks]
    posts = ":filename/"

Si deseas generar una fuente RSS de tu contenido (porque RSS es increíble), agrega lo siguiente en el archivo de configuración de tu sitio (la plantilla predeterminada de Saito mostrará las etiquetas apropiadas en head.html si se detectan estas opciones):

rssLimit = 10
[outputFormats]
    [outputFormats.RSS]
        mediatype = "application/rss"
        baseName = "feed"

Pero, ¿y si tuvieras algún tipo de contenido fuera de una publicación? Ahí es donde entran las plantillas de datos: puedes crear archivos JSON y extraer tus datos para crear tu menú o un elemento en tu barra lateral. YAML y TOML también son opciones pero menos legibles con datos complejos (por ejemplo, objetos anidados). Por supuesto, podrías establecer esto en el archivo de configuración de tu sitio, pero es, para mí, un poco menos fácil de navegar y menos indulgente.

Creemos una lista de «sitios interesantes» que quizás desees mostrar en tu barra lateral, con un enlace y una etiqueta para cada sitio como una matriz en JSON:

{
    "coolsites": [
        { "link": "https://snippetsboard.com", "label": "SnippetsBoard" },
        { "link": "http://gohugo.io/", "label": "Hugo" },
        { "link": "https://netlify.com", "label": "Netlify" }
    ]
}

Puedes guardar este archivo en la raíz de tu repositorio, o en la raíz de tu tema, dentro de una carpeta data, como /data/coolsites.json. Luego, en tu parcial sidebar.html, puedes iterar sobre él range usando .Site.Data.coolsites:

<h3>Cool Sites:</h3>
<ul>
{{ range .Site.Data.coolsites.coolsites }}
    <li><a href="{{ .link }}">{{ .label }}</a></li>
{{ end }}
</ul>

Esto es muy útil para cualquier tipo de datos personalizados sobre los que desees iterar. Lo usé para crear una lista de fuentes de Google para mi tema, en qué categorías pueden estar las publicaciones, autores (con biografía, avatar y enlace a la página de inicio), qué menús mostrar y en qué orden. Realmente puedes hacer mucho con esto, y es bastante sencillo.

Un pensamiento final sobre los datos y demás: todo lo que pongas en tu carpeta /static Hugo estará disponible en la raíz (/) de la compilación en vivo. Lo mismo ocurre con la carpeta de temas.

11. Implementación en Netlify

Así que ya terminaste, ¿o tal vez solo quieras ver qué tipo de magia opera Netlify? Me parece bien, siempre que tu servidor Hugo local no devuelva un error.

Confirma tus cambios y envíalos a tu rama de desarrollo remota (dev). Dirígete a Netlify a continuación y accede a la configuración de tu sitio. Verás una opción para «Construir e implementar». Vamos a necesitar cambiar un par de cosas aquí.

  1. Primero, en la sección «Configuración de compilación», asegúrate de que «Comando de compilación» esté establecido en hugo y que «Directorio de publicación» esté establecido en public (el valor predeterminado que se recomienda que mantengas en tu archivo de configuración de Hugo);
  2. A continuación, en la sección «Implementar contextos», configura «Rama de producción» en tu rama principal en tu repositorio. También sugiero que tus «Implementaciones de sucursales» se establezcan en «Implementar solo la sucursal de producción»;
  3. Finalmente, en la sección «Variables de entorno», edita las variables y haz clic en «Nueva variable». Vamos a establecer el entorno de Hugo en 0.53 con el siguiente par: establecer clave en HUGO_VERSION y valor en 0.53.

Ahora dirígete a tu repositorio remoto y fusiona tu rama de desarrollo en tu rama principal: este será el gancho que desplegará tu blog actualizado (esto se puede personalizar, pero el valor predeterminado es razonable para mí).

Volviendo a tu panel de Netlify, las «implementaciones de producción» de tu sitio deberían tener alguna actividad nueva. Si todo salió bien, esto debería procesarse y resolverse en una etiqueta de «Publicado». Al hacer clic en el elemento de implementación, se abrirá una descripción general con un registro de las operaciones. En la parte superior, verás «Vista previa de la implementación». Continúa, haz clic en él, se lo merece. ¡Está vivo!

12. Configuración de un número de dominio personalizado 

¿Tener la URL como my-super-site.netlify.com no es de tu gusto y ya toca poner my-super-site.com? Vamos a ello.

Dirígete a tu registrador de dominios y ve a la configuración de DNS de tu dominio. Aquí, tendrás que crear una nueva entrada: puede establecer un registro ALIAS / CNAME que apunte a my-super-site.netlify.com, o establecer un registro A que apunte tu dominio al balanceador de carga de Netlify, que se encuentra 104.198.14.52 en el momento de escribir este artículo.

Puede encontrar la información más reciente en la documentación de Netlify sobre dominios personalizados. La IP del equilibrador de carga estará en la sección de configuración de DNS, en «Configuración de DNS manual para dominios personalizados raíz y www«.

Cuando hayas terminado, diríjete al panel de control de tu sitio en Netlify y haz clic en «Configuración de dominio», donde verás «Agregar dominio personalizado». Ingresa tu nombre de dominio para verificarlo.

También puedes administrar tus dominios a través de tu panel de control en la pestaña Dominios. La interfaz es menos confusa en esta página, pero tal vez te ayude a entender mejor la configuración de DNS como lo hizo conmigo.

Nota: Netlify también puede manejar todo por ti si deseas comprar un dominio a través de ellos. Es más fácil pero tiene un costo adicional.

Una vez que hayas configurado tu dominio personalizado, en «Configuración del dominio», desplázate hacia abajo hasta la sección «HTTPS» y habilita el certificado SSL / TLS. Puede tardar unos minutos, pero te otorgará un certificado gratuito: tu dominio ahora se ejecuta en HTTPS.

13. Edición de contenido en Netlify CMS

Si deseas editar tus artículos, cargar imágenes y cambiar la configuración de tu blog como lo harías en la interfaz de back-end de WordPress, puedes usar Netlify CMS, que tiene un tutorial bastante bueno disponible. Es un archivo único que se encargará de todo por ti (y es independiente del generador: funcionará con Jekyll, Eleventy, etc.).

Solo necesitas cargar dos archivos en una carpeta:

  • el CMS (un solo archivo HTML);
  • un archivo de configuración (un archivo YAML).

Este último contendrá todas las configuraciones de tu sitio en particular.

Ve a la carpeta /static raíz de Hugo y crea una nueva carpeta a la que accederás a través de my-super-site.com/FOLDER_NAME (llamaré a la mía admin). Dentro de esta carpeta admin, crea un archivo index.html copiando el marcado proporcionado por Netlify CMS:

<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Content Manager</title>
</head>
<body>
<!-- Include the script that builds the page and powers Netlify CMS -->
    <script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script>
</body>
</html>

El otro archivo que deberás crear es el archivo de configuración: config.yml. Te permitirá definir la configuración de tu sitio (nombre, URL, etc.) para que puedas configurar lo que debe contener la portada de tus publicaciones, así como la forma en que tus archivos de datos (si corresponde) deben ser editables. Es un poco más complejo de configurar, pero eso no significa que no sea fácil.

Si estás utilizando GitHub o GitLab, inicia tu archivo config.yml con:

backend:
    name: git-gateway
    branch: dev # Branch to update (optional; defaults to master)

Si estás usando Bitbucket, es un poco diferente:

backend:
    name: bitbucket
    repo: your-username/your-hugorepo
    branch: dev # Branch to update (optional; defaults to master)

Luego, para nuestras cargas, tendremos que decirle al CMS dónde almacenarlas:

media_folder: "static/images/uploads" # Media files will be stored in the repo under static/images/uploads
public_folder: "/images/uploads" # The src attribute for uploaded media will begin with /images/uploads

Cuando creas una nueva publicación, el CMS generará el slug para el nombre de archivo que puedes personalizar con tres opciones:

slug:
    encoding: "ascii" # You can also use "unicode" for non-Latin
    clean_accents: true # Removes diacritics from characters like é or å
    sanitize_replacement: "-" # Replace unsafe characters with this string

Finalmente, deberás definir cómo se estructuran los datos en tus publicaciones. También definirás cómo se estructuran los sitios de enfriamiento del archivo de datos, en caso de que quieras agregar otro sitio a la lista. Estos se establecen con el objeto collections que definitivamente será el más detallado, junto con un buen puñado de opciones sobre las que puedes leer más aquí.

collections:
    - name: "articles" # Used in routes, e.g., /admin/collections/blog
        label: "Articles" # Used in the Netlify CMS user interface
        folder: "content/posts" # The path to the folder where the posts are stored, usually content/posts for Hugo
        create: true # Allow users to create new documents in this collection
        slug: "{{slug}}" # Filename template, e.g., post-title.md
        fields: # The fields for each document, usually in front matter
            - {label: "Title", name: "title", widget: "string", required: true}
            - {label: "Draft", name: "draft", widget: "boolean", default: true }
            - {label: "Type", name: "type", widget: "hidden", default: "post" }
            - {label: "Publish Date", name: "date", widget: "date", format: "YYYY-MM-DD"}
            - {label: "Featured Image", name: "featuredimage", widget: "image"}
            - {label: "Author", name: "author", widget: "string"}
            - {label: "Body", name: "body", widget: "markdown"}
    - name: 'coolsites'
            label: 'Cool Sites'
            file: 'data/coolsites.json'
            description: 'Website to check out'
            fields:
                - name: coolsites
                    label: Sites
                    label_singular: 'Site'
                    widget: list
                    fields:
                        - { label: 'Site URL', name: 'link', widget: 'string', hint: 'https://…' }
                        - { label: 'Site Name', name: 'label', widget: 'string' }

Nota: Puedes leer más sobre cómo configurar campos individuales en la documentación de Widgets de Netlify CMS que repasa cada tipo de widget y cómo usarlos, especialmente útil para formatos de fecha.

Autenticación

¡Lo último que debemos hacer es asegurarnos de que solo los usuarios autorizados puedan acceder al backend! Usar la autenticación de tu proveedor de Git es una manera fácil de hacerlo.

Dirígete a tu sitio de Netlify y haz clic en la pestaña «Configuración». Luego ve a «Control de acceso», que es el último enlace del menú en el lado izquierdo. Aquí, puedes configurar OAuth para que se ejecute a través de GitHub, GitLab o Bitbucket proporcionando una clave y un valor secreto definido para tu cuenta de usuario (no en el repositorio). Querrás usar el mismo proveedor de Git en el que estás guardado tu repositorio.

GitHub

Ve a tu página «Configuración» en GitHub (haz clic en tu avatar para ver el menú) y accede a «Configuración del desarrollador». Haz clic en «Registrar una nueva aplicación» y proporciona los valores requeridos:

  • Un nombre, como «Netlify CMS para mi superblog».
  • Una URL de la página de inicio, el enlace a tu sitio Netlify.
  • Una descripción, si te apetece.
  • La URL de devolución de llamada de la aplicación, que debe ser «https://api.netlify.com/auth/done«.

Guarda y verás tu ID de cliente y tu secreto de cliente. Proporciónaselos al Control de acceso de Netlify.

GitLab

Haz clic en tu avatar para acceder a la página de Configuración y haz clic en «Aplicaciones» en el menú «Configuración de usuario» a la izquierda. Verás un formulario para agregar una nueva aplicación. Proveele la siguiente informacion:

  • Un nombre, como «Netlify CMS para mi superblog».
  • Un URI de redireccionamiento, que debe ser » https://api.netlify.com/auth/done«.
  • Los alcances que deben comprobarse son:
    • api
    • read_user
    • read_repository
    • write_repository
    • read_registry

Guarda tu aplicación y te dará tu ID de aplicación y tu secreto, que ahora puedes ingresar en el Control de acceso de Netlify.

Bitbucket

Dirígete a la configuración de tu cuenta de usuario (haz clic en tu avatar y luego en «Configuración de Bitbucket»). En «Gestión de acceso», haz clic en «OAth». En la sección «Consumidores de OAuth», haz clic en «Agregar consumidor». Puedes dejar la mayoría de las cosas en tus valores predeterminados, excepto estos:

  • Un nombre, como «Netlify CMS para mi superblog».
  • Una URL de devolución de llamada, que debe ser » https://api.netlify.com/auth/done«.
  • Los permisos que deben comprobarse son:
    • Cuenta: correo electrónico, lectura, escritura.
    • Repositorios: lectura, escritura, administración.
    • Solicitudes de extracción: lectura, escritura.
    • Webhooks: lectura y escritura.

Después de guardar, puedes acceder a tu clave y secreto, que luego puedes devolver en el Control de acceso de Netlify.

Después de proporcionar los tokens, ve a Netlify y busca la Configuración del sitio. Dirígete a «Identidad» y habilita la función. Ahora puedes agregar un proveedor externo: selecciona tu proveedor de Git y haz clic en «Habilitar».

En caso de que necesites detalles adicionales, Netlify CMS tiene una guía de autenticación que puedes leer.

Ahora puedes acceder al backend de tu sitio Netlify y editar el contenido. Cada edición es una confirmación en tu repositorio, en la rama especificada en tu archivo de configuración. Si mantuviste tu rama main como destino para Netlify CMS, cada vez que guardes, se ejecutará una nueva compilación. Más conveniente, pero no tan limpio con «estados intermedios».

Tenerlo guardado en una rama dev te permite tener un control más preciso sobre cuándo deseas ejecutar una nueva compilación. Esto es especialmente importante si tu blog tiene mucho contenido y requiere más tiempo de construcción. De cualquier manera funcionará; es solo una cuestión de cómo deseas administrar tu blog.

Además, ten en cuenta que Git LFS es algo que instalaste localmente, por lo que las imágenes cargadas a través de Netlify CMS serán «normales». Si ingresas tu sucursal remota localmente, las imágenes deben convertirse a LFS, que luego puedes enviar a tu sucursal remota. Además, Netlify CMS actualmente no es compatible con LFS, por lo que la imagen no se mostrará en el CMS, pero sí en tu compilación final.

Conclusión

¡Qué viaje! En este tutorial, has aprendido a exportar tu publicación de WordPress a archivos Markdown, crear un nuevo repositorio, configurar Git LFS, alojar un sitio en Netlify, generar un sitio Hugo, crear tu propio tema y editar el contenido con Netlify CMS.. ¡No está mal!

¿Que sigue? Bueno, puedes experimentar con tu configuración de Hugo y leer más sobre las diversas herramientas que ofrece Hugo; hay muchas que no cubrí por brevedad.

¡Explorar! ¡Divertirse! ¡Blog!

Recursos adicionales

¿Qué opinas?

Escrito por Wombat

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

La guía definitiva para migrar un sitio de WordPress

LearnDash vs LifterLMS: ¿Cuál es el mejor Plugin de WordPress de creación de cursos en el 2021?