Migration d'un site Hugo de Forestry à Tina

illustrations illustrations illustrations illustrations illustrations illustrations illustrations
post-thumb

Publié le 5 janvier 2023 par Andrew Owen (8 minutes)

J’ai lancé la version actuelle de mon site web il y a un an. Devenu défenseur des développeurs en 2021, je ne pensais plus qu’un site WordPress qui n’avait pas été mis à jour depuis une décennie serait suffisant. Je voulais quelque chose d’un peu plus moderne. Dans mon ancienne entreprise, j’avais construit un portail pour les développeurs sur Hugo. L’entreprise a fini par héberger elle-même le site, mais j’avais discuté avec Netlify et Forestry à l’époque. Et j’utilisais GitHub pour mes grands projets open source depuis longtemps. J’ai choisi un thème de démarrage Hugo gratuit de Themefisher qui prenait en charge Netlify et Forestry. J’ai passé un week-end sur le site: mise en place de la structure du site, personnalisation du thème et ajout de contenu. Je n’avais pas toutes les fonctionnalités au début (la recherche, les tags et le RSS sont arrivés plus tard), mais c’était un grand pas en avant par rapport à mon ancien site.

Selon Jamstack, Next.js de Vercel avec ses templates React a dépassé Hugo en popularité. Et cela ne me surprend pas. Selon la plupart des critères, JavaScript n’a jamais quitté le top 10 des langages de programmation au cours des deux dernières décennies. Sur les 347 générateurs de sites statiques répertoriés, 130 sont écrits en JavaScript, 51 en Python et 26 en PHP. Hugo, et 16 autres, sont écrits en Go. Mais Hugo prétend être le plus rapide (vous pouvez vérifier ces affirmations avec PageSpeed) et je m’en tiens donc à lui. Cependant, depuis 2019, l’équipe derrière Forestry développe la prochaine itération appelée TinaCMS. Et le 8 novembre 2022, il est sorti de la version bêta. L’arrêt de Forestry est prévu pour fin mars 2023. Les utilisateurs actuels se verront proposer un chemin de migration vers TinaCMS, un CMS headless de nouvelle génération des créateurs de Forestry. Il est prévu de partager l’outil de migration à la mi-janvier, mais j’ai décidé d’aller de l’avant et d’effectuer une migration manuelle.

J’ai décidé de profiter de l’occasion pour faire un peu de nettoyage et ajouter un shortcode Hugo pour l’audio (merci à John Arrroyo pour les informations sur comment faire cela). J’ai aussi finalement ajouté une page 404 personnalisée. J’ai créé un nouveau dépôt GitHub vide et je l’ai connecté à un nouveau site d’essai sur Netlify. J’ai vérifié une copie locale et j’ai apporté le contenu de l’ancienne version du site. Vous pouvez exécuter TinaCMS localement, donc après l’installation, j’ai pu faire des changements avant de pousser vers le site de mise en scène. J’ai supprimé la configuration de Forestry (bien qu’il n’y aurait pas eu de mal à la laisser en place). Mais je vais supposer que vous voulez simplement ajouter le support de TinaCMS à votre repo existant.

Créer le projet

  1. Enregistrez-vous pour un compte Tina et connectez-vous.
  2. Dans le tableau de bord, naviguez vers Projets et cliquez sur Nouveau projet.
  3. Cliquez sur Import Your Site, puis sur Authenticate with GitHub. Si vous n’êtes pas encore connecté à GitHub, faites-le maintenant.
  4. Sélectionnez le dépôt de votre site Hugo et entrez les URLs du site (l’URL de votre site live et localhost avec le port que vous voulez utiliser lorsque vous faites de l’édition locale).
  5. Cliquez sur Create Project.

Configurer le schéma de votre site

Vous aurez besoin de npm. S’il n’est pas déjà installé:

  • Sur macOS avec Homebrew: brew install npm.
  • Sur Ubuntu: sudo apt install npm.
  • Sous Windows avec Scoop: scoop install npm.

Vous avez également besoin de hugo. Vous pouvez l’installer de la même manière que npm.

  1. Téléchargez une copie locale de votre repo depuis GitHub.
  2. A la racine du dossier du repo: npx @tinacms/cli@latest init.
  3. Quand on vous demande de choisir votre gestionnaire de paquets, sélectionnez yarn.
  4. Choisissez si vous voulez utiliser Typescript.
  5. Lorsque l’on vous demande le nom du dossier de stockage des ressources publiques, entrez static.
  6. Démarrez TinaCMS: npx tinacms dev -c "hugo server -D -p 3003".
  7. Naviguez jusqu’à la page d’administration: http://localhost:3003/admin.

Comme j’ai utilisé VScode, j’ai créé un fichier tasks.json dans le dossier .vscode pour automatiser le déploiement de TinaCMS localement:

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "start TinaCMS",
      "type": "shell",
      "command": "npx tinacms dev -c \"hugo server -D\"",
      "group": {
        "kind": "build",
        "isDefault": true
      },
    },
  ]
}

