Precisávamos carregar dinamicamente conteúdo do nosso fórum Discourse em labs.daemon.com.au para o site público da nossa empresa em www.daemon.com.au/labs
O código recupera o conteúdo mais recente de categorias selecionadas no Discourse e o envolve na marcação que funciona com nosso site antes de injetá-lo na página. Em seguida, fazemos algumas alterações adicionais para tornar o código mais genérico, permitindo que seja reutilizado facilmente em diferentes sites para carregar conteúdo de diferentes fóruns Discourse.
Um fórum Discourse possui inúmeros endpoints de dados. Por exemplo, quando você acessa Latest, ele carrega o endpoint latest.json, que retorna os dados necessários para aquela página específica. Isso nos permite exibir conteúdo do Discourse em nosso próprio site.
Antes de começar
Para carregar conteúdo do Discourse remotamente, precisamos tornar os endpoints do Discourse acessíveis ao nosso site. Isso pode ser feito nas configurações de “Admin” do Discourse.
Faça login no Discourse usando uma conta com acesso de administrador e, em seguida, vá para a aba “Settings” no painel “Admin”:
Encontre “Security” na navegação à esquerda e localize o campo “cors origins” no lado direito. Adicione a URL do site que exibirá o conteúdo do Discourse no campo (no nosso caso: http://www.daemon.com.au/) e salve as alterações:
Endpoints
Como o Discourse gera inúmeros endpoints de dados, é importante encontrar o correto dependendo do conteúdo que precisa ser exibido remotamente. Adicionar /l/latest.json ao final da URL de uma página de categoria mostrará o endpoint contendo as últimas postagens daquela categoria específica. Por exemplo, https://labs.daemon.com.au/c/design/l/latest.json é o endpoint para https://labs.daemon.com.au/c/design.
HTML & JavaScript
Agora que temos o endpoint necessário, vamos habilitar nosso site para ler esse endpoint, permitindo que ele recupere informações úteis e as exiba corretamente. Neste exemplo, nosso objetivo é exibir as 3 últimas postagens publicadas pelo Usuário #1, #2 ou #3 na categoria “Design” dentro do #div em nosso site. Além disso, não queremos mostrar a postagem “About the design category”.
N.B. Em nosso exemplo, usamos o Bootstrap padrão v4.0.0-beta.2 apenas para fornecer alguns estilos necessários para fins de demonstração, e seu uso é 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 for basic styles in the demo -->
<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) {
// Parse data to generate content from Discourse:
// * Discourse endpoint, i.e. `result`,
// * Number of posts to be shown on your site, e.g. `3`,
// * Optional array of user IDs (whitelist)
// if only posts published by particular users are intended to be shown on your site, e.g. `[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;
// Make sure there are enough posts to be shown.
if (numToShow > feedLength) {
numToShow = feedLength;
}
for (var i = 0; i < numToShow; i++) {
var content = '';
// URLs in Discourse endpoints are all relative URLs (e.g. topic.image_url),
// we need this so that the links displayed on your site point to the right places.
// Please modify this to the URL of your Discourse forum.
var discourseURL = 'http://labs.daemon.com.au/';
// Variables for Discourse post data.
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;
// If whitelist is present, check whether the post author is a verified user.
if (typeof whitelist !== 'undefined') {
var verifiedUser = false;
for (var n = 0; n < whitelist.length; n++) {
if (postAuthor === whitelist[n]) {
verifiedUser = true;
break;
}
}
// If the post author is not on the whitelist,
// breaks this iteration and continues with the next iteration in the loop.
if (!verifiedUser) {
// Increase number of posts to be shown if possible
// to compensate for the eliminated post.
if (numToShow < feedLength) {
numToShow++;
}
continue;
}
}
// The following block of code is optional.
// The purpose is to ignore the "About the X category" post
// since it may not be desirable to be displayed on your site.
if (post.title.substring(0, 10) === "About the " && post.title.substring(post.title.length - 9) === ' category') {
// Increase number of posts to be shown if possible
// to compensate for the eliminated post.
if (numToShow < feedLength) {
numToShow++;
}
continue;
}
// If a post does not have a thumbnail,
// then use a default placeholder image as its thumbnail for your site.
// Please modify this to use your site's placeholder image.
if (post.image_url === null) {
postThumbnail = 'http://placehold.it/320x180';
}
// Generate HTML for your site.
// This part of the code may need to be modified accordingly
// to fit the markup of your 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>';
// The following line does a little bit more than displaying excerpt as it is,
// it replaces `<a>` tags in the excerpt with `<em>` tags
// so that they do not show up as links on your site.
// This is optional, however it may be necessary under certain circumstances.
content += '<p class="card-text">' + post.excerpt.replace(/<a/g, '<em').replace(/<\/a/g, '</em') + '</p>';
content += '<a href="' + postLink + '">Read more</a>';
content += '</div>';
content += '</div>';
$(this).append(content);
}
};
});
}(jQuery));
</script>
</body>
</html>
O resultado final
O JavaScript é genérico o suficiente para ser reutilizado em diferentes sites. No entanto, você pode querer seguir passo a passo para adaptá-lo às suas necessidades. Especialmente a parte da marcação HTML, pois é muito provável que precise ser personalizada para se adequar à marcação do seu site.
Divirta-se!
h/t @sesemaya Embed latest topics from Discourse on your website - development - Daemon Labs


