在外部网站上嵌入 Discourse 主题列表

:bookmark: 本指南介绍如何使用 JavaScript 在外部网站上嵌入并显示 Discourse 主题列表,从而在博客、网站或外部内容平台上展示论坛内容(如讨论或公告)。

:person_raising_hand: 所需用户等级:管理员

摘要

在外部网站上嵌入 Discourse 主题,使您能够直接将 Discourse 论坛的主题列表显示在其他站点上。这种集成有助于为论坛引流,并保持受众与社区内容的互动。嵌入的主题以 JavaScript 小部件的形式呈现,可与您站点的 DOM 结构集成,从而更便于通过 CSS 进行自定义。

启用主题嵌入

要在外部站点上设置主题嵌入,请执行以下步骤:

  1. 导航至 管理 > 高级 > 嵌入,切换到 设置 选项卡。启用 embed_topics_list 站点设置。

  1. 将嵌入脚本添加到外部站点的 HTML <head> 部分:
<script src="https://discourse.example.com/javascripts/embed-topics.js"></script>

discourse.example.com 替换为您实际的 Discourse 论坛 URL。

  1. 在您希望显示主题的位置放置主题列表元素(例如在博客文章或单个站点页面上):
<d-topics-list discourse-url="https://discourse.example.com" category="1234" per-page="5"></d-topics-list>
  1. 如果您在与 Discourse 站点不同的域上嵌入主题,请将您的外部站点域名添加到 管理 > 高级 > 嵌入 > 主机

例如,如果您的 Discourse 站点位于 yourdiscourseforum.com,而您希望在 yourexternalsite.com 上嵌入主题,则需要将 yourexternalsite.com 添加到您的允许主机列表中。

:warning: 您无法嵌入来自需要登录的私有 Discourse 站点的主题。

配置参数

d-topics-list 元素支持以下属性以自定义主题显示:

  • discourse-url - 您的 Discourse 站点 URL(必需)
  • template - 显示样式选项:
    • basic(默认)- 仅显示作为链接的主题标题
    • complete - 显示标题、用户名、头像、创建时间、最后回复时间、点赞数、回复数以及特色图片/缩略图
  • per-page - 显示的主题数量(受隐藏的 embed_topic_limit_per_page 站点设置限制,默认为 200)
  • category - 类别 ID,用于从特定类别筛选主题
  • tags - 按特定标签筛选主题
  • allow-create - 设置为 true 时,显示“新建主题”按钮
  • embed-class - 为嵌入的主题列表容器添加自定义 CSS 类(仅限字母数字、连字符和下划线)
  • top-period - 显示特定时间段内的热门主题:
    • all
    • yearly
    • quarterly
    • monthly
    • weekly
    • daily

您可以组合多个参数以优化主题列表的显示。例如:

<d-topics-list 
  discourse-url="https://discourse.example.com" 
  category="5" 
  tags="announcements" 
  per-page="10"
  template="complete">
</d-topics-list>

自定义外观

您可以在 管理 > 外观 > 主题和组件 面板中使用自定义 SCSS 来设置嵌入主题的样式。点击当前或默认主题,然后点击 编辑代码。接着选择 Show_advanced 并选择 嵌入式 CSS 以添加您的自定义代码:

以下是创建网格布局的 SCSS 示例:

.topics-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  
  .topic-list-item {
    .main-link {
      border: 1px dotted gray;
      padding: 0;
    }
    
    .topic-column-wrapper {
      flex-direction: column-reverse;
      
      .topic-column.details-column {
        width: 100%;
      }
      
      .topic-column.featured-image-column .topic-featured-image img {
        max-width: initial;
        max-height: initial;
        width: 100%;
      }
    }
  }
}

最佳实践

  • 使用有意义的类别和标签筛选器,以向受众展示相关内容
  • 设置合适的 per-page 值,避免让访客感到信息过载
  • 在不同屏幕尺寸上测试嵌入的主题,确保响应式设计正常
  • 在空间允许的情况下,考虑使用 complete 模板以获得更好的视觉效果
  • 定期审查您的允许主机列表,确保只有授权域名可以嵌入您的主题

