Intégrez les derniers teasers de publications dans votre site Web

Nous devions charger dynamiquement du contenu depuis notre forum Discourse à l’adresse labs.daemon.com.au vers le site public de notre entreprise à l’adresse www.daemon.com.au/labs.

Le code récupère le contenu le plus récent dans les catégories sélectionnées depuis Discourse, puis l’encapsule dans la structure HTML compatible avec notre site web avant de l’injecter dans la page. Nous apportons ensuite quelques modifications supplémentaires pour rendre le code plus générique, afin qu’il puisse être facilement réutilisé sur différents sites web pour charger du contenu depuis différents forums Discourse.

Un forum Discourse possède de nombreux points de terminaison (endpoints) de données. Par exemple, lorsque vous accédez à Derniers, il charge le point de terminaison latest.json qui renvoie les données nécessaires pour cette page spécifique. Cela nous permet d’afficher le contenu de Discourse sur notre propre site web.

Avant de commencer

Afin de charger du contenu depuis Discourse à distance, nous devons rendre les points de terminaison de Discourse accessibles à notre site web. Cela peut être fait dans les paramètres « Admin » de Discourse.

Connectez-vous à Discourse en utilisant un compte disposant des droits d’administration, puis accédez à l’onglet « Paramètres » dans le panneau « Admin » :

