Cambiar de WordPress a Hugo

Publicado: 2022-03-10
Resumen rápido ↬ WordPress es un CMS fantástico que impulsa una gran parte de los sitios web, todos los cuales 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 por usar el 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 tenerlo, pero aún así se sentía bastante hinchado.

Casi al mismo tiempo, comencé a leer más y más sobre los generadores de sitios estáticos y JAMstack (este artículo de Chris Ferdinandi me convenció). Con proyectos paralelos personales, puede descartar una amplia variedad de problemas, pero como profesional, debe asegurarse de producir la mejor calidad posible. El rendimiento, la seguridad y la accesibilidad se convierten en lo primero en lo que hay que pensar. Definitivamente puede 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 su 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 ustedes 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.

¡Más después del salto! Continúe leyendo a continuación ↓

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é. Todo se compila localmente para que pueda obtener una vista previa de su sitio directamente en su computadora. El proyecto se guardará en un repositorio privado. Además, lo explicaré cómo alojarlo en Netlify y guardar sus 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.

Tenga en cuenta que todo esto es absolutamente gratis, lo cual es bastante sorprendente si me pregunta (aunque tendrá que pagar más si usa todo su almacenamiento LFS o si el tráfico de su sitio es intenso). Además, estoy escribiendo esto desde el punto de vista de un usuario de Bitbucket, ejecutándose en una Mac. Algunos pasos pueden ser ligeramente diferentes, pero debería poder seguirlos, sin importar la configuración que use.

Deberá sentirse algo cómodo con HTML, CSS, JS, Git y la 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 que comiences. ¡Sin embargo, proporcionaré tantos detalles como sea posible!

Sé que parece mucho, y antes de que comenzara a investigar esto, también era para mí. Intentaré que esta transición sea lo más fluida posible desglosando los pasos. No es muy difícil encontrar todos los recursos, pero hubo algunas conjeturas de mi parte al pasar de una documentación a la siguiente.

  1. Exportando el contenido de WordPress
  2. Preparando el diseño de tu blog
  3. Configuración de un nuevo repositorio
  4. Activando Git LFS (Opcional)
  5. Crear el sitio en Netlify
  6. Preparación para medios grandes de Netlify (opcional)
  7. Configuración de Hugo en su computadora
  8. Crear su tema personalizado
  9. Notas sobre la sintaxis de Hugo
  10. Contenido y datos
  11. Implementación en Netlify
  12. Configuración de un dominio personalizado
  13. Edición de contenido en Netlify CMS

Nota : si tiene problemas con algunos de estos, hágamelo saber en los comentarios e intentaré ayudarlo, pero tenga 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 configurarlo más tarde), y no un sitio de la empresa o una cartera personal. Sin duda podrías, sin embargo, 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" (siéntete libre de llamarlo como quieras).

Este tutorial utilizará algunas herramientas de línea de comandos, como npm y Git. Si aún no los tiene, instálelos en su máquina:

  • Instalar Git
  • Instale Node.js y npm (Node.js incluye npm)
  • Instale Homebrew (recomendado para usuarios de macOS/Linux)

Con estos instalados, ¡comencemos!

1. Exportar el contenido de WordPress

En primer lugar, necesitaremos exportar su 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 su terminal de comando. Toma los archivos XML exportados por WordPress y genera archivos Markdown con la estructura correcta, convirtiendo su HTML a Markdown y agregando lo que se llama Front Matter, que es una forma de formatear los metadatos al comienzo de cada archivo.

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

La interfaz de back-end de WordPress con flechas que indican cada paso para llegar a la función de exportación.
Herramienta de exportación de WordPress (vista previa grande)

Puede seleccionar exactamente qué datos desea exportar desde su blog de WordPress.

Dentro de nuestra carpeta WP2Hugo, recomiendo crear una nueva carpeta llamada blog2md en la que colocará los archivos de la herramienta blog2md, así como su exportación XML desde WordPress ( YOUR-WP-EXPORT.xml ). Además, cree una nueva carpeta allí llamada donde irán out publicaciones de Markdown. Luego, abra su terminal de comando y navegue con el comando cd a su carpeta "blog2md" recién creada (o escriba cd con un espacio y arrastre la carpeta a la terminal).

Ahora puede ejecutar los siguientes comandos para obtener sus publicaciones:

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

