Quelle est la "difficulté" de modifier/étendre Discourse pour un développeur backend ?

Quelques réflexions à ce sujet.

Développement de cours payants sur Discourse

L’idée de cours liés au développement de Discourse sur une plateforme comme Udemy ou Coursera est intéressante. Je soupçonne que les principaux problèmes sont qu’il n’y a pas beaucoup de personnes en dehors de l’équipe Discourse qui seraient qualifiées pour créer un cours sur le développement de Discourse et que le nombre potentiel d’étudiants pour un cours est assez faible. Cela dit, je suis sûr qu’un bon cours lié au développement de thèmes ou de plugins Discourse pourrait attirer suffisamment d’étudiants au fil du temps pour justifier l’effort de création d’un cours.

Il y a aussi un problème potentiel : facturer des cours sur Discourse pourrait aller à l’encontre de l’esprit de ce forum. Je ne fais que spéculer à ce sujet cependant.

Tutoriels de développement Discourse

Je pense que l’observation selon laquelle l’implémentation réelle de nombreux plugins, thèmes et composants de thème Discourse est assez simple est correcte. Comme pour le développement pour d’autres plateformes, le problème est de dépasser la barrière initiale de ne pas comprendre comment les pièces s’assemblent. L’équipe Discourse (ou d’autres développeurs qualifiés) pourrait aider à cela en rédigeant quelques tutoriels qui vous guident tout au long du processus de création de thèmes, de composants de thème et de plugins fonctionnels. Par exemple, un guide étape par étape pour créer quelque chose comme le composant de thème Discourse Placeholder.

Je réalise que cela nécessiterait un investissement de temps important, il faudrait donc qu’il corresponde aux objectifs commerciaux de Discourse.

Ressources actuellement disponibles

Avec un peu de recherche, il existe de nombreuses bonnes informations sur le développement de Discourse sur ce forum. Examiner des exemples de code du dépôt GitHub de Discourse est également un excellent moyen d’apprendre.

Un outil récent à ne pas négliger est GitHub Copilot. Si vous structurez votre environnement de développement de la bonne manière, il peut être utile pour avoir une idée de la façon de développer des thèmes et des plugins Discourse. Pour le développement de thèmes Discourse, la meilleure approche que j’ai trouvée est de développer le thème (en utilisant le Discourse Theme CLI) dans le répertoire racine de mon installation locale de Discourse. Structurer les choses de cette façon donne à Copilot un accès facile à la base de code de Discourse. (Notez que pour le développement de plugins, le dossier plugins se trouve déjà dans le répertoire racine /discourse.) (Notez également que je pourrais avoir tort quant à l’accès réel de Copilot à la base de code de Discourse que j’ai chargée dans mon IDE. Dans tous les cas, il est utile d’avoir le code de base de Discourse disponible pour ma propre référence.)

Pour éviter les distractions et aussi pour me concentrer sur l’utilisation de Copilot comme outil d’apprentissage, je désactive les complétions Copilot dans mon IDE (VS Code) et j’interagis avec Copilot via le chat. Voici un exemple du type d’assistance qu’il peut fournir. (shopify.js est le fichier créé par le Theme CLI dans le répertoire /javascripts/discourse/api-initializers/ de mon thème.)

Conversation avec Copilot

_scossar : Pouvez-vous expliquer ce que fait l’exportation par défaut dans shopify.js ? C’est essentiellement le code de base fourni par Discourse lorsqu’un thème est créé avec la gem discourse_theme. J’ai modifié le code de base de manière à ce qu’il enregistre chaque changement de page. Je comprends l’appel à api.onPageChange, mais je ne comprends pas clairement comment l’objet api est injecté dans mon code.

GitHub Copilot : L’objet api est injecté dans votre code via la fonction withPluginApi qui est appelée dans la méthode initialize de l’objet retourné par apiInitializer.

Voici une version simplifiée de ce qui se passe :

  1. Lorsque Discourse démarre, il exécute tous les initialisateurs.
  1. La fonction apiInitializer crée un initialisateur qui s’exécute après l’initialisateur "inject-objects".
  1. Lorsque cet initialisateur s’exécute, il appelle la fonction withPluginApi en passant les paramètres version, cb et opts.
  1. La fonction withPluginApi vérifie si la version actuelle de Discourse est compatible avec la version spécifiée. Si c’est le cas, elle appelle la fonction de rappel (cb) et passe l’instance PluginApi comme argument. Cette instance PluginApi est l’objet api que vous voyez dans votre code.

Ainsi, l’objet api est une instance de PluginApi, et il vous est passé par la fonction withPluginApi. Cet objet fournit un certain nombre de méthodes qui vous permettent d’interagir avec Discourse, telles que onPageChange, que vous utilisez déjà.

_scossar : Donc, la fonction qui est le deuxième argument de l’exportation par défaut dans shopify.js est la fonction de rappel acceptée par apiInitializer ?

GitHub Copilot : Oui, c’est exact. Le deuxième argument de apiInitializer est une fonction de rappel. Cette fonction est appelée avec l’instance PluginApi comme argument lorsque l’initialisateur s’exécute (en supposant que la version actuelle de Discourse soit compatible avec la version spécifiée). C’est ainsi que l’objet api est rendu disponible dans votre fichier shopify.js.

Une fois que j’ai compris cela…

_scossar : …Une autre idée, api.decorateCooked pourrait-il être utilisé pour injecter un iframe de notation hébergé sur une application externe (par exemple, hébergé par l’application Shopify que je développe) ?

GitHub Copilot : Oui, vous pouvez utiliser api.decorateCooked pour injecter un iframe dans un post. Voici un exemple approximatif de la façon dont vous pourriez le faire :

api.decorateCooked($elem => {
  const postId = $elem.data('post-id');
  const iframe = document.createElement('iframe');
  iframe.src = `https://your-app.com/ratings?post_id=${postId}`;
  iframe.width = '100%';
  iframe.height = '200'; // ajustez au besoin
  $elem.append(iframe);
}, { id: 'rating-iframe' });

Dans cet exemple, api.decorateCooked est utilisé pour ajouter un iframe à chaque post. La source de l’iframe est définie sur une URL de votre application externe, avec l’ID du post inclus comme paramètre de requête. Vous remplaceriez 'https://your-app.com/ratings' par l’URL réelle de votre page de notation.

Veuillez noter qu’il s’agit d’un exemple simplifié. Vous devrez peut-être l’adapter à vos besoins, et vous devriez absolument ajouter une gestion des erreurs et d’autres précautions nécessaires pour garantir son bon fonctionnement et sa sécurité.

Il n’est pas raisonnable à ce stade d’attendre de Copilot qu’il écrive tout votre code, mais c’est un excellent outil pour apprendre à écrire du code Discourse.