我们需要将内容从我们的 Discourse 论坛 labs.daemon.com.au 动态加载到公司公共网站 www.daemon.com.au/labs 中。
该代码会检索所选类别中来自 Discourse 的最新内容,然后将其包装为与我们网站兼容的标记,最后注入到页面中。随后,我们进行一些调整,使代码更加通用,以便在不同网站上轻松重用,用于从不同的 Discourse 论坛加载内容。
Discourse 论坛拥有众多数据端点。例如,当您访问 最新帖子 时,它会加载 latest.json 端点,返回该页面所需的数据。这使得我们能够在自己的网站上显示 Discourse 的内容。
开始之前
为了从 Discourse 远程加载内容,我们必须使 Discourse 的端点可供我们的网站访问。这可以在 Discourse 的“管理”设置中完成。
使用具有管理员权限的账户登录 Discourse,然后进入“管理”面板中的“设置”标签页:
在左侧导航中找到“安全”,然后在右侧找到"cors origins"字段。在字段中添加将显示 Discourse 内容的网站 URL(在我们的例子中为:http://www.daemon.com.au/),然后保存更改:
端点
由于 Discourse 生成了无数数据端点,因此根据远程显示所需的内容找到正确的端点非常重要。在类别页面 URL 末尾添加 /l/latest.json 将显示包含该类别最新帖子的端点。例如,https://labs.daemon.com.au/c/design/l/latest.json 是 https://labs.daemon.com.au/c/design 的端点。
HTML 与 JavaScript
既然我们已经有了所需的端点,现在需要使我们的网站能够读取该端点,以便获取有用信息并正确显示。在本示例中,我们旨在显示“设计”类别中由用户 #1、#2 或 #3 发布的最新 3 篇帖子,并将其展示在网站的 #div 中。此外,我们不希望显示“关于设计类别”的帖子。
注意:在我们的示例中,我们使用了默认的 Bootstrap v4.0.0-beta.2,仅为演示目的提供一些必要的样式,其使用完全是可选的。
<!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 嵌入</title>
<!-- 用于演示的基本样式 Bootstrap CSS -->
<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) {
// 解析数据以从 Discourse 生成内容:
// * Discourse 端点,即 `result`,
// * 要在您的网站上显示的帖子数量,例如 `3`,
// * 可选的用户 ID 数组(白名单)
// 如果仅希望显示特定用户发布的帖子,例如 `[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;
// 确保有足够的帖子可以显示。
if (numToShow > feedLength) {
numToShow = feedLength;
}
for (var i = 0; i < numToShow; i++) {
var content = '';
// Discourse 端点中的 URL 都是相对 URL(例如 topic.image_url),
// 我们需要这样设置,以便在您的网站上显示的链接指向正确的位置。
// 请将其修改为您的 Discourse 论坛的 URL。
var discourseURL = 'http://labs.daemon.com.au/';
// 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;
// 如果存在白名单,检查帖子作者是否为已验证用户。
if (typeof whitelist !== 'undefined') {
var verifiedUser = false;
for (var n = 0; n < whitelist.length; n++) {
if (postAuthor === whitelist[n]) {
verifiedUser = true;
break;
}
}
// 如果帖子作者不在白名单中,
// 则中断当前迭代并继续循环中的下一次迭代。
if (!verifiedUser) {
// 如果可能,增加要显示的帖子数量
// 以补偿被排除的帖子。
if (numToShow < feedLength) {
numToShow++;
}
continue;
}
}
// 以下代码块是可选的。
// 目的是忽略“关于 X 类别”的帖子,
// 因为它可能不适合在您的网站上显示。
if (post.title.substring(0, 10) === "About the " && post.title.substring(post.title.length - 9) === ' category') {
// 如果可能,增加要显示的帖子数量
// 以补偿被排除的帖子。
if (numToShow < feedLength) {
numToShow++;
}
continue;
}
// 如果帖子没有缩略图,
// 则使用默认占位符图像作为其缩略图。
// 请将其修改为您的网站的占位符图像。
if (post.image_url === null) {
postThumbnail = 'http://placehold.it/320x180';
}
// 为您的网站生成 HTML。
// 这部分代码可能需要相应修改
// 以符合您网站的标记结构。
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>';
// 以下行不仅显示摘要,
// 还将摘要中的 `<a>` 标签替换为 `<em>` 标签,
// 这样它们就不会在您的网站上显示为链接。
// 这是可选的,但在某些情况下可能是必要的。
content += '<p class="card-text">' + post.excerpt.replace(/<a/g, '<em').replace(/<\/a/g, '</em') + '</p>';
content += '<a href="' + postLink + '">阅读更多</a>';
content += '</div>';
content += '</div>';
$(this).append(content);
}
};
});
}(jQuery));
</script>
</body>
</html>
最终效果
该 JavaScript 代码足够通用,可以在不同网站上重用。不过,您可能希望逐步检查并根据您的需求进行调整。特别是 HTML 标记部分,因为它很可能需要根据您网站的标记结构进行自定义。
祝您使用愉快!
致谢 @sesemaya Embed latest topics from Discourse on your website - development - Daemon Labs


