我有一个网站,我会在上面发布各种教程和博客,并且我将 Discourse 用作论坛和评论区(通过嵌入功能)。
这在大多数情况下都运行良好,但有一个问题:当我创建新页面时,所有内容都会被包含在 Discourse 帖子中。我的有些用户甚至不知道主站的存在,因为他们总是在论坛上阅读完整帖子!这是一个问题,因为像嵌入式代码编辑器这样的功能在 Discourse 上无法正常工作,这给他们带来了糟糕的体验。
在理想情况下,Discourse 帖子应该只是一个简短、非常明显的链接,指向主页上的原始帖子。也许是这样的:
在此处查看原始帖子:
https://example.com
对此帖的回复将显示为原始帖子的评论!
我尝试禁用 embed truncate 设置,如此帖子 中所述,但这似乎隐藏了“显示完整帖子”按钮,但帖子中仍然显示所有内容。
我也尝试编辑 embed.imported_from 消息,但这只会改变人们似乎已经忽略的底部的微小文字。
我也尝试在 Discourse 创建帖子后手动编辑它,但 Markdown 没有被渲染成 HTML,而是显示为纯文本。这听起来与此问题类似:Customizing the "Embedding" Behavior by Disabling Show Full Post?
我是否遗漏了某个设置,或者有什么其他技巧可以用来自定义自动生成的 Discourse 帖子的文本?也许我可以在主站的 HTML 中包含一些内容来欺骗 Discourse 显示正确的内容?或者,如果能解决 Markdown 渲染问题,我也愿意手动编辑它。
感谢您提供的任何帮助!
1 个赞
抱歉打扰,但如果有人能给我一些建议,我将不胜感激!
angus
(Angus McLeod)
2022 年7 月 14 日 12:32
3
1 个赞
感谢您的回复!我正在使用 JavaScript 嵌入。例如,我有这个页面:
其中包含此嵌入代码:
<script type="text/javascript">
DiscourseEmbed = { discourseUrl: location.protocol
+ '//forum.happycoding.io/',
discourseEmbedUrl: location.protocol + '//happycoding.io/tutorials/javascript/react-css' };
(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>
这会在我的 Discourse 中创建此帖子:
https://forum.happycoding.io/t/css-in-react/1092
如果您点击它,您会看到该帖子包含原始页面的全部文本。
angus
(Angus McLeod)
2022 年7 月 15 日 10:04
5
感谢您的澄清。
为什么要在 Discourse 中启用 embed truncate 网站设置?我有点困惑,因为您提到您已禁用它,但您也说您的问题是
embed truncate 设置部分就是为此原因而存在的。这意味着用户在 Discourse 本身中只会看到帖子的部分摘录。
您能否更详细地解释一下您试图避免的具体用户行为,以及您试图鼓励的具体用户行为。
1 个赞
我一直在反复考虑 embed truncate 设置。现在再看一遍,我认为启用它稍微好一些,但我仍然希望有一种方法可以完全避免在 Discourse 中显示原始文章的全文。换句话说,我不想将全文隐藏在按钮点击后面——我根本不想显示全文,只想提供指向原始文章的链接。
我试图避免的行为是用户访问我的 Discourse 并直接在 Discourse 上阅读整篇文章,而不是在原始页面上阅读。这是一个问题,因为 Discourse 上的全文通常包含错误(例如交互式 JS、嵌入式代码等),然后我收到的错误报告会建议停止在 Discourse 上阅读,而是转到“真正的”网站。
换句话说,我试图鼓励的用户行为是在原始页面上阅读整篇文章,而不是在 Discourse 帖子中阅读。
这可能看起来微不足道(从宏观角度来看确实如此),但我担心的是用户会访问我的 Discourse,认为页面的行为存在错误,然后在他们意识到我的“真正”网站上有一个页面应该阅读而不是 Discourse 帖子之前就离开了。
我考虑过的一些可能选项:
是否有某个设置可以告诉 Discourse 只包含链接,而不包含原始帖子的任何内容?
是否有我可以添加到原始 HTML 中的 CSS 类或其他属性,以指示文章的哪个部分应包含(或排除)在 Discourse 帖子中?
也许我可以向 Discourse 添加自定义 CSS 来隐藏“显示完整帖子…”按钮?
angus
(Angus McLeod)
2022 年7 月 18 日 07:20
7
谢谢你的解释,凯文。没有专门针对此问题的设置,但你可以通过两种方式解决此问题。
自定义从你的网站提取的 HTML
嵌入的工作方式是它们使用 Readability gem 从网站抓取内容。该 gem 及其输出使用以下选项来过滤抓取了哪些 HTML
opts[:whitelist] = SiteSetting.allowed_embed_selectors if SiteSetting.allowed_embed_selectors.present?
opts[:blacklist] = SiteSetting.blocked_embed_selectors if SiteSetting.blocked_embed_selectors.present?
allowed_embed_classnames = SiteSetting.allowed_embed_classnames if SiteSetting.allowed_embed_classnames.present?
因此,你可以设置站点设置 allowed_embed_selectors、blocked_embed_selectors 或 allowed_embed_classnames 来限制从你的 HTML 中提取并显示在 Discourse 帖子中的内容,例如,你可以将其限制为不存在的类,这样就不会提取任何内容。
然后,从网站抓取的内容将附加此 HTML:
"\n<hr>\n<small>#{I18n.t('embed.imported_from', link: \"<a href='#{url}'>#{url}</a>\")}</small>\n"
因此,你只需在管理面板中自定义 embed.imported_from 文本,告知用户在博客上阅读内容。请注意,你可以在该文本中插入指向内容的链接,例如,该语言的本地化文本是
这是原始条目的伴随讨论主题,网址为 %{link}
隐藏“显示完整帖子”按钮
正如你所建议的,使用 CSS 隐藏“显示完整帖子”按钮也应该有效。
2 个赞
我很难理解为什么没有选项可以自定义完整的嵌入文本。我不想抓取嵌入式 URL 的任何实际内容,而只是提供一个指向它的链接以及简短的描述(例如,仅摘要)。
现在我通过自动 API 调用来实现这一点,但希望切换到原生嵌入功能。
我尝试在抓取的网站上创建一个隐藏元素,专门供 Discourse 抓取该单个元素,但缺点是链接不会显示 onebox。
自定义 embed.imported_from 也有其局限性,因为它总是被强制放入 \u003csmall\u003e 标签中,不允许任何实际自定义。
angus
(Angus McLeod)
2024 年5 月 20 日 06:25
9
听起来你不是想要嵌入,而嵌入的本质就是“嵌入”来自另一个地方的内容。
你为什么要切换?
Angus McLeod:
听起来你并不想要一个嵌入
确实,我只想在发布新博客文章时自动创建帖子。
但是,我也想使用原生的 JS 嵌入功能,在外部网站的博客文章下方显示评论,这也会带来论坛中的嵌入行为。
我目前的自动化存在一些延迟(不是实时的),并且在我们的 CMS 中实现新文章发布时的自动帖子创建会更困难一些,因为它不仅仅是一个博客 CMS,甚至没有一个明确的“发布”事件。
无论如何,JS 嵌入尝试创建帖子和我的自动化之间会出现冲突,前者通常会更快。这就是为什么我想“切换”到只使用 JS 嵌入功能,缺点是帖子每次都需要手动编辑。
欢迎提出建议!
angus
(Angus McLeod)
2024 年5 月 20 日 09:41
11
谢谢你的解释。
好的,如果我理解正确的话:
你想要 JS 嵌入 的主题创建和评论链接功能;以及
你只想要一个链接,并在 Discourse 中链接主题的第一个帖子中附带简短描述。
我说得对吗?关于第 2 点,你是否尝试过 embed truncate 站点设置?如果尝试过,你觉得它有什么不满意的地方?我明白你在第一个回复中已经稍微提到了这一点,但能否具体解释一下你遇到的困难?也许举一个例子来说明是什么阻碍了你实现期望的结果(以及那个期望的结果到底是什么)。
1 个赞
Angus McLeod:
如果我没理解错的话
是的,你没理解错。
问题出在链接的 onebox(自动预览),它不会显示,因为嵌入内容总是被包裹在 HTML 标签中。
我知道这听起来是个小问题(确实如此),但每次都要手动编辑这篇文章的麻烦程度相当大,而且我早就想修复这个问题了。
我希望它看起来是这样的(以 Discourse 博客文章为例):
目前,我必须去摆弄网站上的隐藏元素才能专门抓取 URL 和摘要,即便如此,问题还是 onebox 没有显示。我唯一能比较完整地自定义的是底部的“阅读完整博文…”部分。
我想我要求的是能够向 JS 代码段添加类似这样的内容:
DiscourseEmbed = {
discourseUrl: 'https://forum.example.com/',
discourseEmbedUrl: 'https://blog.discourse.org/2024/03/a-warm-welcome-to-spiceworks',
discourseRaw: 'https://blog.discourse.org/2024/03/a-warm-welcome-to-spiceworks\n\nWe are thrilled to share the move of the Spiceworks community to Discourse! The Spiceworks team has worked closely with our migration team\n\n<small>Read the full blog post on <a href="https://blog.discourse.org/2024/03/a-warm-welcome-to-spiceworks/">discourse.org</a>. This post has been created automatically and replies will be shown on the website.</small>'
};
discourseEmbedRaw 相当于常规 API 请求 /posts.json 中的 raw 值。
但我明白这可能是一个边缘情况的需求,对大多数用户来说并不重要。我想我将尝试通过在 JS 代码段尝试这样做之前 通过 API 创建主题来解决这个问题。
angus
(Angus McLeod)
2024 年5 月 20 日 11:54
13
我不推荐这样做。
sutterseba:
discourseEmbedRaw
这会导致各种问题。我们暂时把这个问题放在一边。
我很欣赏你希望完全控制一切,但请耐心等待我尝试将你的需求转化为当前系统可能的可行改进。请记住,这些只是建议,我无法控制 Discourse 团队最终是否会接受。
Discourse 中的嵌入式帖子基本上由两部分组成:
“导入自” HTML(即链接)
来自链接页面的 HTML 内容,可以是完整的或截断的。
1. 控制“导入自” HTML
目前,此 HTML 是硬编码的:
"
\u003chr\u003e
\u003csmall\u003e#{I18n.t("embed.imported_from", link: "\u003ca href='#{url}'\u003e#{url}\u003c/a\u003e")}\u003c/small\u003e
"
你希望将其自定义为,例如,仅 URL,以便它可以一键生成。我认为一个可行的改进是添加一个站点设置,将其简单地切换为“仅 URL”,这样你就无需让管理员在某处输入 HTML。
2. 控制截断的 HTML 内容
你已经可以做到这一点了。只需将站点设置 allowed embed classnames 设置为你用于包装你网站上所需摘要的元素的类名即可,例如:
在 Discourse 上
设置以下站点设置:
embed truncate 为 false
allowed embed classnames 为 “discourse-excerpt”
在你的博客页面上
\u003cdiv class="discourse-excerpt"\u003e
我们很高兴地宣布 Spiceworks 社区迁移到 Discourse!Spiceworks 团队与我们的迁移团队密切合作
\u003c/div\u003e
3. 控制“导入自” HTML 和 HTML 内容的顺序
如果我理解正确的话,你希望“导入自”部分(例如仅 URL)出现在 HTML 内容(或截断内容)之前。同样,最简单的方法是添加一个布尔值站点设置,例如 embed imported from above content。
所以,总而言之,如果我理解正确的话,通过添加两个新的布尔设置和对 TopicEmbed 类的少量调整,你就可以实现这一点。你会注意到,所有这些更改都针对 discourse/discourse 本身,因为处理必须在那里进行。
如上所述,这些只是我将如何实现你想要的建议。要实现这些或类似的功能,需要 Discourse 团队的同意。
1 个赞
感谢您写下这些内容!
是的,这正是我尝试过的,问题在于内容会被包装在几个 HTML 标签中,这就是为什么 onebox 不会触发的原因。我尝试用 <br> 标签(以触发 onebox)分隔 URL,但似乎这类内容会自动被修剪掉。
Angus McLeod:
我不推荐这样做。
嗯,好吧,为什么呢?
我当然会设置 embed_url 值。
angus
(Angus McLeod)
2024 年5 月 20 日 13:32
15
让您的嵌入式 URL 触发 onebox 是一个单独的问题。仅使用 allowed embed classnames 来设置文本摘要,就像我的示例一样。
sutterseba:
嗯,好的,为什么?
因为您实际上是在重新发明轮子,试图规避真正的问题——TopicEmbed 解析问题。这还会带来新的问题,例如,如果您的代码没有按预期顺序执行,例如出现竞态条件或其他中间异常。这类问题在使用外部网站的代码和 WP Discourse 插件的混合体时相对常见。总之,不值得。
您似乎对代码库很熟悉 :)。您实际上需要对这个类 进行两个简单的更改。
在此处插入一个由站点设置控制的条件
# downcase
# remove trailing forward slash/
# remove consecutive hyphens
# remove leading and trailing whitespace
url.downcase.sub(%r{/\z}, "").sub(/\-+/, "-").strip
end
def self.imported_from_html(url)
url = UrlHelper.normalized_encode(url)
I18n.with_locale(SiteSetting.default_locale) do
"\n<hr>\n<small>#{I18n.t("embed.imported_from", link: "<a href='#{url}'>#{url}</a>")}</small>\n"
end
end
# Import an article from a source (RSS/Atom/Other)
def self.import(user, url, title, contents, category_id: nil, cook_method: nil, tags: nil)
return unless url =~ %r{\Ahttps?\://}
original_contents = contents.dup.truncate(EMBED_CONTENT_CACHE_MAX_LENGTH)
contents = first_paragraph_from(contents) if SiteSetting.embed_truncate && cook_method.nil?
contents ||= ""
在此处插入另一个由站点设置控制的条件
end
end
# Import an article from a source (RSS/Atom/Other)
def self.import(user, url, title, contents, category_id: nil, cook_method: nil, tags: nil)
return unless url =~ %r{\Ahttps?\://}
original_contents = contents.dup.truncate(EMBED_CONTENT_CACHE_MAX_LENGTH)
contents = first_paragraph_from(contents) if SiteSetting.embed_truncate && cook_method.nil?
contents ||= ""
contents = contents.dup << imported_from_html(url)
url = normalize_url(url)
embed = topic_embed_by_url(url)
content_sha1 = Digest::SHA1.hexdigest(contents)
post = nil
# If there is no embed, create a topic, post and the embed.
if embed.blank?
Topic.transaction do
您甚至不需要构建 discourse 应用程序。只需先编写两个 rspec 测试,然后进行更改,一旦它们正常工作,就可以提交一个 PR
1 个赞
就我而言,这是我最终的做法:
在我的博客上,我有一个 <div>,其 ID 为 forum-excerpt,它被 display:none 隐藏了,但包含我想在 Discourse 帖子中显示的 HTML。(我使用了一些 Jekyll / Liquid 逻辑来实现这一点,但这似乎并不重要。)
在我的 Discourse 上,我将 CSS 选择器,用于允许嵌入的元素 设置为 #forum-excerpt。虽然该 div 在我的实际页面上是隐藏的,但内容会显示在论坛上。
我还取消选中 截断嵌入的帖子。
在 嵌入的 CSS 部分,我为 .button 设置了更大的字体。这是一个小改动,但它使添加评论的按钮变大了。
我还自定义了 embed.continue、embed.start_discussion 和 embed.imported_from 文本,这会更改我的网站评论部分显示的内容。
这意味着我对显示在论坛帖子中的 HTML 拥有完全的控制权。我提供给它的 HTML 基本上相当于一个 OneBox——它是一个大缩略图和一个指向主帖子的链接。
这对我来说几乎完美地奏效,迟到的感谢您的帮助!
2 个赞
system
(system)
关闭
2024 年6 月 20 日 04:20
17
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.