Le petit générateur de site statique à rechargement à chaud depuis Shell. Suppose Bash 4.4+.
AVERTISSEMENT : voici les yacks !
Le travail de shite
est de m'aider à créer mon site Web : https://evalapply.org Ainsi, la portée de shite
, l'ensemble des (mauvaises) fonctionnalités, le polissage sera toujours de niveau production, où la production consiste à "travailler sur ma (mes) machine(s). )" :)
Table des matières
Eh bien, shite
a pour but de créer des sites Web.
Il s'agit d'un petit système de publication composé de flux de travail en pipeline, éventuellement pilotés par des flux d'événements de fichiers (pour les bits de rechargement à chaud).
Cela ne surprendra pas un hacker Perl/PHP du siècle dernier.
Il existe parce qu'on siffle des airs idiots et qu'on rase des yaks.
C'est essentiellement ce qu'il fait (réf : la fonction 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
Avant que vous ne soyez trop excité, puis-je vous prévenir que la licence MIT signifie que je n'ai rien à foutre si ce petit créateur de merde ne parvient pas à faire fonctionner votre merde. La contribution regorge de plus d’avertissements.
Et enfin et surtout, je décrète par la présente que tous les textes contenus dans le présent document soient lus en voixh de Sean Connery.
Dans mes rêves shite
, je désire...
Surtout, pour que la « logique métier » reste petite . Assez petit pour mettre en cache, déboguer et refactoriser dans ma tête.
À installer et à utiliser sans l'autorisation du superutilisateur.
Pour éviter extrêmement les chaînes d’outils et créer des dépendances. Pas de gemmes / npms / venvs / qu'avez-vous. Ainsi, Bash est le langage, car Bash est partout. Et des packages standards comme pandoc
ou tidy
, quand on a besoin de fonctionnalités avancées spécifiques .
Modèles sans dépendance avec du HTML simple défini dans de bons vieux héréditaires.
Système de métadonnées simple, espace de noms du contenu, organisation des actifs statiques, etc.
Serveur Web facultatif (ou tout type de processus serveur d'ailleurs). Après tout, nous visons des sites statiques qui fonctionnent très bien avec la navigation file://
.
Pour le construire à partir de petites pièces composables, purement fonctionnelles, semblables à des outils Unix, parce que j'aime beaucoup ce genre de choses.
Pour me donner un flux de travail d'édition-sauvegarde-construction-aperçu transparent de type REPL.
J'ai accidentellement recommencé à bloguer après une longue pause. Avant de pouvoir mettre des mots dans le cloud, je me suis débrouillé avec des générateurs de sites statiques « modernes ». Parce que WordPress appartient tellement au siècle dernier (du moins c'est ce que je me suis dit). Ensuite, j'ai été ennuyé par la magie de la création de modèles sur mesure SSG Jamstack, etc. Maintenant, je suis sur le chemin sombre pour réaliser cela. Il est blogué sur : merde : sites statiques de Shell : partie 1/2
J'utilise shite principalement en mode "hotreload", principalement pour écrire des articles (en mode org) et les prévisualiser en direct (dans Firefox). Moins principalement, pour prévisualiser à chaud les modifications apportées aux styles et/ou aux modèles de page. Le moins principalement, après avoir travaillé interminablement sur un article, je l'utilise en mode "ne pas recharger à chaud" pour effectuer une reconstruction complète du site.
exemples de démonstration de merde ci-dessous.
Fondamentalement, cela signifie que si je crée, mets à jour, supprime un fichier sous sources
, il doit automatiquement être traduit en HTML, être publié localement sur public
et provoquer une navigation de page appropriée ou une action de rechargement dans le navigateur Web, où mon site est ouvert.
Appelez le script "principal" dans une nouvelle session de terminal ou un volet tmux.
./shite.sh
Il ouvre utilement le fichier d'index dans Firefox, selon les valeurs par défaut que j'ai définies dans le tableau shite_global_data
dans ./shite.sh
.
Dans votre Emacs ou Vim, ouvrez un fichier de contenu sous sources
. Modifiez, enregistrez et regardez le contenu apparaître dans le navigateur. (Oui, spécifier Emacs/Vim est ridicule, car je déclenche des actions à chaud basées sur des événements inotify. Apparemment, différents éditeurs effectuent les mises à jour de fichiers différemment. J'utilise Emacs ou Vim, donc je surveille les événements qu'ils provoquent, donc cela fonctionne sur ma machine. : )).
Souvent, le navigateur mémorise la position de défilement, ce qui est pratique. Parfois, le rechargement à chaud est, eh bien, de la merde. Je viens donc d'appuyer sur l'espace et d'enregistrer le fichier de contenu pour déclencher à nouveau le rechargement à chaud.
Accédez à un actif statique, comme une feuille de style CSS. Modifiez quelque chose, comme la valeur de la couleur d'arrière-plan. Enregistrez et regardez le changement de couleur dans le navigateur.
Ajustez un fragment de modèle dans templates.sh
--- disons, un modèle d'article de blog. Passez ensuite à un fichier de contenu d'article de blog et modifiez-le pour déclencher la création de page avec le modèle modifié (par exemple, appuyez sur Espace et enregistrez).
C'est un hack. La page racine index.org sous sources est spéciale. Si je le modifie, cela signifie que je veux reconstruire les listes de publications pour la page d'index, pour les balises, et également reconstruire les méta-fichiers associés comme le flux RSS, le plan du site, le robots.txt, etc.
Dans une nouvelle session de terminal propre, appelez shite.sh
avec "no", et éventuellement avec la base_url
de l'environnement de déploiement :
Reconstruisez le site complet pour la navigation fichier:/// « local ». Vraiment "sans serveur" :)
./shite.sh " no "
Reconstruire le site complet pour publication sous mon domaine.
./shite.sh " no " " https://evalapply.org "
Ces indicateurs modifient le comportement du système.
SHITE_BUILD
sur "hot" exécutera le système d'événements en mode "moniteur", ce qui à son tour détermine le comportement de rechargement à chaud. Le définir sur « non » supprimera le rechargement à chaud du navigateur.SHITE_DEBUG_TEMPLATES
sur "debug", les modèles seront d'abord recherchés, avant de publier tout contenu source basé sur un modèle. shite
est assez Unixy à l'intérieur. C'est du moins ce que j'aimerais penser.
Le code est un style de programmation fonctionnel Bash. Tout est fonction. La plupart des fonctions sont de pures fonctions --- de petits outils Unix en elles-mêmes. La plupart des logiques sont orientées pipeline. Cela fonctionne étonnamment bien, car Shell n'est pas un mauvais endroit pour FP.
Je voulais également une expérience interactive en direct de type REPL lors de l'écriture avec shite
, car j'aime travailler dans des environnements d'exécution en direct/interactifs comme Clojure et Emacs.
Ainsi, shite
est devenu ce système entièrement réactif, piloté par les événements, capable de créer et de recharger à chaud lors de la sauvegarde.
Il existe trois espaces de noms de répertoire principaux :
sources
hébergeant le contenu « source », comme les articles de blog écrits en mode org, ainsi que CSS, Javascript et autres ressources statiques.public
pour les artefacts compilés / construitsbin
pour le code du bâtiment de la merde Le schéma de dénomination des URL suit la structure des sous-répertoires sous sources
et est répliqué tel quel sous la structure du répertoire pubilic
. Puisqu’il s’agit d’un système d’espacement de noms d’URL standard, il s’applique également directement au contenu publié. Comme ça :
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
Toutes les fonctions "publiques" ont un espace de noms shite_the_func_name
. Toutes les fonctions "privées" ont un espace de noms comme __shite_the_func_name
.
Des fonctions existent pour :
Dans une nouvelle session de terminal propre :
source ./bin/utils_dev.sh
shitTABTAB
ou __shiTABTAB
sur la ligne de commande pour les saisies semi-automatiques.type -a func_name
pour imprimer la définition de la fonction et lire son API.shite_global_data
et shite_page_data
selon vos besoins. Des modèles existent pour les fragments de page (comme l'en-tête, le pied de page, la navigation) et pour les définitions de page complète (comme le modèle de page par défaut). Ceux-ci sont écrits en HTML brut enveloppé dans des heredocs. ./bin/templates.sh
les fournit.
Les modèles sont remplis de données variables provenant de différentes sources :
shite_global_data
contient des métadonnées à l'échelle du site et shite_page_data
contient des métadonnées spécifiques à la page. Certains processus extérieurs doivent prédéfinir ces tableaux avant de traiter une page.Par exemple, une page complète peut être construite comme suit :
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
Le système de métadonnées de shite
est défini sous forme de paires clé-valeur. Les clés nomment les éléments de métadonnées et seraient associées à n'importe quelle valeur de ce type. Exemples ci-dessous.
Comme indiqué précédemment, les métadonnées d'exécution sont transportées dans l'environnement par les tableaux associatifs shite_global_data
et shite_page_data
. Ceux-ci peuvent être complétés par construction directe, ainsi que mis à jour à partir de sources externes.
Chaque page peut spécifier ses propres métadonnées dans « avant-propos » en haut de la page. Ceci sera utilisé en plus des métadonnées de page dérivées d'autres sources.
shite
s'attend à ce que nous écrivions le texte préliminaire en utilisant une syntaxe compatible avec le type de contenu donné, comme suit.
Utilisez les lignes de commentaires # SHITE_META
pour délimiter les métadonnées de style organisation que shite
devrait également analyser en tant que métadonnées spécifiques à la page.
# 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
Écrivez des éléments de présentation YAML de style Jekyll, encadrés entre ---
séparateurs.
---
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
On peut simplement utiliser des balises <meta>
standards, qui obéissent à cette convention : <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 >
Voici les Yaks !
Étant entièrement gâché par les flux de travail interactifs en direct insta-gratifiants de style Clojure/Lisp/Spreadsheet, je veux également un rechargement à chaud et une navigation à chaud dans la création de merde.
Mais il ne semble pas exister de serveur/outil de développement Web autonome en direct qui ne souhaite pas également que je télécharge la moitié de l'Internet connu sous forme de dépendances. Comme je l’ai déjà dit, c’est une chose que je ne veux absolument pas faire.
DuckSearch a livré le mode impatient d'Emacs, ce qui est assez chaud, mais je ne veux pas câbler cela avec mon Emacs. Heureusement, il a également généré cette onde cérébrale passionnante mettant en vedette « inotify-tools » et « xdotool » : github.com/traviscross/inotify-refresh
Copie chaude !
Parce que quoi de plus chaud que mon ordinateur qui claque sur la touche F5 pour moi ? Comme s’il savait ce que je voulais vraiment au plus profond de mon cœur.
Le sous-système événementiel est orthogonal à tout le reste et compose avec le reste du système.
La conception est une architecture de streaming standard, à savoir. surveillez les événements du système de fichiers, puis filtrez-les, dédupliquez-les, analysez-les et acheminez-les (te) vers différents processeurs d'événements. Actuellement, il n’existe que deux processeurs de ce type ; un pour compiler et publier la page ou l'actif associé à l'événement, un autre pour recharger à chaud le navigateur (ou naviguer à chaud) en fonction du même événement.
En gros, ceci :
# 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 )
Les événements sont simplement un flux d'enregistrements CSV structuré comme ceci :
unix_epoch_seconds,event_type,base_dir,sub_dir,url_slug,file_type,content_type `
Nous utilisons différentes parties de l'enregistrement de l'événement pour provoquer différents types d'actions.
Le script inotify-refresh mentionné ci-dessus tente d'actualiser périodiquement un ensemble de fenêtres de navigateur. Nous voulons cependant être très impatients. Toute action de modification sur nos fichiers de contenu et/ou nos ressources statiques doit déclencher instantanément des actions de rechargement/navigation à chaud dans l'onglet du navigateur qui affiche notre merde.
Nous souhaitons définir des scénarios de rechargement distincts : des compartiments mutuellement exclusifs et collectivement exhaustifs dans lesquels nous pouvons mapper les événements de fichiers que nous souhaitons surveiller.
Si nous faisons cela, nous pouvons alors modéliser les mises à jour comme une sorte de journal à écriture anticipée, transmettant les événements via un pipeline d'analyse, les associant au scénario de correspondance exacte, puis finalement provoquant l'action. Par exemple:
Actualiser l'onglet actuel lorsque
Rentre chez toi quand
Accédez au contenu lorsque
Puisque nous demandons à l'ordinateur d'émuler nos propres actions au clavier, cela peut perturber nos actions personnelles. Si nous nous contentons d'écrire notre merde dans notre éditeur de texte et laissons l'ordinateur faire le travail de rechargement à chaud, nous ne devrions pas être ennuyés.
Il existe de nombreux Yaks dans le monde.
Pour un mojo de publication multisite vraiment omniprésent :
shite
devrait être disponible sur mon PATHC'est un petit yak. Je vais probablement le raser bientôt.
Évidemment, on peut utiliser les tâches CI des hôtes git populaires pour déclencher des builds shite
. Mais pourquoi utiliser une technologie maladroite du siècle actuel, alors que nous avons déjà atteint l'état de l'art de la fin des années 1900... entièrement en streaming et entièrement réactif ?
Sarcasam mis à part, je ne vois pas pourquoi le même système d'événements ne peut pas être utilisé pour ajouter la prise en charge du déploiement à chaud, sur une machine distante que j'exécute.
Sur la box distante :
sources
du site est consacrésources
(sans la surveillance du navigateur).Sur ma box locale :
https://mydomain.com/posts/hello/index.html
Faites quelque chose via SSH pour ramener l'actualisation du navigateur sur la boîte locale, en cas de déploiements à chaud sur un serveur distant.
Peut-être un scénario de configuration/démontage du temps de « développement/rédaction » ? Peut-être une fonction 'dev_server' que nous utilisons pour démarrer une nouvelle session d'écriture de merde ?
Si vous êtes arrivé jusqu'ici et que vous souhaitez toujours contribuer...
Pourquoi?
Pourquoi, au nom de tout ce qui est saint et bon, voudriez-vous le faire ? N’est-il pas évident qu’il s’agit là de l’œuvre d’un idiot ? N'avez-vous pas entendu dire que Bash n'est même pas un véritable langage de programmation ? Et n'est-il pas évident que vos relations publiques languiront éternellement et que vos commentaires tomberont dans un vide sans nom ?
Oui, envoyer des correctifs est une très mauvaise idée.
Mais s'il vous plaît, envoyez-moi vos espoirs et vos rêves concernant votre créateur de merde ! J'ai lu les e-mails à mon prénom et à mon nom de famille sur Gmail.
Ensemble, nous pouvons siffler des airs idiots et raser nos yacks respectifs, à notre manière.
Que la Source soit avec nous.
Ce travail bénéficie d'une double licence sous la licence MIT et la licence CC By-SA 4.0.
SPDX-License-Identifier : mit OR cc-by-sa-4.0