We are launching a forum for our product, whose external embeds already function with OneBox after allowing Iframes from us.
A direct link to an embed, is neatly transformed into the result of our oembed endpoint.
Now, our concern is first and foremost that we would like thumbnails to appear when the Topic List Thumbnails is active. I am not sure why the thumbnail is not picked up.
To add, the default behavior mostly works today, short of not supporting our dynamic embeds. We’d like to load JS instead of an Iframe. Admittedly there is a different solution to this, namely to optionally resize the iframe with some JS, but we are not planning to implement that generically for oEmbeds in the short run.
After some discussion with the Discourse team at email, I’m updating here.
The main discovery is that thumbnails are not loaded if a link which becomes a onebox is rendered as an iframe.
This means that the link:
Will and will not render a thumbnail depending on whether iframes are allowed from the domain (allowed iframes). The solution to this is to somehow inject an iframe to the post. I made a plugin which does so, and makes sure display: none is set on the image, to prevent it from appearing in the post.
I imagine it is possible to generalize this to either:
For all generic oneboxes, silently load and hide an image next to it if get_oembed.thumbnail_url exists.
Arguably a better solution, add general support for extracting get_oembed.thumbnail_url and associating it with the post, without it being part of the cooked area itself.
I am not super happy about this modal behavior, that is, is allowed iframes enabled or not? It would be nice if Discourse extracts and makes use of all properties from a given oembed endpoint when it first sends a GET to it.
Have you tried this? Writing a specific onebox for your case might allow you to supply a onebox image to the cooked post? Then thumbnails would then work automatically.
I note that Youtube oneboxes I believe are static in-site content, until you click the play button and then it shows an iframe. The content presented prior to the click includes an image which is picked up then thumbnailed. Obviously Discourse can’t read from an iframe, so this technique is a good approach.
I note your example includes an og:image in the header tags which is perfect.
The only downside to this will be your image will be static until you rebuild the Post, assuming the target image is also updated. Thus if you are hoping to show a dynamically changing thumbnail you might have to get even more creative.
Writing a plugin was the first thing I did, and that worked fantastically—no matter if I put it in lib/onebox/engine, or as a separate plugin. The caveat is that we are on a hosted plan, where plugins are understandably not allowed on multi-tenant plans, leaving cooking in Rails out of the question.
That leaves us with one of three opportunities:
Running our own instance
Hacking something on the client-side, if it might work
Which means that if we were to modify this selector, we might be able to force in some HTML that is equivalent to a regular image upload. However, it seems modifying editorPreviewNode.innerHTML does not result in any change at all.
Why is this, or what can I modify in composerBeforeSave to do something similar?
This mostly makes sense to me, I think we’d be open to accepting a PR to core for a onebox engine for everviz.com (or similar visualization services). However, I would avoid inserting and hiding an image in the cooked post, there is a lighter option. Discourse’s post processor will look for an upload the following elements:
So adding the thumbnail as an anchor below the iframe might work? You could keep it visible, or hide it using a class like “hidden”.
Apologies for the confusion, the output looked similar to the image onebox engine.
The suggested link (properly fitted with a UUID) does not work. Nor does this image I pulled from Google (and am here writing as an anchor tag. If the pasting some HTML is equivalent to having a onebox output it, this would explain our results.
Ah, my bad, you’re right, that approach doesn’t work. When we generate thumbnails, we use only downloaded images but images linked in an anchor tag aren’t downloaded.
An alternative here might be to add to core something similar to what @merefield recommended, but wrapped as a generic oneboxer for lazy-loaded iframes. Maybe add a new site setting lazy_loaded_iframes, and the onebox can initially output the image from the OG tag (which should get picked up by the thumbnails), and when clicked, a little bit of JS replaces the image with the correct iframe (similar to the Youtube iframe replacement).
One tricky detail here is that the image used and the iframe should have the same height, otherwise this can introduce unwanted jumps when scrolling/navigating posts.