El pequeño generador de sitios estáticos de recarga en caliente desde Shell. Asume Bash 4.4+.
ADVERTENCIA: ¡Aquí estén los yaks!
El trabajo de shite
es ayudarme a crear mi sitio web: https://evalapply.org Por lo tanto, el alcance de shite
, el conjunto de (malas) características y el pulido siempre serán de grado de producción, donde la producción es "funciona en mi(s) máquina(s). )" :)
Tabla de contenido
Bueno, shite
tiene como objetivo hacer sitios web.
Es un pequeño sistema de publicación hecho de flujos de trabajo canalizados, opcionalmente impulsados por flujos de eventos de archivos (para los bits de recarga en caliente).
No sorprenderá a un caballero hacker de Perl/PHP del siglo pasado.
Existe porque uno silba tonterías y afeita yaks.
Esto es básicamente lo que hace (ref: la función shite_templating_publish_sources
).
cat " ${watch_dir} /sources/ ${url_slug} " |
__shite_templating_compile_source_to_html ${file_type} |
__shite_templating_wrap_content_html ${content_type} |
__shite_templating_wrap_page_html |
${html_formatter_fn} |
tee " ${watch_dir} /public/ ${slug} .html "
# The complete "business logic" is 300-ish lines as of this comment,
# counted as all lines except comments and blank lines.
grep -E -v " s?#|^$ "
./bin/{events,metadata,templating,utils,hotreload}.sh |
wc -l
Antes de que te excites demasiado, puedo advertirte que la licencia del MIT significa que no me tiene que importar una mierda si este pequeño fabricante de mierda no logra hacer que tu mierda funcione. Las contribuciones están repletas de más advertencias.
Y por último, pero no menos importante, por la presente decreto que todo el texto aquí incluido se lea en voz alta de Sean Connery.
En mis sueños shite
, deseo...
Sobre todo, mantenerla (la "lógica empresarial") pequeña . Lo suficientemente pequeño como para almacenar en caché, depurar y refactorizar en mi cabeza.
Para instalar y usar sin permiso de superusuario.
Para evitar al máximo las cadenas de herramientas y crear dependencias. Sin gemas / npms / venvs / what-have-yous. Por tanto, Bash es el lenguaje, porque Bash está en todas partes. Y paquetes estándar como pandoc
o tidy
, cuando se necesita una funcionalidad avanzada específica .
Plantillas sin dependencia con HTML simple configurado en buenos documentos heredocs.
Sistema de metadatos simple, espacio de nombres de contenido, organización de activos estáticos, etc.
Servidor web opcional (o cualquier tipo de proceso de servidor). Después de todo, apuntamos a sitios estáticos que funcionan bien con la navegación file://
.
Construirlo a partir de piezas pequeñas, componibles, puramente funcionales, similares a herramientas Unix, porque me gustan mucho ese tipo de cosas.
Para tener un flujo de trabajo fluido de edición, guardado, compilación y vista previa similar a REPL.
Accidentalmente reinicié el blog después de un largo tiempo. Antes de poder poner palabras en la nube, me metí en problemas con los "modernos" generadores de sitios estáticos. Porque WordPress es del siglo pasado (o eso me dije a mí mismo). Luego me molestó la magia de creación de plantillas personalizadas de SSG Jamstack, etc. Ahora estoy en el camino oscuro de hacer esto. Se está escribiendo un blog sobre esto en: mierda: sitios estáticos desde shell: parte 1/2
Utilizo mierda principalmente en modo "hotreload", principalmente para escribir publicaciones (en modo org) y obtener una vista previa en vivo (en Firefox). Menos principalmente, para obtener una vista previa en caliente de las modificaciones de estilos y/o plantillas de página. Lo menos importante es que, después de trabajar interminablemente en una publicación, la uso en modo "no recargar en caliente" para realizar una reconstrucción completa del sitio.
Ejemplos de demostración de mierda a continuación.
Básicamente, esto significa que si creo, actualizo o elimino cualquier archivo en sources
, debe traducirse automáticamente a HTML, publicarse localmente al public
y provocar una navegación de página adecuada o una acción de recarga en el navegador web donde está abierto mi sitio.
Llame al script "principal" en una nueva sesión de terminal o panel tmux limpio.
./shite.sh
Abre de manera útil el archivo de índice en Firefox, de acuerdo con los valores predeterminados que configuré en la matriz shite_global_data
en ./shite.sh
.
En su Emacs o Vim, abra algún archivo de contenido en sources
. Edite, guarde y observe cómo aparece el contenido en el navegador. (Sí, especificar Emacs/Vim es una tontería, porque activo acciones activas basadas en eventos de inotify. Aparentemente, diferentes editores realizan actualizaciones de archivos de manera diferente. Utilizo Emacs o Vim, así que observo los eventos que causan, por lo que funciona en mi máquina. : )).
Con frecuencia, el navegador recuerda la posición de desplazamiento, lo cual es claro. A veces la recarga en caliente es, bueno, una mierda. Así que simplemente presiono la barra espaciadora y guardo el archivo de contenido para activar la recarga en caliente nuevamente.
Vaya a algún recurso estático, como una hoja de estilo CSS. Modificar algo, como el valor del color de fondo. Guarde y observe el cambio de color en el navegador.
Modifique algún fragmento de plantilla en templates.sh
, digamos, plantilla de publicación de blog. Luego cambie a algún archivo de contenido de publicación de blog y modifíquelo para activar la creación de la página con la plantilla modificada (por ejemplo, presione la barra espaciadora y guarde).
Esto es un truco. La página raíz index.org en fuentes es especial. Si lo modifico, significa que quiero reconstruir las listas de publicaciones para la página de índice, las etiquetas y también reconstruir los metaarchivos relacionados como la fuente RSS, el mapa del sitio, robots.txt, etc.
En una nueva sesión de terminal limpia, llame a shite.sh
con "no" y, opcionalmente, con la base_url
del entorno de implementación:
Reconstruya el sitio completo para la navegación "local" file:///. Verdaderamente "sin servidor" :)
./shite.sh " no "
Reconstruir el sitio completo para publicarlo en mi dominio.
./shite.sh " no " " https://evalapply.org "
Estas banderas alteran el comportamiento del sistema.
SHITE_BUILD
en "caliente" ejecutará el sistema de eventos en modo "monitor", lo que a su vez impulsa el comportamiento de recarga en caliente. Configurarlo en "no" suprimirá la recarga en caliente del navegador.SHITE_DEBUG_TEMPLATES
en "depurar" hará que las plantillas se obtengan primero, antes de publicar cualquier contenido fuente con plantilla. shite
es bastante Unixy por dentro. O eso me gustaría pensar.
El código es Bash de estilo de programación funcional. Todo es una función. La mayoría de las funciones son funciones puras: pequeñas herramientas de Unix en sí mismas. La mayor parte de la lógica está orientada a canalizaciones. Esto funciona sorprendentemente bien, porque Shell no es un mal lugar para la FP.
También quería una experiencia interactiva en vivo similar a REPL al escribir con shite
, porque me gusta trabajar en tiempos de ejecución interactivos en vivo como Clojure y Emacs.
Entonces, shite
se ha convertido en este sistema totalmente reactivo impulsado por eventos capaz de compilar y recargar en caliente al guardar.
Hay tres espacios de nombres de directorio principales:
sources
que albergan el contenido "fuente", como publicaciones de blog escritas en modo org, así como CSS, Javascript y otros activos estáticos.public
para los artefactos compilados/construidos.bin
para el código de construcción de mierda El esquema de nomenclatura de URL sigue la estructura de subdirectorios en sources
y se replica tal cual en la estructura de directorios pubilic
. Dado que este es un esquema de espacio de nombres de URL estándar, también se aplica directamente al contenido publicado. Así:
file:///absolute/path/to/shite/posts/slug/index.html
http://localhost:8080/posts/slug/index.html
https://your-domain-name.com/posts/slug/index.html
Todas las funciones "públicas" tienen un espacio de nombres como shite_the_func_name
. Todas las funciones "privadas" tienen un espacio de nombres como __shite_the_func_name
.
Existen funciones para:
En una nueva sesión de terminal limpia:
source ./bin/utils_dev.sh
shitTABTAB
o __shiTABTAB
en la línea de comando para autocompletar.type -a func_name
para imprimir la definición de la función y leer su API.shite_global_data
y shite_page_data
según sea necesario. Existen plantillas para fragmentos de página (como encabezado, pie de página, navegación) y para definiciones de página completa (como la plantilla de página predeterminada). Estos están escritos como HTML simple incluido en heredocs. ./bin/templates.sh
los proporciona.
Las plantillas se completan con datos variables de diferentes fuentes:
shite_global_data
contiene metadatos de todo el sitio y shite_page_data
contiene metadatos específicos de la página. Algún proceso externo debe preestablecer estas matrices antes de procesar cualquier página.Por ejemplo, una página completa se puede construir de la siguiente manera:
cat ./sample/hello.md |
pandoc -f markdown -t html |
cat << EOF
<!DOCTYPE html>
<html>
<head>
$( shite_template_common_meta )
$( shite_template_common_links )
${shite_page_data[canonical_url]}
</head>
<body ${shite_page_data[page_id]} >
$( shite_template_common_header )
<main>
$( cat - )
</main>
$( shite_template_common_footer )
</body>
</html>
EOF
El sistema de metadatos shite
se define como pares clave-valor. Las claves nombran los elementos de metadatos y se asociarían con cualquier valor de ese tipo. Ejemplos a continuación.
Como se señaló anteriormente, los metadatos en tiempo de ejecución se transportan en el entorno mediante las matrices asociativas shite_global_data
y shite_page_data
. Estos pueden completarse mediante construcción directa, así como actualizarse desde fuentes externas.
Cada página puede especificar sus propios metadatos en el "anterior" en la parte superior de la página. Esto se utilizará además de los metadatos de la página derivados de otras fuentes.
shite
espera que escribamos el contenido inicial usando una sintaxis que sea compatible con el tipo de contenido dado, de la siguiente manera.
Utilice las líneas de comentario # SHITE_META
para demarcar los metadatos de estilo de organización shite
también deben analizarse como metadatos específicos de la página.
# SHITE_META
#+title: This is a Title
#+slug: this/is/a/slug
#+date: Friday 26 August 2022 03:38:01 PM IST
#+tags: foo bar baz quxx
# SHITE_META
#+more_org_metadata: but not processed as shite metadata
#+still_more_org_metadata: and still not processed as shite metadata
* this is a top level heading
this is some orgmode content
#+TOC: headlines 1 local
** this is a sub heading
- this is a point
- this is another point
- a third point
Escriba la portada YAML estilo Jekyll, encuadrada entre ---
separadores.
---
TITLE : This is a Title
slug : this/is/a/slug
DATE : Friday 26 August 2022 03:38:01 PM IST
TAGS : foo BAR baz QUXX
---
# this is a heading
this is some markdown content
## this is a subheading
- this is a point
- this is another point
- a third point
Simplemente podemos usar etiquetas <meta>
estándar, que obedecen a esta convención: <meta name="KEY" content="value">
.
< meta name =" TITLE " content =" This is a Title " >
< meta name =" slug " content =" this/is/a/slug " >
< meta name =" DATE " content =" Friday 26 August 2022 03:38:01 PM IST " >
< meta name =" TAGS " content =" foo BAR baz QUXX " >
< h1 > This is a heading </ h1 >
< p > This is some text </ p >
< h2 > This is a subheading </ h2 >
< p >
< ul >
< li > This is a point </ li >
< li > This is another point. </ li >
< li > This is a third point. </ li >
</ ul >
</ p >
¡Aquí estén los yaks!
Al estar completamente mimado por los gratificantes flujos de trabajo interactivos en vivo estilo Clojure/Lisp/Spreadsheet, también quiero recargar y navegar en caliente en la creación de mierda.
Pero no parece existir un servidor/herramienta de desarrollo web independiente y en vivo que no quiera que descargue la mitad de lo conocido de Internet como dependencias. Como dije antes, algo que no quiero hacer en absoluto .
DuckSearch entregó el modo impaciente de Emacs, que es bastante atractivo, pero no quiero conectarlo a mi Emacs. Afortunadamente, también entregó esta emocionante idea con 'inotify-tools' y 'xdotool': github.com/traviscross/inotify-refresh
¡Copia caliente!
Porque, ¿qué podría ser más atractivo que que mi computadora presione la tecla F5 por mí? Como si supiera lo que realmente quería en el fondo de mi corazón.
El subsistema de eventos es ortogonal a todo lo demás y se compone con el resto del sistema.
El diseño es una arquitectura de transmisión estándar, a saber. Esté atento a los eventos del sistema de archivos, luego filtre, deduplica, analice y enrute (tee) a diferentes procesadores de eventos. Actualmente sólo existen dos procesadores de este tipo; uno para compilar y publicar la página o activo asociado con el evento, otro para recargar en caliente el navegador (o navegar en caliente) dependiendo del mismo evento.
Básicamente esto:
# detect file events
__shite_detect_changes ${watch_dir} ' create,modify,close_write,moved_to,delete ' |
__shite_events_gen_csv ${watch_dir} |
# hot-compile-and-publish content, HTML, static, etc.
tee >( shite_templating_publish_sources > /dev/null ) |
# browser hot-reload
tee >( __shite_hot_cmd_public_events ${window_id} ${base_url} |
__shite_hot_cmd_exec )
Los eventos son simplemente un flujo de registros CSV estructurados de esta manera:
unix_epoch_seconds,event_type,base_dir,sub_dir,url_slug,file_type,content_type `
Usamos diferentes partes del registro de eventos para provocar diferentes tipos de acciones.
El script inotify-refresh vinculado anteriormente intenta actualizar periódicamente un conjunto de ventanas del navegador. Nosotros, sin embargo, queremos tener muchas ganas. Cualquier acción de edición en nuestros archivos de contenido y/o activos estáticos debe activar instantáneamente acciones de recarga/navegación en caliente en la pestaña del navegador que muestra nuestra mierda.
Queremos definir distintos escenarios de recarga: depósitos mutuamente excluyentes y colectivamente exhaustivos en los que podemos asignar eventos de archivos que queremos monitorear.
Si hacemos esto, entonces podemos modelar las actualizaciones como una especie de registro de escritura anticipada, registrar eventos a través de un canal de análisis, asociarlos con el escenario de coincidencia exacta y finalmente provocar la acción. Por ejemplo:
Actualizar la pestaña actual cuando
Vete a casa cuando
Navegar al contenido cuando
Dado que estamos haciendo que la computadora emule nuestras propias acciones del teclado, puede alterar nuestras acciones personales. Si nos limitamos a escribir nuestra mierda en nuestro editor de texto y dejamos que la computadora haga la recarga en caliente, no deberíamos sentirnos molestos.
Hay muchos yaks en el mundo.
Para un mojo de publicación multisitio verdaderamente omnipresente:
shite
debería estar disponible en mi RUTA.Este es un yak pequeño. Probablemente me lo afeitaré pronto.
Obviamente, uno puede usar los trabajos de CI de hosts git populares para activar compilaciones shite
. Pero, ¿por qué utilizar tecnología torpe del siglo actual, cuando ya hemos avanzado al estado del arte de finales del siglo XX... completamente en streaming y completamente reactivo?
Dejando a un lado el sarcasmo, no veo por qué no se puede usar el mismo sistema de eventos para agregar soporte de implementación en caliente en una máquina remota que ejecuto.
En la caja remota:
sources
del sitiosources
(menos la observación del navegador).En mi caja local:
https://mydomain.com/posts/hello/index.html
Haga algo a través de SSH para que la actualización del navegador vuelva al cuadro local, en caso de implementaciones en caliente en un servidor remoto.
¿Quizás algún escenario de configuración/desmontaje del tiempo de "desarrollo/redacción"? ¿Quizás una función 'dev_server' que usamos para iniciar una nueva sesión de escritura de mierda?
Si llegaste hasta aquí y aún quieres contribuir...
¿Por qué?
¿Por qué, en nombre de todo lo que es santo y bueno, querrías hacerlo? ¿No es deslumbrantemente obvio que esto es obra de un tonto? ¿No has oído que Bash ni siquiera es un lenguaje de programación real? ¿Y no es tremendamente obvio que sus relaciones públicas languidecerán eternamente y sus comentarios caerán en un vacío sin nombre?
Sí, enviar parches es una idea terrible.
¡Pero por favor envíame un correo electrónico con tus esperanzas y sueños sobre tu creador de mierda! Leí el correo electrónico en mi nombre y apellido en gmail.
Juntos podemos silbar melodías tontas y afeitar nuestros respectivos yaks, a nuestra manera especial.
Que La Fuente esté con nosotros.
Este trabajo tiene doble licencia bajo la licencia MIT y la licencia CC By-SA 4.0.
Identificador de licencia SPDX: mit OR cc-by-sa-4.0