常见问题与解决方案

外部域上未显示主题

问题:在外部域上查看时,嵌入的主题显示为空白或灰色方框。

解决方案:将外部域名添加到 Discourse 站点的 管理 > 高级 > 嵌入 > 主机。请确保包含正确的子域名(例如,如果您的站点使用 www.example.com,请添加 www.example.com 而不是仅添加 example.com)。

脚本加载错误

问题:嵌入脚本加载失败或返回连接错误。

解决方案

  • 验证脚本源中的 Discourse URL 是否正确且可访问
  • 检查 embed_topics_list 站点设置是否已启用
  • 确保您的 Discourse 站点对公开主题不要求登录

SameSite 上下文行为

在嵌入站点和论坛共享父域名的 SameSite 上下文中,Discourse 会尊重登录状态并相应地显示结果。已登录用户可能看到匿名用户无法访问的安全类别中的内容。

常见问题解答(FAQs)

问:我可以嵌入来自私有 Discourse 站点的主题吗?
答:不可以。主题嵌入仅适用于公共 Discourse 站点。需要登录的私有站点无法被嵌入。

问:我可以在同一页面上嵌入多个主题列表吗?
答:可以。您可以在同一页面上包含多个 <d-topics-list> 元素,并使用不同的参数来显示各种主题集合。

问:如何嵌入带有特色图片的主题?
答:在您的 <d-topics-list> 元素中使用 template="complete" 参数,即可显示带有缩略图和特色图片的主题。

问:我可以更改主题链接的打开位置吗?
答:默认情况下,主题链接会在父窗口中打开。您可以通过 CSS 或 JavaScript 自定义来修改此行为。

其他资源

9 个赞

这是否适用于 Discourse 订阅?我尝试实现它,但它却将我的整个论坛框起来,而不是主题?

1 个赞

是的,这应该可以与Discourse Subscriptions插件一起正常工作。

嵌入依赖于配置特定参数来控制显示哪些主题,例如通过网站HTML中的d-topics-list标签来设置categorytagsper-page。如果您的嵌入最终框定了您的整个论坛,您可能需要确保Discourse URL和d-topics-list标签中的任何参数都已正确设置,以反映您打算显示的主题。

4 个赞

你好,非常好!谢谢!

我想将 topic-list-item a 元素的 target 值更改为 “_blank”(默认是 “_parent”,存在跨域问题,也不是我想要的),

我该怎么做?

您好,我正尝试将这些内容显示在两个不同的网站上。

我的 Discourse URL 是 https://learn.getupearlier.com

我已将此脚本嵌入在此处,并且可以正常工作:

我已将相同的脚本嵌入在此处,但无法正常工作:

这是放在标头中的内容:

<script src="https://learn.getupearlier.com/javascripts/embed-topics.js"></script>

这是放在页面中的内容:

<d-topics-list discourse-url="https://learn.getupearlier.com" category="5" per-page="10"></d-topics-list>

任何帮助都将不胜感激!

2 个赞

您好 Michael,

您在这里遇到的问题很可能与使用不同于您的 Discourse 域的域来嵌入主题有关。

您的脚本在 getupearlier.com 上可以工作,因为这与您的 Discourse 站点 learn.getupearlier.com 位于同一域上,而 michaelbakerdigital.com 位于不同的域上。

我已将此部分添加到指南中,其中解释了如何解决这种情况。

因此,在您的情况下,将 michaelbakerdigital.com 添加到您的 Discourse 站点的“嵌入”→“允许的主机”应该可以使您在该域上正确嵌入主题。

6 个赞

您好,我允许了我下面显示的这个 URL:

这是测试 URL:
https://www.michaelbakerdigital.com/discourse-test/

我只得到一个空白的灰色错误框

这是 michaelbakerdigital.com 里面的代码

<div id='discourse-comments'></div>
<meta name='discourse-username' content='MikeB'>

<script type="text/javascript">
  DiscourseEmbed = {
    discourseUrl: 'https://learn.getupearlier.com/',
    discourseEmbedUrl: 'michaelbakerdigital.com',
    // className: 'CLASS_NAME',
  };

  (function() {
    var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
    d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
  })();
