Faire un site low-cost avec Hedgedoc

J'ai une activité de webmaster, où je propose de la conception et de la maintenance de sites web vitrine. J'utilise pour cela un savant mélange de Directus et de Zola.

Directus me permet de proposer à mes client·es une interface jolie, simple et strictement adaptée aux besoins du site. C'est ça qui contient toutes les données du site. Directus génère une interface d'édition complètement adaptable, crée sa propre base de données SQL en fonction du modèle de données créé par moi, génère une API, gère le téléversement de fichiers, dispose de permissions fines, etc.

Zola me permet de générer un site statique à partir de templates HTML et des données rentrées dans Directus. Pourquoi découper le système en une interface d'édition et un site statique, au lieu d'un CMS standard ? Plusieurs raisons :

Mais ce n'est pas de ça dont je viens parler ici, ce sera pour un autre article, quand j'aurais bien peaufiné cette suite d'outils.

Aujourd'hui, on va faire du low-cost, pas chiadé du tout, faisable en quelques heures !

Cette idée a germé dans mon esprit il y a environ un an, avant que je ne découvre Directus. Je l'ai reprise cette semaine, alors qu'une asso qui n'avait pas les moyens d'une prestation complète me contactait pour refaire leur site fait en 2010, en plus simple. Et sans avoir besoin de connaître le HTML pour éditer le site.

On va donc s'appuyer sur Hedgedoc (anciennement CodiMD), un éditeur collaboratif de fichiers en Markdown. J'utilise l'instance ouverte aux inscriptions de Picasoft, md.picasoft.net, et crée un site pour l'asso, qu'on appellera LASSO dans la suite de l'article.

Voici la vue d'ensemble :

En pratique :

<!doctype html>
<html>

<head>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="icon" href="./favicon.ico">
	<title>LASSO</title>
	<style>
		html {
			font-family: Gill Sans, Aller, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
			line-height: 1.5;
		}

		html,
		body {
			margin: 0;
		}

		main {
			max-width: 900px;
			min-height: 100vh;
		}

		img {
			display: block;
			max-width: 100%;
			height: auto;
		}

		a {
			color: inherit;
			text-decoration: underline;
		}

		nav a {
			text-decoration: inherit;
			font-weight: 600;
			color: #027d00;
		}

		.w-full {
			width: 100%;
		}

		.flex {
			display: flex;
			flex-direction: row;
		}

		.flex.center {
			justify-content: center;
		}

		article h1 {
			font-weight: 800;
			font-size: 2.25em;
			margin-top: 0;
			margin-bottom: 0.8888889em;
			line-height: 1.1111111;
		}

		article h2 {
			font-weight: 700;
			font-size: 1.5em;
			margin-top: 2em;
			margin-bottom: 1em;
			line-height: 1.3333333;
		}

		article h3 {
			font-weight: 600;
			font-size: 1.25em;
			margin-top: 1.6em;
			margin-bottom: 0.6em;
			line-height: 1.6;
		}

		article h4 {
			font-weight: 600;
			margin-top: 1.5em;
			margin-bottom: 0.5em;
			line-height: 1.5;
		}

		article img {
			margin-top: 2em;
			margin-bottom: 2em;
		}
	</style>
</head>

<body class="w-full flex center" style="background-color: #lacouleurquetuveux">
    <!-- Limiter la largeur du contenu -->
	<main class="w-full" style="max-width: 900px; background-color: #fff">

		<header class="flex">
            <!-- Logo, etc-->
		</header>

        <nav style="font-size: 1.2em">
            <a href="./index.html">Accueil</a>
            <a href="./news.html">Newsletter</a>
            <!-- Autres pages -->
        </nav>

		<article id="content" style="margin: 2em"></article>

        <!-- La librairie qui va convertir le markdown en html -->
        <!-- Téléchargée depuis https://cdn.jsdelivr.net/npm/marked/marked.min.js -->
		<script src="./marked.min.js"></script>
        <!-- La librairie qui va supprimer les éventuels cochonneries de hackers. Le contenu
        markdown devrait être de confiance, mais si jamais l'asso se trompe dans les permissions de
        ses pages, mieux vaut jouer la prudence. -->
        <!-- Téléchargée depuis https://github.com/cure53/DOMPurify/raw/main/dist/purify.min.js -->
		<script src="./purify.min.js"></script>
		<script>
			async function put_content() {
                // On extrait le nom du fichier HTML actuel
				const url = window.location.pathname;
				const filename = url.substring(url.lastIndexOf('/') + 1);
                // On va télécharger le contenu de la page Hedgedoc correspondante
				const response = await fetch(`https://md.picasoft.net/LASSO-${filename}/download`);
				const markdown = await response.text();
                // On convertit le Markdown en HTML,
                // On le purifie,
                // Et on l'insère dans le HTML, dans l'<article> 20 lignes plus haut ↑
				document.getElementById('content').innerHTML = DOMPurify.sanitize(marked.parse(markdown));
			}
			put_content();
		</script>

	</main>
</body>

</html>

Maintenant qu'on a ça, on a plus qu'à l'installer sur l'hébergement web de l'asso. Dans mon cas, c'est un hébergement gratuit avec Free, mais ce fichier HTML peut carrément aller n'importe où !

Personnellement, j'ai tous ces fichiers sur mon PC :

# Mes images
favicon.ico  header.png  logo.png
# Les librairies Javascript
marked.min.js  purify.min.js
# Les fichiers HTML
index.html  news.html ...
  1. Tous les fichiers HTML ne sont en vrai qu'un seul et même fichier : ce sont des liens durs (hard links) d'un seul fichier, créés avec la commande ln sous Linux.
  2. Sinon, ça fonctionne très bien aussi d'éditer toujours le même fichier puis de le copier en écrasant les autres, mais c'est plus sujet à erreur.
  3. Encore une autre solution, c'est d'envoyer le même fichier côté serveur web pour toutes les routes qui finissent par .html. Mais ça demande un accès au serveur web, ce qui n'est pas mon cas sur de l'hébergement mutualisé Free.

Je mets à jour le HTML du site avec un :

$ rsync -a ./ host:/path/to/directory

Partant ce principe, c'est assez facile de faire sa sauce et de faire plein de petites améliorations je pense !

Notamment :

Mais j'ai la flemme 🙃

Voilà, hésitez pas à vous abonner, à cliquer sur la cloche, tout ça...

Mon flux RSS en bas à droite