kluvin
(Martin Kleiven)
1
我们正在为我们的产品推出一个论坛,其外部嵌入在允许我们使用 Iframes 后已能通过 OneBox 正常运行。
指向 embed 的直接链接,会整齐地转换为我们 oembed endpoint 的结果。
现在,我们首先关心的是,当启用 Topic List Thumbnails 时,我们希望缩略图能够显示出来。我不确定为什么缩略图没有被抓取到。
我们需要将集成添加到 lib/onebox/engine 吗?
补充说明,默认行为今天大部分都能正常工作,只是不支持我们的动态嵌入。我们希望加载 JS 而不是 Iframe。不可否认,这有另一种解决方案,即使用一些 JS 可选地调整 iframe 的大小,但我们短期内不打算为 oEmbed 通用实现这一点。
我知道 Using onebox images for topic thumbnails - #20 by david,但发现它对我的情况没有帮助。
1 个赞
kluvin
(Martin Kleiven)
3
在与 Discourse 团队通过电子邮件进行一些讨论后,我在此更新。
主要发现是,如果一个会变成 onebox 的链接被渲染成 iframe,缩略图将不会被加载。
这意味着链接:
https://app.everviz.com/embed/N0dDTJaOQ
是否渲染缩略图取决于是否允许来自该域的 iframe(“允许的 iframe”)。解决方案是某种方式将 iframe 注入帖子。我创建了一个 插件,它会这样做,并确保将 display: none 设置在图片上,以防止它出现在帖子中。
我认为可以将其推广为:
- 对于所有通用的 onebox,如果
get_oembed.thumbnail_url 存在,则静默加载并隐藏旁边的图片。
- 也许更好的解决方案是,添加通用支持来提取
get_oembed.thumbnail_url 并将其与帖子关联,而无需将其本身作为 cooked 区域的一部分。
相关位置:
- https://oembed.com/
- discourse/lib/onebox/engine at main · discourse/discourse · GitHub
- discourse/lib/onebox/engine/standard_embed.rb at main · discourse/discourse · GitHub
我对这种模态行为不太满意,即是否启用了“允许的 iframe”?如果 Discourse 在首次向 oembed 端点发送 GET 请求时提取并使用该端点的所有属性,那将是很好的。
kluvin
(Martin Kleiven)
4
更新
我有一个想法,就是使用客户端插件 API 将图片加载到帖子中。
api.decorateCooked($elem => {
$elem[0].querySelectorAll('.my-iframe')
.forEach(function (iframe) {
// 工作
iframe.insertAdjacentElement('beforebegin', thumbnail);
});
}, {id: 'unique_string'});
但是 Discourse 没有识别到任何内容。
似乎发生了以下两种情况之一:
- 我们太晚了,Discourse 已经完成了缩略图检索和生成。
- 我们的图片缺少某些属性,导致缩略图生成机制错过了它。
希望是后者。这里需要注意的一点是,图片从未上传到我们的 Discourse 实例,而只是从我们自己的服务器引用。
您尝试过这样做吗?为您的特定情况编写一个 onebox 可能会允许您为已处理的帖子提供一个 onebox 图片?然后缩略图就会自动工作。
我注意到 Youtube 的 onebox 我认为是在网站内部静态显示的,直到您点击播放按钮,然后它会显示一个 iframe。点击之前呈现的内容包括一张图片,然后这张图片会被拾取并缩略。显然 Discourse 无法从 iframe 中读取内容,因此这种技术是一个很好的方法。
我注意到您的示例在 header 标签中包含了一个 og:image,这非常完美。
我的建议是,在这里放弃 javascript,然后在 Rails 中进行处理。
这唯一的缺点是您的图片将是静态的,直到您重建帖子,假设目标图片也已更新。因此,如果您希望显示动态变化的缩略图,您可能需要更有创意。
3 个赞
kluvin
(Martin Kleiven)
6
您好 Robert,感谢您的回复!
编写插件是我做的第一件事,而且效果非常好——无论我把它放在 lib/onebox/engine 中,还是作为一个单独的插件。需要注意的是,我们使用的是托管计划,而插件在多租户计划中是不能使用的,因此在 Rails 中进行定制是不可能的。
这样我们就剩下三种选择:
- 运行我们自己的实例
- 尝试在客户端进行一些修改,看看是否可行
- 向 主线 Discourse 提交一个 PR
在此提出一个问题。我不确定这样的贡献是否会被接受,特别是如果它只是加载一张图片然后隐藏它。我该如何了解情况?
2 个赞
kluvin
(Martin Kleiven)
7
我已经在这方面取得了一些进展。查看:
api.composerBeforeSave
其回调在 composer.js 中处理。从那里,我们可以看到 createPost 和 editPost 方法调用 getCookedHtml,它或多或少地返回以下内容的 innerHTML:
const editorPreviewNode = document.querySelector(
"#reply-control .d-editor-preview"
);
这意味着,如果我们修改此选择器,我们或许可以强制插入等同于常规图像上传的 HTML。但是,修改 editorPreviewNode.innerHTML 似乎没有任何效果。
这是为什么,或者我可以在 composerBeforeSave 中修改什么来实现类似的功能?
pmusaraj
(Penar Musaraj)
9
这对我来说大部分是说得通的,我认为我们会接受一个 PR 来为 everviz.com(或类似的视觉化服务)的核心添加一个 onebox 引擎。但是,我会避免在 cooked 帖子中插入和隐藏图片,有一个更轻量级的选择。Discourse 的帖子处理器会查找上传,以下是元素:
所以将缩略图添加为 iframe 下方的锚点可能有效?你可以让它保持可见,或者使用像“hidden”这样的类来隐藏它。
5 个赞
kluvin
(Martin Kleiven)
10
您好,Penar,感谢您的回复。
使用
<div>
#{get_oembed.html}
<a class="hidden" href="https://app.everviz.com/thumbnails/#{match[:uuid]}.png"></a>
</div>
作为我的 to_html 方法,会产生以下输出:
<div class="...">
<iframe>
...
</iframe>
<a class="hidden" href="https://app.everviz.com/thumbnails/[...].png" rel="nofollow ugc noopener"></a>
</div>
直接链接一张图片会产生:
<a href="https://app.everviz.com/thumbnails/[...].png" target="_blank" rel="noopener" class="onebox">
<img src="//localhost:3000/uploads/default/original/1X/[...].png"
style="aspect-ratio: 690 / 459;" loading="lazy">
</a>
这似乎是因为 image_onebox.rb 引擎仅在链接的图片不是由其他 onebox 引擎处理的上下文之外时才运行。
其后果是,目前建议的技术不起作用,因此有必要链接并隐藏一张图片,或者修改 Discourse 以适应这种情况。
在这种情况下,插入并隐藏一张图片是否可以接受的 PR?或者需要做更复杂的事情?
pmusaraj
(Penar Musaraj)
11
我不确定我是否理解,这不应该通过图片 onebox 引擎。
这个:
<a class="hidden" href="https://app.everviz.com/thumbnails/[...].png" rel="nofollow ugc noopener"></a>
不起作用吗?也就是说,当一个主题的第一个帖子在其“cooked”列中有这个时,图片在处理后会被识别为缩略图吗?
2 个赞
kluvin
(Martin Kleiven)
12
抱歉造成混淆,输出看起来像图片单框引擎。
建议的链接(已正确添加 UUID)不起作用。我从 Google 提取的此图片也不起作用(并且我在此处将其写为锚定标签。如果粘贴一些 HTML 等同于输出单框,这将解释我们的结果)。
https://static-cse.canva.com/blob/1031184/1600w-wK95f3XNRaM.jpg
1 个赞
pmusaraj
(Penar Musaraj)
13
啊,我的错,你说得对,那种方法行不通。我们生成缩略图时,只使用下载的图片,但锚标签中的图片不会被下载。
这里的一个替代方案可能是向核心添加一些类似 @merefield 推荐的功能,但将其包装成一个通用的 oneboxer,用于延迟加载的 iframe。也许可以添加一个新的站点设置 lazy_loaded_iframes,onebox 最初可以输出 OG 标签中的图片(这应该会被缩略图拾取),点击后,一小段 JavaScript 会将图片替换为正确的 iframe(类似于 YouTube iframe 的替换方式)。
这里一个棘手的细节是,使用的图片和 iframe 应该有相同的高度,否则这可能会在滚动/导航帖子时引入不必要的跳跃。
3 个赞