</script>

或者这个:

<d-topics-list discourse-url="https://learn.getupearlier.com" category="5" per-page="5"></d-topics-list>

非常感谢您的帮助,我一直被这个问题困扰,一直想解决它。

你好,这里的解决方案是我的域名在嵌入部分添加了 www。

就是这样!花了这么多时间来处理这 4 个字符,但最终在 Discourse 和 WP Engine 支持的帮助下解决了。

是否有示例代码可用于将特色图片输出到外部网站?

非常感谢

需要帮助:在 Next.js 网站上嵌入 Discourse 主题列表

大家好,

我正尝试在我用 Next.js 框架和 Node.js 构建、并通过 Vercel 部署的网站 (example.io) 上嵌入 Discourse 主题列表。为此,我在 test-discourse.app 上创建了一个测试副本。

以下是我目前所做的:

  1. 在 Discourse 的嵌入设置中添加了主机。
  2. 在环境中启用了 CORS,并将主机添加到了 CORS 源。
  3. 关闭了 CSP (内容安全策略)。

尽管遵循了这些步骤并添加了必要的脚本,我仍然无法在我的网站上看到主题列表。

这是我正在使用的代码:

在 head 部分:

<script src="my-website/javascripts/embed-topics.js"></script>

在 body 部分:

<d-topics-list discourse-url="my-website" tags="example"></d-topics-list>

也尝试了帖子中所示的分类嵌入。

有人能指出我可能遗漏或做错的地方吗?任何关于让主题列表出现在我网站上的建议都将不胜感激。

提前感谢您的帮助!

我有一个 Discourse 实例运行在 VPS 上
我还有另一个网站运行在不同的 VPS 上
两者都有相同的根域名,例如

community.mydomain.com
mydomain.com

我已成功使用此方法将论坛服务器 (Discourse) 的主题列表嵌入到另一个网站中。这对于从我的网站吸引流量到论坛非常有用。

我使用右侧边栏块组件来列出 discourse-calendar 插件日历中的“即将举行的活动”

我想在我的其他网站上复制“即将举行的活动”。我可以使用此主题中描述的方法来获取日历类别中的所有主题,但它们的排序方式是按最近发布的时间。

右侧边栏块组件按活动日期对它们进行排序
示例

有办法做到这一点吗?我对两个网站都有管理控制权。
是否有其他方法可以从我的 Discourse 服务器提取数据,例如 API?API 是默认安装在所有 Discourse 实例上的,还是我必须安装它?

1 个赞

既然我没有得到任何提示,我想我会为那些查看的人回答我自己的几个问题。

仅供参考,是的,自托管的 官方安装 包括 REST API。

API 示例线程 获取提示,了解如何从终端发出 cURL 调用。一旦 cURL 命令起作用,我就使用这个网站将命令行版本转换为 PHP

我的另一个服务器运行 PHP 作为后端,我从网页向服务器上的函数发出 ajax 调用。Discourse 输出它构建用于解码的 json 和 javascript。按需样式化……汤
注意这可能只起作用,因为

并且我使用 API 密钥和用户,如 此处 所示。
希望这对某人有帮助 :+1:

1 个赞

我们似乎也可以像这样在论坛帖子中使用嵌入链接:

<iframe> width="500" height="400" src="https://meta.discourse.org/embed/topics?tags=release-notes" frameborder="0" scrolling="no"></iframe>

(在这里它不起作用,因为他们尚未在其 iframe 管理设置中启用自己的网站)

但是,scrolling="no" 无效……显然,标准机构在 HTML5 中已弃用 scrolling,并用……什么都没有替换它。iframe 每年都在变得更好,对吧?

在我测试时,如果我将 iframe 中的 <body> 更改为 overflow: hidden,水平滚动条就会消失。我还没有找到一种方法来消除垂直滚动条。从我的插件来看,我是否有办法修改嵌入页面以设置 overflow: hidden

嵌入主题列表时,如果我想从所有嵌入的主题创建一个带有水平滚动的轮播,哪种方式“最好”?

有没有办法将每个主题链接更改为在新标签页/窗口中打开?