Par défaut, TinaCMS s’attend à trouver des images dans un dossier media. Editez votre fichier de configuration de TinaCMS pour qu’il pointe vers /static/images/ ou vers l’endroit où vous gardez vos images. Par exemple:

    media: {
      tina: {
        mediaRoot: "images",
        publicFolder: "static",
      },

Modélisez votre contenu

Avant de pouvoir éditer votre contenu, vous devez le modéliser, en vous basant sur les métadonnées que vous utilisez dans les en-têtes de vos fichiers markdown. Dans mon cas, j’utilise date, description, draft status, image, une liste de tags et un title. En plus des métadonnées, vous devez également définir le texte du body. Mon schéma ressemble à ceci:

schema: {
      collections: [
        {
          name: "blog",
          format: "md",
          label: "Blog",
          path: "content/blog/",
          defaultItem: () => {
            return {
              draft: true,
            }
          },
          fields: [
            {
              name: "draft",
              type: "boolean",
              label: "Draft",
              required: true,
            },

J’ai une collection unique appelée Blog qui correspond au dossier où vont mes articles (content/blog). Le champ draft est un booléen qui détermine si l’article est affiché. Vous pouvez définir une valeur par défaut pour les nouveaux articles dans la liste defaultItem afin que les nouveaux articles soient tous créés en tant que brouillons.

            {
              name: "title",
              type: "string",
              label: "Title",
              isTitle: true,
              required: true,
            },
            {
              name: "date",
              type: "datetime",
              label: "Date",
            },
            {
              name: "description",
              type: "string",
              label: "Description",
            },
            {
              name: "image",
              type: "image",
              label: "Image",
            },

Les champs title, date, description, et image sont tous assez explicites. Vous pouvez mettre la valeur required à true pour empêcher la sauvegarde d’un article auquel il manque un champ obligatoire.

            {
              name: 'tags',
              type: 'string',
              label: 'Tags',
              list: true,
            },
            {
              name: 'body',
              type: 'rich-text',
              isBody: true,
              label: "Body",
              templates: [
                {
                  name: 'shortcode',
                  label: 'shortcode',
                  match: {
                    start: '{{',
                    end: '}}',
                  },
                  fields: [
                    {
                      // Be sure to call this field `text`
                      name: 'text',
                      label: 'Text',
                      type: 'string',
                      required: true,
                      isTitle: true,
                      ui: {
                        component: 'textarea',
                      },},],},],},],},],},

Les tags sont un ensemble de chaînes de texte. Pour des éléments comme celui-ci, mettez la valeur de list à true. Définir le type à rich-text active l’éditeur GUI pour le corps du texte. Pour pouvoir inclure les shortcodes Hugo, vous devez inclure le modèle ci-dessus pour eux. En pratique, j’ai trouvé nécessaire d’inclure les crochets d’ouverture et de fermeture dans les éléments start et end afin qu’aucun espace ne soit inséré entre les curly brackets et le crochet d’angle (parce qu’un espace tue le shortcode audio).

Corrigez votre Markdown

Cette partie est un casse-tête, mais tant qu’il n’y aura pas d’outil de migration de Forestry vers Tina, il n’y aura pas de solution. Le gros problème que j’ai rencontré est que tout mon contenu Markdown était en TOML et, au moment où j’écris ces lignes, TinaCMS ne prend en charge que YAML. J’ai utilisé la recherche et le remplacement dans VScode. Mais il existe une meilleure méthode.

Activer Tina Cloud dans TinaCMS

  1. Connectez-vous à Tina Cloud.
  2. Naviguez vers Overview et obtenez une copie de votre clientID.
  3. Naviguez vers Tokens et cliquez sur New Token.
  4. Donnez un nom au token. Par exemple: Production Content Token.
  5. Entrez les branches Git auxquelles le token a accès. Par exemple: main. Puis cliquez sur Create Token.
  6. Naviguez vers Tokens et obtenez une copie du token que vous venez de créer.
  7. Ajoutez votre clientID et votre token à votre configuration:
  export default defineConfig({
    branch,
    clientId: "",   // Get this from tina.io
    token: "",      // Get this from tina.io

Dans votre fichier netlify.toml, ajoutez TinaCMS à votre commande de construction:

[build]
publish = "public"
command = "yarn tinacms build && hugo"

Vous pouvez le définir directement dans vos paramètres de construction sur Netlify, mais ce qui est dans le fichier aura la priorité sur ce qui est sur Netlify.

Vous pouvez maintenant pousser vos modifications sur GitHub. Une fois que Netlify aura déployé votre build, vous pourrez travailler sur votre site dans Tina Cloud.

Synchronisez vos médias

Avant de commencer à éditer. Allez dans Media Manager, cliquez sur Sync puis sur Sync Media. Cela permet de copier les médias du dossier images dans votre branche désignée (typiquement main) dans votre dépôt git vers le service d’actifs de Tina Cloud. Vous pouvez maintenant utiliser ces ressources dans votre site avec Tina Cloud.

Réflexion après coup

J’ai écrit ceci avant que TinaCMS ne publie son outil de migration Forestry et son guide. Je suis redevable au PDG et cofondateur de Forestry, Scott Gallant, d’avoir partagé une ébauche de ce guide avec moi lorsque j’étais bloqué (et à JP O’Halloran pour l’avoir écrit). Il a également été d’une aide précieuse sur le TinaCMS Discord. Fait amusant: Tina porte le nom du lama dans “Napoleon Dynamite”.

Par ailleurs, vous voudrez peut-être désaffecter votre site de Forestry. Vous pouvez le faire dans Forestry en naviguant vers My Sites. Cliquez sur le menu déroulant de la branche et sélectionnez Remove Site. Cliquez ensuite sur Remove Site pour confirmer.