aboutsummaryrefslogtreecommitdiff
path: root/blog
diff options
context:
space:
mode:
Diffstat (limited to 'blog')
-rw-r--r--blog/content/2026/02/la-antigua-nueva-escuela.gmi2
-rw-r--r--blog/content/2026/09/windows-sólo-es-fácil-a-veces.gmi6
-rw-r--r--blog/content/notes/index.gmi3
-rw-r--r--blog/content/notes/tech/how-this-site-works.gmi64
4 files changed, 75 insertions, 0 deletions
diff --git a/blog/content/2026/02/la-antigua-nueva-escuela.gmi b/blog/content/2026/02/la-antigua-nueva-escuela.gmi
index 4ec4cd31..d1b4f6d8 100644
--- a/blog/content/2026/02/la-antigua-nueva-escuela.gmi
+++ b/blog/content/2026/02/la-antigua-nueva-escuela.gmi
@@ -16,6 +16,8 @@ En 2022 recuperé mi primer blog y una lista de correo donde escribía críticas
Y finalmente, tras una semanita entretenida, aquí está la última iteración.
+=> ../../notes/tech/how-this-site-works Actualización: aquí hay una descripción casi completa en inglés.
+
La idea es explorar mecanismos para facilitar la publicación de contenido simultáneamente en la web y en el Geminiespacio.
Para ello, me aventuré a redescubrir la técnica clásica de la negociación de contenido. El nuevo motor de este blog es básicamente un generador de webs estáticas que parte de un montón de ficheros en el formato gemtext de Gemini, masajeándolo un poco y creando una segunda copia en formato HTML.
diff --git a/blog/content/2026/09/windows-sólo-es-fácil-a-veces.gmi b/blog/content/2026/09/windows-sólo-es-fácil-a-veces.gmi
index 6b2626ff..3f87bdd7 100644
--- a/blog/content/2026/09/windows-sólo-es-fácil-a-veces.gmi
+++ b/blog/content/2026/09/windows-sólo-es-fácil-a-veces.gmi
@@ -22,5 +22,11 @@ El segundo, y más importante, es que el USB de recuperación te recupera un Win
Seguramente esto es más culpa de Lenovo que de Microsoft. (Bastante decepcionante, hacen mis portátiles no Apple favoritos y uno esperaría que con su orientación empresarial supiesen dar una buena experiencia de instalación de Windows.) Pero es un recordatorio de que Windows es fácil en el camino trilladísimo de comprar un equipo con Windows preinstalado. (Y sospecho que Linux funciona igual de bien en ese escenario.) Linux tiene sus complicaciones y la experiencia para muchos es inferior, pero oye, al menos es gratis cuando los dos pueden fastidiarte una tarde igual.
+Actualización al día siguiente:
+
+Una peculiaridad de este portátil es que como muchos Lenovo, tiene las teclas CTRL y FN al revés de lo normal, cosa que me toca la moral. Y como es común en esta época, las teclas de función por defecto no hacen de teclas de función.
+
+En la mayoría de ThinkPads, la BIOS permite configurar esto. Pero esto es un tablet y el teclado en realidad es un dispositivo USB y la BIOS no soporta trastear con él. Lenovo tiene algunas utilidades para jugar con esto. Yo anteriormente usé "Lenovo Vantage" para esto, que es un poco frágil, pero permite hacer actualizaciones que no vienen en Windows Update y configurar el teclado. Por algún motivo, la imagen de recuperación de Lenovo traía "Lenovo Commercial Vantage", que muestra las opciones, pero no permite aplicarlas. Y ahora, "Lenovo Vantage" tampoco parece querer ni mostrarme las opciones.
+
=> https://github.com/alexpdp7/windows-usb/ [1] Un script que tengo para convertir la imagen de Windows que ofrece Microsoft en un USB desde Linux
=> https://github.com/alexpdp7/rpi-zero-usb-iso/ Además, si tenéis una Rasperry Pi Zero a mano, podéis usar esto para convertirla en un práctico USB "virtual"
diff --git a/blog/content/notes/index.gmi b/blog/content/notes/index.gmi
index dea7ed8e..95933044 100644
--- a/blog/content/notes/index.gmi
+++ b/blog/content/notes/index.gmi
@@ -12,8 +12,11 @@ Notes about some books and long articles I like:
=> cliffs/governable-spaces Governable Spaces
=> cliffs/peopleware Peopleware
=> cliffs/the-tyranny-of-structurelessness The tyranny of structurelessness
+
## Tech
+=> tech/how-this-site-works How this site works
+
=> tech/misc-linux-stuff Misc Linux stuff
=> tech/running-commands-in-linux Running commands in Linux
=> tech/ssh-for-beginners SSH for beginners
diff --git a/blog/content/notes/tech/how-this-site-works.gmi b/blog/content/notes/tech/how-this-site-works.gmi
new file mode 100644
index 00000000..9c78b9fc
--- /dev/null
+++ b/blog/content/notes/tech/how-this-site-works.gmi
@@ -0,0 +1,64 @@
+# How this site works
+
+## The use of gemtext
+
+=> https://github.com/alexpdp7/alexpdp7/tree/master/blog/content This site is composed of many gemtext files following the structure of the site.
+
+Gemtext is the native response format of the Gemini protocol. Gemtext is much simpler and constrained than Markdown. Gemtext has only:
+
+* Three levels of headers
+* Links as full lines, no inline links
+* Single-level lists and quotes
+* Preformatted blocks
+
+Gemtext can be parsed with only a single state flag (whether you are in a preformatted block or not) and use only simple text parsing operations.
+
+This means that a full correct gemtext parser can be coded in a few hours with a few hundred lines in code. Additionally, gemtext constrains your content to the bare minimum structure. And unlike HTML files that have a complex hierarchical structure, gemtext files can for example be combined by plain text file concatenation; for example, you can concatenate a header, body, and footer with the cat command.
+
+The Gemini protocol suite of protocols also describes a way to derive a feed from a gemtext page. Links in a gemtext page whose link text starts with a YYYY-MM-DD timestamp form an implicit feed. Contrary to traditional feed formats like RSS and Atom, gemtext implicit feeds are easy to create with a plain text editor.
+
+## Static site generation
+
+As a first step, a process converts every foo/bar.gmi file to a foo/bar.html HTML file.
+
+=> https://github.com/alexpdp7/coppewebite/tree/main/gemini-to-web This is done with the coppewebite-to-html command part of my coppewebite suite of Gemini tools.
+
+Then, the root index.gmi is generated. The header is a static gemtext snippet. Then, coppewebite-indexer generates a series of links in chronological order to the articles in YYYY/MM/article.gmi files that follows the header.
+
+The series of links is an implicit gemtext feed, which the coppewebite-to-rss tool converts to RSS. index.gmi and index.rss both have an implicit gemtext feed and an RSS feed. Using coppewebite-to-html again, index.gmi is converted to index.html containing metadata embedding the feed.
+
+The result is a directory with .html, .gmi, and .rss files, including index.html, index.rss, index.gmi, but also notes/tech/how-this-site.works.html and .gmi.
+
+## Serving the static site
+
+Apache httpd is the main web server for this site.
+
+The directory that contains the static site has the MultiViews option enabled. This means that when serving foo/bar, Apache serves foo/bar.html or foo/bar.gmi depending on the Accept header of the request.
+
+For web browsers, which send text/html as their Accept header, the .html file is served. However, you can append .gmi to the URL to request the gemtext version.
+
+Interestingly, when the request does not have an Accept header that selects a unique file, Apache replies with the smallest file, which frequently is the gemtext version. When using curl in a terminal, Apache replies with the gemtext version, which is nicer to read on a terminal.
+
+=> https://github.com/alexpdp7/coppewebite/tree/main/gemini-from-http gemini-from-http from my coppewebite suite is the Gemini server.
+
+gemini-to-http serves all Gemini requests by making an equivalent HTTP request to a web server running on the same host with a text/gemini Accept header. Therefore, when requesting gemini://alex.corcoles.net/foo this queries Apache for https://alex.corcoles.net/foo, which returns foo.gmi that is proxied back to the Gemini client.
+
+(The site is actually published at two different URLs, so all internal links are relative. Also extra care is required to never include extensions in links. But the differences between the gemtext and HTML conversion is minimal.)
+
+## Publishing the site
+
+The site is part of a Git repository. The server hosting this site has this Git repository.
+
+=> https://github.com/alexpdp7/alexpdp7/blob/master/blog/post-receive The Git repository on the server has a post-receive hook that runs the site build script and stores the result in the Apache document root for the site.
+
+## Observations
+
+I think this is a pretty optimal system to host a dual HTTP/HTML + Gemini/gemtext site. The coppewebite suite is less than 700 lines of Python code that only depends on two HTML libraries and an RSS library. The site-specific code is two shell scripts totaling less than 100 lines.
+
+Beyond the content, the Gemini server has barely any configuration; most of the small configuration is in Apache httpd. The overhead to support the dual site is minimal.
+
+(And if instead of using the indexer to generate the list of blog entries on the front page, you maintain a list by hand, you can eliminate a significant amount of code. The Git hook for publishing is another significant amount of complex code that you can avoid.)
+
+I believe the tools I use enable anyone to publish a site by using only a plain text editor and requiring much less knowledge about web technologies than using regular HTML (especially for the feeds).
+
+I would like to package all of this in a way that enables anyone to create sites with little effort.