Busque en el /WP2Hugo/blog2md/out para verificar si todas sus publicaciones (y páginas potenciales) están allí. Si es así, puede 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 tenía algún comentario sobre WordPress, puede exportarlo para volver a implementarlo más tarde con un servicio especializado como Disqus.

Si está lo suficientemente familiarizado con JS, puede modificar el archivo index.js para cambiar la forma en que aparecerán sus archivos de publicación editando la función wordpressImport . Es posible que desee capturar la imagen destacada, eliminar el enlace permanente, cambiar el formato de fecha o establecer el tipo (si tiene publicaciones y páginas). Tendrá que adaptarlo a sus necesidades, pero sepa que el bucle ( posts.forEach(function(post){ ... }) ) se ejecuta en todas las publicaciones de la exportación, por lo que puede verificar el contenido XML de cada publicación en ese ciclo y personaliza tu Front Matter.

Además, si necesita actualizar las URL contenidas en sus publicaciones (en mi caso, quería hacer 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 pierda el sueño. . Muchos editores de texto ofrecen edición masiva para que pueda insertar una expresión regular y realizar los cambios que desee en sus archivos. Además, puede ejecutar el script blog2md tantas veces como sea necesario, ya que sobrescribirá cualquier archivo existente previamente en la carpeta de salida.

Una vez que haya exportado sus archivos Markdown, su contenido estará listo. El siguiente paso es preparar su tema de WordPress para que funcione en Hugo.

2. Preparando el diseño de tu blog

Mi blog tenía un diseño típico con un encabezado, una barra de navegación, una barra lateral y de contenido y un pie de página, bastante fácil 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 increíble! ) y establecer una estrategia de nomenclatura más consistente (algo así como las pautas de CSS Wizardry). Puedes hacer lo que quieras, pero recuerda 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.

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

Un diseño de blog con un banner en la parte superior y un menú debajo. El área principal tiene una gran sección para contenido y un área lateral más pequeña para contenido secundario. En la parte inferior hay un pie de página con una nota de derechos de autor y enlaces a la página de Twitter del autor y su correo electrónico.
Un diseño de blog muy simple. (Vista previa grande)

Cuando digo simple, quiero decir realmente simple.

Alternativamente, puede omitir este paso por ahora y diseñar su blog a medida que avanza cuando su sitio de Hugo está configurado. Tenía el marcado básico en su lugar y prefería un enfoque iterativo a los estilos. También es una buena manera de ver qué funciona y qué no.

3. Configuración de un nuevo repositorio

Ahora que eso está fuera del camino, necesitamos configurar un repositorio. Voy a suponer que querrá crear un nuevo repositorio para esto, lo que será una gran oportunidad para usar Git LFS (Sistema de archivos grandes). La razón por la que aconsejo hacer esto ahora es que implementar Git LFS cuando ya tiene cientos de imágenes no es tan sencillo. Lo he hecho, pero fue un dolor de cabeza que probablemente quieras 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 de Git patentada, Sourcetree, puedes hacerlo absolutamente con GitHub y GitLab y sus propias herramientas de escritorio. También puede 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 haya creado su nuevo repositorio en la plataforma Git de su elección, cree una carpeta vacía dentro de su carpeta de proyecto local (WP2Hugo), por ejemplo, hugorepo , luego abra su terminal de comando o herramienta Git GUI e inicialice su repositorio Git local; luego, vincúlelo al repositorio remoto (generalmente puede encontrar el comando exacto para usar en el repositorio remoto recién creado).

Recomendaría crear una rama dev (o stage ) para que su rama principal se use estrictamente para implementaciones de producción. También limitará la generación de nuevas compilaciones solo cuando haya terminado con una serie potencial de cambios. La creación de una rama se puede hacer localmente o en la página web remota de su repositorio.

Una guía de los distintos pasos para llegar al formulario 'Nueva rama' en los repositorios. GitHub requiere que el usuario haga clic en la rama activa y escriba un nuevo nombre en el campo de entrada. GitLab requiere que el usuario haga clic en un menú 'más' que revela un menú desplegable con un enlace 'Nueva rama' a una página con el formulario. Bitbucket requiere que el usuario haga clic en el "más" en el menú general para deslizar las opciones y haga clic en el enlace "Crear una sucursal" para acceder a una nueva página con el formulario.
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 selector de ramas y escribiendo un nuevo nombre. En GitLab, debe abrir el menú desplegable "Más" para acceder a la opción. Bitbucket requiere que abra el menú "Más" a la izquierda para abrir el menú deslizable y haga clic en "Crear una sucursal" en la sección "Poner manos a la obra".

