Necesitábamos cargar contenido dinámicamente desde nuestro foro Discourse en labs.daemon.com.au en el sitio web público de nuestra empresa en www.daemon.com.au/labs.
El código recupera el contenido más reciente de categorías seleccionadas en Discourse y lo envuelve con la estructura de marcado que funciona con nuestro sitio web antes de inyectarlo en la página. Luego, realizamos algunos cambios adicionales para hacer el código más genérico, de modo que pueda reutilizarse fácilmente en diferentes sitios web para cargar contenido de distintos foros de Discourse.
Un foro de Discourse posee numerosos puntos de acceso (endpoints) de datos. Por ejemplo, cuando vas a Recientes, se carga el punto de acceso latest.json, que devuelve los datos necesarios para esa página en particular. Esto nos permite mostrar contenido de Discourse en nuestro propio sitio web.
Antes de comenzar
Para cargar contenido de Discourse de forma remota, debemos hacer que los puntos de acceso de Discourse estén disponibles para nuestro sitio web. Esto se puede hacer en la configuración de “Administración” de Discourse.
Inicia sesión en Discourse con una cuenta que tenga acceso de administrador y luego ve a la pestaña “Configuración” en el panel de “Administración”:
Busca “Seguridad” en la navegación izquierda y localiza el campo “cors origins” en el lado derecho. Agrega la URL del sitio web que mostrará contenido de Discourse en el campo (en nuestro caso: http://www.daemon.com.au/) y guarda los cambios:
Puntos de acceso
Dado que Discourse genera innumerables puntos de acceso de datos, es importante encontrar el correcto dependiendo del contenido que se requiera mostrar de forma remota. Agregar /l/latest.json al final de la URL de una página de categoría mostrará el punto de acceso que contiene las publicaciones más recientes de esa categoría en particular. Por ejemplo, https://labs.daemon.com.au/c/design/l/latest.json es el punto de acceso para https://labs.daemon.com.au/c/design.
HTML y JavaScript
Ahora que tenemos el punto de acceso necesario, procedemos a habilitar que nuestro sitio lo lea para recuperar información útil y mostrarla correctamente. En este ejemplo, nuestro objetivo es mostrar las 3 publicaciones más recientes publicadas por el Usuario #1, #2 o #3 de la categoría “Diseño” en el #div de nuestro sitio. Además, no queremos mostrar la publicación “Acerca de la categoría de diseño”.
Nota: En nuestro ejemplo, utilizamos Bootstrap v4.0.0-beta.2 predeterminado para proporcionar algunos estilos necesarios solo con fines de demostración, y su uso es totalmente opcional.
<!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>Discourse embed</title>
<!-- Bootstrap CSS para estilos básicos en la demostración -->
<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) {
// Analizar datos para generar contenido desde Discourse:
// * Punto de acceso de Discourse, es decir, `result`,
// * Número de publicaciones a mostrar en tu sitio, por ejemplo `3`,
// * Opcional: array de IDs de usuarios (lista blanca)
// si solo se pretende mostrar publicaciones de usuarios particulares en tu sitio, por ejemplo `[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;
// Asegurarse de que haya suficientes publicaciones para mostrar.
if (numToShow > feedLength) {
numToShow = feedLength;
}
for (var i = 0; i < numToShow; i++) {
var content = '';
// Las URL en los puntos de acceso de Discourse son todas URL relativas (por ejemplo, topic.image_url),
// necesitamos esto para que los enlaces mostrados en tu sitio apunten a los lugares correctos.
// Por favor, modifica esto con la URL de tu foro de Discourse.
var discourseURL = 'http://labs.daemon.com.au/';
// Variables para los datos de la publicación en 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 hay una lista blanca presente, verifica si el autor de la publicación es un usuario verificado.
if (typeof whitelist !== 'undefined') {
var verifiedUser = false;
for (var n = 0; n < whitelist.length; n++) {
if (postAuthor === whitelist[n]) {
verifiedUser = true;
break;
}
}
// Si el autor de la publicación no está en la lista blanca,
// se interrumpe esta iteración y se continúa con la siguiente iteración en el bucle.
if (!verifiedUser) {
// Aumentar el número de publicaciones a mostrar si es posible
// para compensar la publicación eliminada.
if (numToShow < feedLength) {
numToShow++;
}
continue;
}
}
// El siguiente bloque de código es opcional.
// El propósito es ignorar la publicación "Acerca de la categoría X"
// ya que puede no ser deseable mostrarla en tu sitio.
if (post.title.substring(0, 10) === "About the " && post.title.substring(post.title.length - 9) === ' category') {
// Aumentar el número de publicaciones a mostrar si es posible
// para compensar la publicación eliminada.
if (numToShow < feedLength) {
numToShow++;
}
continue;
}
// Si una publicación no tiene una miniatura,
// entonces usa una imagen de marcador de posición predeterminada como su miniatura para tu sitio.
// Por favor, modifica esto para usar la imagen de marcador de posición de tu sitio.
if (post.image_url === null) {
postThumbnail = 'http://placehold.it/320x180';
}
// Generar HTML para tu sitio.
// Esta parte del código puede necesitar modificarse en consecuencia
// para adaptarse a la estructura de marcado de tu sitio.
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 siguiente línea hace un poco más que mostrar el extracto tal cual,
// reemplaza las etiquetas `<a>` en el extracto con etiquetas `<em>`
// para que no aparezcan como enlaces en tu sitio.
// Esto es opcional, sin embargo, puede ser necesario bajo ciertas circunstancias.
content += '<p class="card-text">' + post.excerpt.replace(/<a/g, '<em').replace(/<\/a/g, '</em') + '</p>';
content += '<a href="' + postLink + '">Leer más</a>';
content += '</div>';
content += '</div>';
$(this).append(content);
}
};
});
}(jQuery));
</script>
</body>
</html>
El aspecto final
El JavaScript es lo suficientemente genérico como para reutilizarse en diferentes sitios web. Sin embargo, es posible que desees revisarlo paso a paso para adaptarlo a tus necesidades. Especialmente la parte de marcado HTML, ya que es muy probable que deba personalizarse para adaptarse a la estructura de marcado de tu sitio.
¡Disfruta!
h/t @sesemaya Embed latest topics from Discourse on your website - development - Daemon Labs


