Récememnt j’ai utilisé bit.ly pour raccourcir un URL, pour m’apercevoir seulement après qu’on ne peut pas supprimer l’URL crée ! Inadmissible ! Inacceptable ! Scandale ! Bon ok je m’arrete là, mais c’est à peu près ce que j’ai ressenti. Je me suis donc dit que ce serait cool d’avoir son propre raccourcisseur d’URL. Il y a plein de solutions auto-hébergées (self-hosted comme on dit) mais je ne voulais pas installer un énième service. Mon blog utilisant le framework Quartz, je me suis dit que je “hackerai” le système pour y ajouter une fonctionnalité de raccourcisseur d’URL.

Voici donc comment créer un raccourcisseur d’URL simple, pour les huit utilsateurs français de Quartz. Cela va vous permettre de spécifier une propriété redirectUrl dans le frontmatter de votre fichier markdown, transformant ainsi la page en une redirection vers n’importe quel autre URL.

Création d’un Plugin d’Émetteur de Redirection

Premièrement, vous devez créer le plugin principal responsable de la génération des pages de redirection. Créez un nouveau fichier à l’emplacement quartz/plugins/emitters/RedirectEmitter.ts avec le contenu suivant :

import { QuartzEmitterPlugin, BuildCtx, ProcessedContent, StaticResources } from "../types";
import { FilePath } from "../../util/path";
import { promises as fs } from "fs";
import path from "path";
 
interface Options {
  enableRedirects?: boolean
}
 
const defaultOptions: Options = {
  enableRedirects: true
}
 
export const RedirectEmitter: QuartzEmitterPlugin<Options> = (opts?: Options) => ({
  name: "RedirectEmitter",
 
  getQuartzComponents(ctx: BuildCtx) {
    return [];
  },
 
  async emit(ctx: BuildCtx, content: ProcessedContent[], resources: StaticResources): Promise<FilePath[]> {
    const filePaths: FilePath[] = [];
 
    for (const [tree, file] of content) {
      const redirectUrl = file.data?.frontmatter?.redirectUrl;
 
      if (redirectUrl) {
        const targetUrl = redirectUrl.startsWith('http') ? redirectUrl : `/${redirectUrl.replace(/^\//, '')}`;
 
        const redirectHtml = `
<!DOCTYPE html>
<html lang="en-US">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="refresh" content="0;url=${targetUrl}">
    <script>
      window.location.replace("${targetUrl}");
    </script>
    <title>Redirection...</title>
</head>
<body>
    <p>Redirection vers <a href="${targetUrl}">${targetUrl}</a>...</p>
</body>
</html>`;
 
        const outputPath = path.join(ctx.argv.output, file.data.slug! + ".html");
        await fs.mkdir(path.dirname(outputPath), { recursive: true });
        await fs.writeFile(outputPath, redirectHtml);
        const fp = file.data.slug! + ".html";
 
        filePaths.push(fp);
      }
    }
 
    return filePaths;
  },
});

Ce code définit un plugin RedirectEmitter. Décortiquons ce qui se passe :

  • Imports: Il importe les types nécessaires de Quartz et les modules pour les opérations sur le système de fichiers et la manipulation des chemins.
  • Interface Options: Il définit une interface Options pour configurer optionnellement le plugin. Actuellement, elle inclut seulement enableRedirects, défini à true par défaut.
  • Définition du Plugin: RedirectEmitter est défini comme un QuartzEmitterPlugin. Les plugins émetteurs dans Quartz sont responsables de prendre le contenu traité et de produire des fichiers de sortie.
  • Fonction emit: C’est le cœur du plugin. Elle itère sur chaque fichier de votre contenu.
    • Elle vérifie la présence de la propriété redirectUrl dans le frontmatter de chaque fichier.
    • Si redirectUrl existe, elle construit l’targetUrl, en s’assurant qu’elle est correctement formatée (ajoutant un / au début si nécessaire pour les redirections internes, ou la gardant telle quelle pour les URLs externes).
    • Elle génère un HTML minimal pour la redirection. Cet HTML utilise à la fois <meta http-equiv="refresh"> et window.location.replace() de JavaScript pour assurer une redirection immédiate. Cette double approche améliore la fiabilité sur différents navigateurs.
    • Il écrit cet HTML dans un fichier dans votre répertoire de sortie, en utilisant le slug du fichier original pour créer le nom du fichier HTML (par exemple, mon-article.html).
    • Le plugin ajoute ensuite le chemin du fichier généré au tableau filePaths, qui est retourné à Quartz.

Enregistrement du Plugin

Pour activer le RedirectEmitter, vous devez l’enregistrer dans votre fichier quartz.config.ts. Ouvrez quartz.config.ts et modifiez le tableau plugins dans le bloc configuration pour inclure Plugin.RedirectEmitter({ enableRedirects: true }) :

 Plugin.Assets(),
 Plugin.Static(),
 Plugin.NotFoundPage(),
 Plugin.RedirectEmitter({ enableRedirects: true }),

En ajoutant Plugin.RedirectEmitter({ enableRedirects: true }), vous indiquez à Quartz d’utiliser votre nouveau plugin pendant le processus de construction. L’option enableRedirects: true est actuellement la seule configuration, et elle est définie à true par défaut dans le plugin, mais c’est une bonne pratique de l’inclure explicitement.

Exclusion des Pages de Redirection des Notes Récentes

Jusqu’ici, c’est cool, mais en l’état, les pages de redirection créees apparaitra dans les articles récents, ce qui est un peu balot. Pour les exclure, modifiez le composant RecentNotes.tsx pour filtrer les pages ayant la propriété redirectUrl dans le frontmatter. Ouvrez quartz/components/RecentNotes.tsx et mettez à jour la logique de filtrage des pages :

const pages = allFiles
  .filter(opts.filter)
  .filter(page => !page.frontmatter?.redirectUrl) // Filter out pages with redirectUrl
  .sort(opts.sort)

Ce changement ajoute .filter(page => !page.frontmatter?.redirectUrl) à la chaîne de filtrage des pages. Cela garantit que toute page ayant un redirectUrl dans son frontmatter sera exclue de la liste des notes récentes.

Exportation du Plugin

Enfin, assurez-vous que votre nouveau plugin est exporté pour que Quartz puisse le trouver. Ouvrez quartz/plugins/index.ts et ajoutez la ligne suivante aux exports :

export { RedirectEmitter } from "./emitters/RedirectEmitter"

Utilisation de la Fonctionnalité de Redirection

Maintenant, pour créer des redirections, créez une page comme vous le feriez pour ajouter un article, mais ajoutez simplement la propriété redirectUrl au frontmatter de votre fichier markdown. Par exemple :

---
title: Ma Page de Redirection
redirectUrl: https://example.com
---
 
Ce contenu sera ignoré. Vous serez redirigé.

Lorsque Quartz construira votre site, il générera un fichier HTML pour cette page markdown qui redirigera immédiatement vers https://example.com. Le contenu markdown original sera effectivement ignoré, et la page fonctionnera comme un raccourcisseur d’URL.