4. Activando Git LFS (Opcional)

Git Large File System es una característica de Git que le 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 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 su repositorio será un archivo de texto que contiene un puntero a ese recurso remoto.

Por desgracia, no es una opción que simplemente haga clic para habilitar. Debe configurar su repositorio para activar LFS y esto requiere algo de trabajo localmente. Con Git instalado, debe instalar una extensión Git-LFS:

 git lfs install

Si, como yo, ese comando no te funcionó, prueba la alternativa de Homebrew (para macOS o Linux):

 brew install git-lfs

Una vez hecho esto, deberá especificar qué archivos rastrear en su 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). Decida la estructura de su carpeta y rastree sus archivos dentro:

 git lfs track "static/uploads/*"

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

 git lfs track "*.jpg"

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

Con eso en su lugar, puede enviar sus archivos de configuración LFS a su repositorio y enviarlos a su repositorio remoto. La próxima vez que envíe localmente un archivo que coincida con la configuración de seguimiento de LFS, se "convertirá" en un recurso LFS. Si trabaja en una rama de desarrollo, fusione este compromiso en su rama principal.

Ahora echemos un vistazo a Netlify.

5. Crear el sitio en Netlify

En este punto, su repositorio está configurado, por lo que puede continuar y crear una cuenta en Netlify. Incluso puede iniciar sesión con su cuenta de GitHub, GitLab o Bitbucket si lo desea. Una vez en el tablero, haga clic en el botón "Nuevo sitio desde Git" en la esquina superior derecha y cree su nuevo sitio de Netlify.

Nota : puede dejar todas las opciones en sus valores predeterminados por ahora.

El formulario que se muestra en Netlify cuando un usuario crea un nuevo sitio web, con las opciones de creación en sus valores vacíos predeterminados.
Nueva página de creación de sitios de Netlify. (Vista previa grande)

Seleccione su proveedor de Git: esto abrirá una ventana emergente para autenticarlo. Cuando termine, la ventana se cerrará y verá una lista de repositorios en ese proveedor de Git al que tiene acceso. Seleccione su repositorio recién creado y continúe. Se le preguntarán algunas cosas, la mayoría de las cuales puede dejar por defecto, ya que todas las opciones se pueden editar más adelante.

Por ahora, en la Configuración del sitio, haga clic en "Cambiar el nombre del sitio" y asigne el nombre que desee a su sitio; yo chris-smashing-hugo-blog . Ahora podremos acceder al sitio a través chris-smashing-hugo-blog.netlify.com : ¡una hermosa página 404!

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

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

Digamos que tiene un enlace a portrait.jpg, que es una imagen de 900 × 1600 píxeles. Con Netlify Large Media, puede llamar al archivo portrait.jpg?nf_resize=fit&w=420 , que lo escalará proporcionalmente. Si define w y h , y establece nf_resize=smartcrop , se redimensionará recortando para enfocarse en el punto de interés de la imagen (según lo determinado por un algoritmo elegante, ¡también conocido como magia del cerebro del robot! ). Considero 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 le parece atractivo, ¡vamos a configurarlo!

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á asegurarse de estar en la carpeta de su repositorio local (que llamé "hugorepo" anteriormente) y ejecutar:

 netlify login

Autorizar 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 debe copiar (que debería verse como /Users/YOURNAME/.netlify/helper/path.bash.inc en Mac): ejecútelo. Tenga en cuenta que Keychain puede solicitarle la contraseña de administrador de su máquina en macOS.

El siguiente paso es vincular Netlify:

 netlify link

Puede proporcionar el nombre de su sitio aquí (proporcioné el nombre chris-smashing-hugo-blog que le di anteriormente). Con esto en su lugar, solo necesita configurar la función de medios grandes ejecutando lo siguiente:

 netlify lm:setup

Confirme estos nuevos cambios en su repositorio local y envíelos a la rama de desarrollo remota. Tuve algunos errores con Sourcetree y Keychain en la línea de git "credential-netlify" is not a git command . Si ese es tu caso, intenta empujar manualmente con estos comandos:

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

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

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

Intente enviar su compromiso ahora (ya sea con su GUI o terminal de comando): ¡debería funcionar!

Nota : si cambia su contraseña de Netlify, ejecute el cierre de sesión de netlify logout y vuelva a iniciar sesión netlify login .

