Durante estos últimos años he publicado muchos artículos sobre diferentes temas, pero me he dado cuenta de que aún no he escrito un artículo sobre mi equipo y mi flujo de trabajo para publicar este blog.
Material utilizado
Hardware
Mi equipo para escribir las publicaciones del blog es un portátil Huawei D14 que conseguí a buen precio, es ligero y aguanta bien el trato díario de tener que acompañarme en mis viajes de ida y vuelta al trabajo.
Como sistema operativo utilizo Arch Linux y Gnome entorno de escritorio, ya que como buen friki del cacharreo siempre quiero estar a la última, por cierto, rara vez he tenido problemas por ello.

El blog esta alojado en una Raspnerry Pi 3b+, la cual tengo separada del resto de la red de casa mediante una VLAN, que es inaccesible por el resto de equipos de las otras VLANs
Cuando termino de escribir un artículo en el portátil, lo previsualizo localmente antes de su publicación, en la Raspberry Pi o en el portátil, proceso que explico más adelante.
Software
Los artículos están escritos en Emacs utilizando org-mode para su redacción y ox-hugo como exportador markdown compatible con Hugo que es el encargado de generar el sitio.
En el momento de escribir esta publicación el software utilizado para la creación del blog es:
emacs --version
GNU Emacs 28.2
Copyright (C) 2022 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of GNU Emacs
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.
M-x org-version
Org mode versión 9.5.5 (release_9.5.5 @ /usr/share/emacs/28.2/lisp/org/)
M-x ox-hugo
ox-hugo 20221028.1631 installed Hugo Markdown Back-End for Org Export Enginey
hugo version
hugo v0.109.0+extended linux/amd64 BuildDate=unknown
En la Raspberry Pi utilizo el siguiente docker-compose para desplegar una imagen de Hugo
services:
hugo:
image: klakegg/hugo:ext-alpine
entrypoint: /bin/sh
volumes:
- "/home/carlos/web/:/src"
ports:
- "1313:1313"
stdin_open: true # docker run -i
tty: true # docker run -t
/home/carlos/web/ se corresponde con la carpeta public del proyecto
Estructura del proyecto
La estructura de directorios de este blog es la siguiente:
tree -d -L 2
.
├── archetypes
├── content
│ ├── images
│ └── posts
├── data
├── layouts
│ ├── _default
│ ├── partials
│ └── shortcodes
├── resources
│ └── _gen
├── static
│ ├── jetbrains-mono
│ └── symbols-nerd-font
└── themes
└── hugo-ficurinia
17 directories
Estructura del archivo org
Todos los artículos los guardo en un único fichero org, de esta forma puedo relacionar las publicaciones por etiquetas y categorías.
Configuración global y metadatos
El fichero .org tiene un emcabezado principal como este
# -*- mode: org; coding: utf-8; -*-
#+author: Carlos M.
#+startup: content
#+language: es
#+hugo_section: /posts
#+hugo_base_dir: /home/carlos/Documentos/proyectos/ebdl
#+hugo_auto_set_lastmod: nil
#+todo: BORRADOR | PUBLICADO
Lo que significa cada línea:
# -*- mode: org; coding: utf-8; -*-ia codificación a utilizar esUTF-8#+author: Carlos M.autor global, se propaga para cada publicación#+startup: contentle dice a Emacs que, al abrir este archivo, muestre por defecto todos los encabezados y subtítulos, pero no el contenido hasta que se presioneTABen el encabezado#+language: esidioma a usar para traducir ciertas cadenas, por ejemplo, esta opción traducirá ‘Table of contents’ al español ‘Tabla de contenidos'#+hugo_section: /postsox-hugo exportara todas los ficheros markdown a este directorio#+hugo_base_dir: /home/carlos/Documentos/proyectos/ebdlDirectorio raíz del sitio#+hugo_auto_set_lastmod: nilcuando exporto el fichero no añade la hora y fecha de modificación.#+todo: BORRADOR | PUBLICADOestados que tendrán los encabezados de las publicaciones, BORRADOR si estoy trabando en ellos y PUBLICADO si ya está terminado y listo para su publicación.
Creando una página
Mi fichero .org esta estructurado en categorías, las he ido añadiendo en función del número de publicaciones que iba creando a lo largo del tiempo.
Cada publicación creada dentro de cada encabezado hereda su categoría (@)
** Asus :@asus:
** Blog :@blog:
** Emacs :@emacs:
** Git :@git:
** GNU/Linux :@linux:
** OpenMediaVault :@openmediavault:
** OpenWrt :@openwrt:
** Programas :@programas:
** Raspberry Pi :@raspberry:
** Redes :@redes:
** Rock64Pro :@rock64pro:
** Synology :@synology:
Para crear una nueva publicación creo un nuevo encabezado con sus respectivas etiquetas para poder ser relacionadas con otras publicaciones
# -*- mode: org; coding: utf-8; -*-
#+author: Carlos M.
#+startup: content
#+language: es
#+hugo_section: /posts
#+hugo_base_dir: /home/carlos/Documentos/proyectos/ebdl
#+hugo_auto_set_lastmod: nil
#+todo: BORRADOR | PUBLICADO
* Blog
** Asus :@asus:
** Blog :@blog:
*** PUBLICADO Balance del blog 2022 :blog:
*** PUBLICADO Como publico este blog :hugo:org_mode:blog:
Cada públicocion contiene unas propiedades
:PROPERTIES:
:EXPORT_FILE_NAME: 2020-10-12-configurar-vlans-de-o2-en-outer-synology-rt2600
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :image /images/posts/2020/rt2600/rt2600-01.png
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :toc
:END:
:EXPORT_FILE_NAME:nombre del fichero md que se exportara a/posts:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :imageenlace a una imagen destacada del artículo, que también se muestra en la vista previa:toc truecrea una lista de contenido al inico de la publicación
El tema utilizado para el blog, hugo-ficurinia, admite muchos otros parámetros además de :image, puedes verlos en su sitio web
Cuando una publicación pasa del estado BORRADOR al estado PUBLICADO se genera una marca de tiempo, que sera la fecha y hora en la que se publicará en el blog, de esta forma, modificando esta marca de tiempo puedo programar cuando quiero que se publique
CLOSED: [2023-02-13 lun 07:30]
Este sería el ejemplo de una publicación:
CLOSED: [2023-02-13 lun 07:30]
:PROPERTIES:
:EXPORT_FILE_NAME: 2023-02-13-synology-daskboard-homarr
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :image /images/posts/2023/homarr/homarr-08.png
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :toc true
:END:
Exportando la página
Por último solo queda exportar nuestra publicación a un fichero markdown para que Hugo genere la página, en este artículo explico un poco mas sobre como hacer este proceso
Corrección de errores
Cuando finalizo el artículo y antes de su publicación, lo previsualizo para corregir errores, aunque siempre se me cuela mas de uno 🙈.
Normalmente lo hago desde el ordenador portátil, abriendo una consola de terminal y lanzando el servidor de Hugo con el siguiente comando:
hugo server -D -F
~/Documentos/proyectos/ebdl ❯ hugo server -D -F
Start building sites …
hugo v0.109.0+extended linux/amd64 BuildDate=unknown
| ES
-------------------+-------
Pages | 569
Paginator pages | 58
Non-page files | 2750
Static files | 33
Processed images | 0
Aliases | 1
Sitemaps | 1
Cleaned | 0
Built in 2279 ms
Watching for changes in /home/carlos/Documentos/proyectos/ebdl/{archetypes,content,data,layouts,static,themes}
Watching for config changes in /home/carlos/Documentos/proyectos/ebdl/config.toml
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Abro un navegador web e ingreso la url http://localhost:1313/, con -D veo las publicaciones con la propiedad Draft: true (borradores) y con -F muestra las publicaciones futuras.
De una manera alternativa puedo conectar con la Raspberry Pi y desde la shell del contenedor de Hugo realizar el mismo proceso que antes, pero utilizando la url de la Raspberry Pi
Publicación
Como escribí al inicio, el blog se hospeda en la Raspberry Pi, por lo que he de sincronizar los ficheros de mi ordenador portátil con ella, para ello ejecuto el siguiente script
#!/bin/bash
rsync -avzh --delete --exclude "public" /home/carlos/Documentos/proyectos/ebdl/ [email protected]:/home/carlos/web/
Una vez sincronizados los ficheros, vuelvo a construir el sitio web ejecutando el comando hugo desde la shell del contenedor o mediante la ejecución del comando /usr/bin/docker exec -it hugo-hugo-1 /bin/sh -c 'hugo' desde la terminal de la Raspberry Pi.
Normalmente suelo publicar los artículos los lunes a las 07:30 horas, y difundo en Twitter y Mastodon que he publicado un nuevo artículo
El resto de días (martes a domingo) suelo publicar un artículo de manera aleatoria en Twitter y en Mastodon, uno por la mañana y otro por la tarde.
Para realizar todo esto he programado el cron de la Raspberry Pi con los siguientes comandos
0 9,18 * * 2,3,4,5,6,0 /usr/bin/python /home/carlos/bin/ebddl2tweet.py
30 7 * * 1 /home/carlos/bin/update_ebdl.sh
45 7 * * 1 /home/carlos/bin/nuevo_art.py
0 4 * * * /usr/bin/sudo /usr/bin/rsync -avzhv --delete --exclude "public" /home/carlos/web /mnt/usb1/backups/web
La primera línea del cron es un script de python que publique en este artículo, público los artículos de manera aleatoria en Twitter y Mastodon
La segunda línea es la utilizada para publicar un nuevo artículo del blog, en realidad lo que hace es llamar al comando
hugopara volver reconstruir el sitio webLa tercera línea es otro script de python para la publicación del nuevo artículo en Twitter y Mastodon
La última línea y a modo de curiosidad hace un backup de los ficheros del blog a un dispositivo usb que tengo conectado a la Raspberry Pi
Espero que te haya gustado, pasa un gran día 🐧