Recherchez « Sécurité » dans la navigation de gauche, puis localisez le champ « cors origins » sur le côté droit. Ajoutez l’URL du site web qui affichera le contenu de Discourse dans ce champ (dans notre cas : http://www.daemon.com.au/), puis enregistrez les modifications :

Points de terminaison (Endpoints)

Puisque Discourse génère d’innombrables points de terminaison de données, il est important de trouver le bon en fonction du contenu qui doit être affiché à distance. Ajouter /l/latest.json à la fin de l’URL d’une page de catégorie affichera le point de terminaison contenant les derniers messages pour cette catégorie spécifique. Par exemple, https://labs.daemon.com.au/c/design/l/latest.json est le point de terminaison pour https://labs.daemon.com.au/c/design.

HTML & JavaScript

Maintenant que nous avons le point de terminaison nécessaire, nous passons à l’étape suivante pour permettre à notre site de lire ce point de terminaison afin de récupérer des informations utiles et de les afficher correctement. Dans cet exemple, nous visons à afficher les 3 derniers messages publiés par l’Utilisateur #1, #2 ou #3 dans la catégorie « Design » dans le #div de notre site. De plus, nous ne souhaitons pas afficher le message « À propos de la catégorie Design ».

N.B. Dans notre exemple, nous utilisons Bootstrap v4.0.0-beta.2 par défaut pour fournir quelques styles nécessaires à des fins de démonstration uniquement, et son utilisation est tout à fait optionnelle.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta content="ie=edge" http-equiv="x-ua-compatible">
    <meta content="initial-scale=1.0, shrink-to-fit=no, width=device-width" name="viewport">
    <title>Intégration Discourse</title>

    <!-- Bootstrap CSS pour les styles de base dans la démo -->
    <link crossorigin="anonymous" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" rel="stylesheet">
  </head>
  <body>
    <div class="container">
      <div class="card-deck" id="div"></div>
    </div>

    <!-- jQuery -->
    <script crossorigin="anonymous" integrity="sha384-p7RDedFtQzvcp0/3247fDud39nqze/MUmahi6MOWjyr3WKWaMOyqhXuCT1sM9Q+l" src="https://code.jquery.com/jquery-3.2.1.js"></script>

    <!-- JavaScript -->
    <script>
      (function ($) {
        'use strict'

        $(function () {
          $.ajax('https://labs.daemon.com.au/c/design/l/latest.json').then(function (result) {
            // Analyser les données pour générer du contenu depuis Discourse :
            // * Point de terminaison Discourse, c'est-à-dire `result`,
            // * Nombre de messages à afficher sur votre site, par exemple `3`,
            // * Tableau facultatif d'identifiants d'utilisateurs (liste blanche)
            //   si seuls les messages publiés par des utilisateurs spécifiques doivent être affichés sur votre site, par exemple `[1, 2, 3]`.
            console.log(result);
            $('#div').discourse(result, 3, [1, 2, 3]);
          });

          $.fn.discourse = function (feed, numToShow, whitelist) {
            var feedLength = feed.topic_list.topics.length;

            // S'assurer qu'il y a assez de messages à afficher.
            if (numToShow > feedLength) {
              numToShow = feedLength;
            }

            for (var i = 0; i < numToShow; i++) {
              var content = '';

              // Les URL dans les points de terminaison Discourse sont toutes des URL relatives (par exemple topic.image_url),
              // nous avons besoin de cela afin que les liens affichés sur votre site pointent vers les bonnes adresses.
              // Veuillez modifier ceci avec l'URL de votre forum Discourse.
              var discourseURL = 'http://labs.daemon.com.au/';

              // Variables pour les données de message Discourse.
              var post          = feed.topic_list.topics[i],
                  postAuthor    = post.posters[0].user_id,
                  postDate      = new Date(post.created_at),
                  postLink      = discourseURL + 't/' + post.slug + '/' + post.id,
                  postThumbnail = discourseURL + post.image_url;

              // Si une liste blanche est présente, vérifier si l'auteur du message est un utilisateur vérifié.
              if (typeof whitelist !== 'undefined') {
                var verifiedUser = false;

                for (var n = 0; n < whitelist.length; n++) {
                  if (postAuthor === whitelist[n]) {
                    verifiedUser = true;
                    break;
                  }
                }

                // Si l'auteur du message n'est pas dans la liste blanche,
                // interrompt cette itération et passe à l'itération suivante dans la boucle.
                if (!verifiedUser) {
                  // Augmenter le nombre de messages à afficher si possible
                  // pour compenser le message éliminé.
                  if (numToShow < feedLength) {
                    numToShow++;
                  }

                  continue;
                }
              }

              // Le bloc de code suivant est facultatif.
              // L'objectif est d'ignorer le message « À propos de la catégorie X »
              // car il peut être indésirable de l'afficher sur votre site.
              if (post.title.substring(0, 10) === "About the " && post.title.substring(post.title.length - 9) === ' category') {
                // Augmenter le nombre de messages à afficher si possible
                // pour compenser le message éliminé.
                if (numToShow < feedLength) {
                  numToShow++;
                }

                continue;
              }

              // Si un message n'a pas de vignette,
              // alors utiliser une image de remplacement par défaut comme vignette pour votre site.
              // Veuillez modifier ceci pour utiliser l'image de remplacement de votre site.
              if (post.image_url === null) {
                postThumbnail = 'http://placehold.it/320x180';
              }

              // Générer le HTML pour votre site.
              // Cette partie du code peut devoir être modifiée en conséquence
              // pour s'adapter à la structure HTML de votre site.
              content += '<div class="card" style="max-width: 20rem;">';
                content += '<img alt="' + post.fancy_title + '" class="card-img-top" src="' + postThumbnail + '">';
                content += '<div class="card-body">';
                  content += '<h4 class="card-title">' + post.fancy_title + '</h4>';
                  content += '<p class="card-text"><small>' + postDate.getDate() + '/' + postDate.getMonth() + '/' + postDate.getFullYear() + '</small></p>';
                  // La ligne suivante fait un peu plus que d'afficher l'extrait tel quel,
                  // elle remplace les balises `<a>` dans l'extrait par des balises `<em>`
                  // afin qu'elles n'apparaissent pas sous forme de liens sur votre site.
                  // Ceci est facultatif, mais peut être nécessaire dans certaines circonstances.
                  content += '<p class="card-text">' + post.excerpt.replace(/<a/g, '<em').replace(/<\/a/g, '</em') + '</p>';
                  content += '<a href="' + postLink + '">Lire la suite</a>';
                content += '</div>';
              content += '</div>';

              $(this).append(content);
            }
          };
        });
      }(jQuery));
    </script>
  </body>
</html>

Résultat final

Le JavaScript est suffisamment générique pour être réutilisé sur différents sites web. Cependant, vous voudrez peut-être passer étape par étape pour l’adapter à vos besoins. En particulier la partie de la structure HTML, car il est très probable qu’elle doive être personnalisée pour convenir à la structure de votre site.

Profitez-en !

h/t @sesemaya Embed latest topics from Discourse on your website - development - Daemon Labs

18 « J'aime »

I have to say thanks for this how-to; it was very helpful in getting started on our own implementation and I wanted to share our version back with the community for future reference. I slightly refactored your code to better fit our needs and we’re using Mustache templates to handle the markup more flexibly.

Our actual implementation is rather different, but I’ve published a pen of your original demo built with our model:

N.B.
The included API key is for a temporary TL0 user to enable access as our instance has login required while it’s under development

4 « J'aime »