Podría preguntar: "Todo esto, ¿y aún no hemos inicializado nuestra versión de Hugo?" Sí, lo sé, tomó un tiempo, pero todos los preparativos para la transición ya están hechos. ¡Ya podemos configurar nuestro blog de Hugo!

7. Configuración de Hugo en su computadora

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

 brew install hugo

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

 hugo new site your_temporary_folder

Segunda opción: puede obligarlo a instalarse en su repositorio local con una bandera, solo asegúrese de ejecutarlo en la carpeta correcta:

 hugo new site . --force

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

 hugo server

Obtendrá una vista previa local en localhost . Lamentablemente, no tienes contenido ni tema propio. ¡No se preocupe, 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 (esto debe coincidir con la URL en su tablero de Netlify):

 title = "Chris' Smashing Hugo Blog" baseURL = "https://chris-smashing-hugo-blog.netlify.com"

Este enlace se sobrescribirá mientras desarrolla localmente, por lo que no debería encontrarse con errores 404.

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

8. Crear su tema personalizado

Para este paso, recomiendo descargar el repetitivo Saito, que es un tema con todos los parciales que necesitará para comenzar (y sin estilos), un punto de partida muy útil. Por supuesto, podría mirar esta colección de temas preparados para Hugo si desea omitir esta parte del proceso. ¡Todo depende de usted!

Desde la carpeta del repositorio local, clone 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 desee, como cool-theme . Deberá decirle a su configuración de Hugo qué tema desea usar editando su archivo config.toml/yaml/json . Edite el valor del tema a saito , o cool-theme , o cualquiera que sea el nombre de la carpeta de su tema. Su vista previa ahora debería mostrar el título de su blog junto con una línea de derechos de autor. Es un comienzo, ¿verdad?

Abra el archivo layout/partials/home.html del tema y edítelo para mostrar su contenido, limitándose a los primeros cinco elementos 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>

Su contenido ahora es visible, de la manera más básica. Es hora de hacerlo tuyo, ¡vamos a sumergirnos!

Plantillas con Hugo

Si lo desea, puede leer primero la Introducción a las plantillas de Hugo, pero intentaré repasar algunos elementos esenciales que lo ayudarán a comprender los conceptos básicos.

Todas las operaciones en Hugo se definen dentro de los delimitadores: llaves dobles (por ejemplo, {{ .Title }} ), que le resultarán familiares si ya ha trabajado un poco con plantillas. Si no lo ha hecho, considérelo como una forma de ejecutar operaciones o inyectar valores en un punto específico de su marcado. Para los bloques, terminan con la etiqueta {{ end }} , para todas las operaciones excepto los códigos abreviados.

Los temas tienen una carpeta de layout que contiene las piezas del diseño. La carpeta _default será el punto de partida de Hugo, siendo baseof.html ( ¡lo has adivinado! ) la base de tu diseño. Llamará a cada componente, llamado "parciales" (más sobre esto en la documentación de Hugo sobre Plantilla parcial), similar a cómo usaría include en PHP, que quizás ya haya visto en su tema de WordPress. Los parciales pueden llamar a otros parciales, pero no lo conviertas en un bucle infinito.

Puede llamar a un parcial con {{ partial "file.html" . }} {{ partial "file.html" . }} sintaxis. La sección partial es bastante sencilla, pero es posible que sea necesario explicar las otras dos. Es posible que tenga que escribir parciales/archivo.html, pero dado que todos los parciales deben estar en la carpeta de parciales, Hugo puede encontrar esa carpeta sin problemas. Por supuesto, puede crear subcarpetas dentro de la carpeta "parciales" si necesita más organización.

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

Su archivo baseof.html es un shell que llama a todos los parciales necesarios para representar el diseño de su blog. Debe 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>

El {{ block "main" . }}{{ end }} 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 su tema, cree una carpeta llamada 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 de partials (a la que llama 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 luché por encontrar una respuesta directa, si desea usar Autoprefixer, Hugo también implementa PostCSS. Puede agregar una función de tubería adicional entre toCSS y minify en la primera línea, así:

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

Cree un archivo "postcss.config.js" en la raíz de su blog de Hugo y pase las opciones, como:

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

¡Y listo! De Sass a CSS prefijado y minimizado. La función de tubería de "huella digital" es para asegurarse de que el nombre del archivo sea único, como style.c66e6096bdc14c2d3a737cff95b85ad89c99b9d1.min.css . Si cambia 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 efectiva de prevención de caché.

9. Notas sobre la sintaxis de Hugo

Quiero asegurarme de que comprende "el punto", que es cómo Hugo analiza las variables (o, en mis propias palabras, proporciona una referencia contextual) que usará en sus plantillas.

El punto y el alcance

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

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

 {{ with .Site.Title }} {{ . }} {{ final }}

Aunque estamos ejecutando esto en el ámbito principal, el valor del punto cambia según el contexto, que es .Site.Title en este caso. Entonces, para imprimir el valor, solo necesita escribir . en lugar de volver a escribir el nombre de la variable de nuevo. 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, generalmente 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 desea verificar un valor pero usar otro. Puede usar $ , que siempre será el ámbito 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 los valores fuera de él con $ , donde el uso intuitivo de .Site.Params.DescriptionEnglish no funcionaría porque intentaría resolverse en .Site.Params.InfoEnglish.Site.Params.DescriptionEnglish , lanzando un error.

Variables personalizadas

Puede 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 lo contrario así:

 {{ $customvar = "updated value" }}

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

Rasguño

La funcionalidad Scratch le permite asignar valores que están disponibles en todos los contextos. Digamos que tiene 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, desea iterar sobre el contenido del archivo y almacenar su favorito 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 desde dentro del ciclo y usarlo en cualquier lugar. A medida que su tema se vuelva más y más complejo, probablemente se encuentre buscando Scratch.

Nota : Esto es simplemente un ejemplo, ya que este ciclo se puede optimizar para generar este resultado sin Scratch, pero esto debería brindarle 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. Hay, en esencia, funciones que toman dos argumentos (los paréntesis son opcionales si llamas a los valores directamente):

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

Hay varias de estas funciones:

  • eq comprueba la igualdad
  • ne comprueba la desigualdad
  • gt verificar si es mayor que
  • ge comprobar si es mayor o igual que
  • lt si hay menos de
  • le comprueba si es menor o igual que

Nota : Puede aprender todo acerca de 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á su marcado tal como está, dejando líneas en blanco alrededor de las condicionales que no se cumplieron, por ejemplo.

Digamos que tenemos este parcial hipotético:

 {{ 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 (tenga 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. Puede usar uno o ambos al mismo tiempo, pero solo asegúrese de que haya un espacio entre el guión y la operación dentro del delimitador.

Como tal, si su 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 con display: inline-block que no deberían tener espacios en blanco entre ellos. Por el contrario, si quiere asegurarse de que cada elemento esté en su propia línea en el marcado (por ejemplo, en un bucle {{ range }} ), tendrá que colocar cuidadosamente los guiones para evitar el recorte de espacios en blanco "codicioso".

El ejemplo anterior mostraría 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 datos

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

Su página de inicio llamará al diseño _default/list.html , que podría tener este aspecto:

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

El bloque principal llama al parcial list.html con el contexto de . , también conocido como el nivel superior. El parcial list.html 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 quieras! 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é completamente confundido como yo por el formato de fecha en Hugo. Cada vez que la unidad se asigna a un número (primer mes, segundo día, tercera hora, etc.) tuvo mucho más sentido para mí una vez que vi la explicación visual a continuación que proporciona la documentación del lenguaje Go, lo cual es un poco extraño, pero un poco inteligente, también!

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

Ahora todo lo que queda por hacer es mostrar su publicación en una sola página. Puedes editar el post.html parcial 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 muestra su contenido!

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

 [permalinks] posts = ":filename/"

Si desea generar una fuente RSS de su contenido (porque RSS es increíble), agregue lo siguiente en el archivo de configuración de su 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 tuviera algún tipo de contenido fuera de una publicación? Ahí es donde entran las plantillas de datos: puede crear archivos JSON y extraer sus datos para crear su menú o un elemento en su barra lateral. YAML y TOML también son opciones pero menos legibles con datos complejos (por ejemplo, objetos anidados). Por supuesto, podría establecer esto en el archivo de configuración de su sitio, pero es, para mí, un poco menos fácil de navegar y menos indulgente.

Vamos a crear una lista de "sitios geniales" que quizás quieras mostrar en tu barra lateral, con un enlace y una etiqueta para cada sitio como una matriz en JSON:

 { "coolsites": [ { "link": "https://smashingmagazine.com", "label": "Smashing Magazine" }, { "link": "https://gohugo.io/", "label": "Hugo" }, { "link": "https://netlify.com", "label": "Netlify" } ] }

Puede guardar este archivo en la raíz de su repositorio, o en la raíz de su tema, dentro de una carpeta data , como /data/coolsites.json . Luego, en su sidebar.html parcial, puede iterar sobre él con el 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 que desee 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.

Una reflexión final sobre los datos y demás: todo lo que coloque en su carpeta Hugo /static estará disponible en la raíz ( / ) en la compilación en vivo. Lo mismo ocurre con la carpeta del tema.

11. Implementación en Netlify

Entonces, ¿ha terminado, o tal vez solo quiere ver qué tipo de magia opera Netlify? Me parece bien, siempre y cuando su servidor Hugo local no devuelva un error.

Confirme sus cambios y envíelos a su rama de desarrollo remota ( dev ). Dirígete a Netlify a continuación y accede a la configuración de tu sitio. Verá una opción para "Construir e implementar". Vamos a tener que cambiar un par de cosas aquí.

  1. Primero, en la sección "Configuración de compilación", asegúrese de que "Comando de compilación" esté configurado en hugo y que "Publicar directorio" esté configurado en public (el valor predeterminado que se recomienda mantener en su archivo de configuración de Hugo);
  2. A continuación, en la sección "Implementar contextos", establezca "Rama de producción" en su rama principal en su repositorio. También sugiero que sus "implementaciones de rama" se configuren en "implementar solo la rama de producción";
  3. Finalmente, en la sección "Variables de entorno", edite las variables y haga clic en "Nueva variable". Vamos a establecer el entorno de Hugo en 0.53 con el siguiente par: establezca la clave en HUGO_VERSION y el valor en 0.53 .

Ahora diríjase a su repositorio remoto y fusione su rama de desarrollo con su rama principal: este será el enlace que implementará su blog actualizado (esto se puede personalizar, pero el valor predeterminado es razonable para mí).

De vuelta a su panel de control de Netlify, las "implementaciones de producción" de su sitio deberían tener alguna actividad nueva. Si todo salió bien, esto debería procesarse y resolverse como una etiqueta "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á "Vista previa de implementación". Adelante, haz clic en él, te lo mereces. ¡Está vivo!

12. Configuración de un dominio personalizado

¿Tener la URL como my-super-site.netlify.com no es de su agrado y ya posee my-super-site.com ? Lo entiendo. ¡Cambiemos eso!

Dirígete a tu registrador de dominio y ve a la configuración de DNS de tu dominio. Aquí, tendrá 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 su dominio al balanceador de carga de Netlify, que es 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 balanceador de carga estará en la sección de configuración de DNS, en "Configuración manual de DNS para dominios personalizados raíz y www".

Cuando haya terminado, diríjase al panel de control de su sitio en Netlify y haga clic en "Configuración de dominio", donde verá "Agregar dominio personalizado". Introduzca su nombre de dominio para verificarlo.

También puede administrar sus dominios a través de su tablero en la pestaña Dominios. La interfaz se siente menos confusa en esta página, pero tal vez ayude a dar más sentido a la configuración de DNS como lo hizo conmigo.

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

Después de configurar su dominio personalizado, en "Configuración de dominio", desplácese hacia abajo hasta la sección "HTTPS" y habilite el certificado SSL/TLS. Puede tardar unos minutos, pero le otorgará un certificado gratuito: su dominio ahora se ejecuta en HTTPS.

13. Edición de contenido en Netlify CMS

Si desea editar sus artículos, cargar imágenes y cambiar la configuración de su blog como lo haría en la interfaz de back-end de WordPress, puede usar Netlify CMS, que tiene un tutorial bastante bueno disponible. Es un solo archivo que manejará todo por usted (y es independiente del generador: funcionará con Jekyll, Eleventy, etc.).

Solo necesita 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 su sitio en particular.

Vaya a la carpeta /static de la raíz de Hugo y cree una nueva carpeta a la que accederá a través my-super-site.com/FOLDER_NAME (llamaré a la mía admin ). Dentro de esta carpeta de admin , cree 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á crear es el archivo de configuración: config.yml . Le permitirá definir la configuración de su sitio (nombre, URL, etc.) para que pueda configurar lo que debe contener el frente de sus publicaciones, así como también cómo sus archivos de datos (si los hay) deben ser editables. Es un poco más complejo de configurar, pero eso no significa que no sea fácil.

Si está utilizando GitHub o GitLab, inicie su archivo config.yml con:

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

Si está utilizando 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 crea una nueva publicación, el CMS generará el slug para el nombre de archivo que puede personalizar con tres opciones:

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

Finalmente, deberá definir cómo se estructuran los datos en sus publicaciones. También definiré cómo se estructura el archivo de datos coolsites, en caso de que quiera agregar otro sitio a la lista. Estos se configuran con el objeto de collections , que definitivamente será el más detallado, junto con un buen puñado de opciones sobre las que puede leer más aquí.

 collections: - name: "articles" # Used in routes, eg, /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, eg, 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 : Puede leer más sobre cómo configurar campos individuales en la documentación de Netlify CMS Widgets, que repasa cada tipo de widget y cómo usarlos, especialmente útil para los 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 su 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 vaya a "Control de acceso", que es el último enlace en el menú del lado izquierdo. Aquí puede configurar OAuth para que se ejecute a través de GitHub, GitLab o Bitbucket proporcionando una clave y un valor secreto definido para su cuenta de usuario (no en el repositorio). Querrá usar el mismo proveedor de Git en el que está guardado su repositorio.

GitHub

Vaya a su página de "Configuración" en GitHub (haga clic en su avatar para mostrar el menú) y acceda a "Configuración de desarrollador". Haga clic en "Registrar una nueva aplicación" y proporcione los valores requeridos:

  • un nombre, como "Netlify CMS para mi súper blog";
  • una URL de página de inicio, el enlace a su 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 ".

Guarde y verá su ID de cliente y Secreto de cliente. Entréguelos al control de acceso de Netlify.

GitLab

Haga clic en su avatar para acceder a la página Configuración y haga clic en "Aplicaciones" en el menú "Configuración de usuario" a la izquierda. Verá un formulario para agregar una nueva aplicación. Provee la siguiente informacion:

  • un nombre, como "Netlify CMS para mi súper blog";
  • un URI de redireccionamiento, que debe ser " https://api.netlify.com/auth/done ";
  • los alcances que se deben revisar son:
    • api
    • read_user
    • read_repository
    • write_repository
    • read_registry

Guardar su aplicación le dará su ID de aplicación y secreto, que ahora puede 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, luego en "Configuración de Bitbucket"). En "Administración de acceso", haga clic en "OAth". En la sección "Consumidores de OAuth", haga clic en "Agregar consumidor". Puede dejar la mayoría de las cosas en sus valores predeterminados, excepto estas:

  • un nombre, como "Netlify CMS para mi súper blog";
  • una URL de devolución de llamada, que debe ser " https://api.netlify.com/auth/done ";
  • los permisos que se deben revisar son:
    • Cuenta: Correo electrónico, Leer, Escribir
    • Repositorios: lectura, escritura, administración
    • Solicitudes de extracción: lectura, escritura
    • Webhooks: leer y escribir

Después de guardar, puede acceder a su clave y secreto, que luego puede proporcionar en el control de acceso de Netlify.

Después de proporcionar los tokens, vaya a Netlify y busque la Configuración del sitio. Dirígete a "Identidad" y habilita la función. Ahora puede agregar un proveedor externo: seleccione su proveedor de Git y haga clic en "Habilitar".

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

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

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

Además, tenga en cuenta que Git LFS es algo que instaló localmente, por lo que las imágenes cargadas a través de Netlify CMS serán "normales". Si extrae su rama remota localmente, las imágenes deben convertirse a LFS, que luego puede confirmar y enviar a su rama remota. Además, Netlify CMS actualmente no es compatible con LFS, por lo que la imagen no se mostrará en el CMS, pero aparecerá en su compilación final.

Lectura recomendada : Generadores de sitios estáticos Revisados: Jekyll, Middleman, Roots, Hugo

Conclusión

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

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

¡Explorar! ¡Divertirse! ¡Blog!

Más recursos

  • Hugo Documentación
    • Instalación
    • Inicio rápido
    • Configuración
    • Plantillas
    • Taxonomías
    • Códigos cortos
    • Hugo en Netlify
  • Documentación de Netlify
    • Dominios personalizados
    • DNS administrado
    • netlify.toml Implementar secuencias de comandos
  • Documentación de Netlify CMS
    • Widgets
  • Git LFS