Nous lançons un forum pour notre produit, dont les intégrations externes fonctionnent déjà avec OneBox après avoir autorisé les Iframes de notre part.
Un lien direct vers un embed est joliment transformé en résultat de notre point de terminaison oembed.
Maintenant, notre préoccupation principale est que nous aimerions que des miniatures apparaissent lorsque Topic List Thumbnails est actif. Je ne suis pas sûr de la raison pour laquelle la miniature n’est pas capturée.
Pour ajouter, le comportement par défaut fonctionne en grande partie aujourd’hui, à l’exception du fait qu’il ne prend pas en charge nos intégrations dynamiques. Nous aimerions charger du JS au lieu d’un Iframe. Certes, il existe une solution différente, à savoir redimensionner éventuellement l’iframe avec du JS, mais nous ne prévoyons pas de l’implémenter de manière générique pour les oEmbeds à court terme.
Après quelques discussions avec l’équipe Discourse par e-mail, je mets à jour ici.
La principale découverte est que les miniatures ne sont pas chargées si un lien qui devient un onebox est rendu sous forme d’iframe.
Cela signifie que le lien :
https://app.everviz.com/embed/N0dDTJaOQ
Rendra ou ne rendra pas de miniature en fonction de l’autorisation des iframes du domaine (allowed iframes). La solution consiste à injecter d’une manière ou d’une autre un iframe dans le message. J’ai créé un plugin qui le fait, et s’assure que display: none est appliqué à l’image, pour l’empêcher d’apparaître dans le message.
J’imagine qu’il est possible de généraliser cela soit :
Pour tous les oneboxes génériques, charger silencieusement et masquer une image à côté s’il existe get_oembed.thumbnail_url.
Sans doute une meilleure solution, ajouter un support général pour l’extraction de get_oembed.thumbnail_url et son association au message, sans qu’il fasse partie de la zone cooked elle-même.
Je ne suis pas très satisfait de ce comportement modal, c’est-à-dire si allowed iframes est activé ou non ? Il serait souhaitable que Discourse extrait et utilise toutes les propriétés d’un point de terminaison oembed donné lorsqu’il lui envoie une requête GET pour la première fois.
Il semble que l’une des deux choses suivantes se produise :
Nous sommes en retard et Discourse a déjà effectué la récupération et la génération de la miniature.
Il manque certains attributs à notre image, ce qui fait que le mécanisme de génération de miniatures la manque.
Avec un peu de chance, c’est le second cas. Une chose à noter ici est que l’image n’est jamais téléchargée sur notre instance Discourse, mais simplement référencée depuis notre propre serveur.
Avez-vous essayé cela ? L’écriture d’une onebox spécifique à votre cas pourrait vous permettre de fournir une image onebox au message cuisiné ? Les miniatures fonctionneraient alors automatiquement.
Je note que les onebox Youtube sont, je crois, du contenu statique sur le site, jusqu’à ce que vous cliquiez sur le bouton de lecture, puis qu’elles affichent un iframe. Le contenu présenté avant le clic comprend une image qui est capturée puis mise en miniature. Évidemment, Discourse ne peut pas lire à partir d’un iframe, donc cette technique est une bonne approche.
Je note que votre exemple inclut une balise og:image dans les balises d’en-tête, ce qui est parfait.
Ma suggestion est de vous éloigner de javascript ici et de cuisiner dans Rails.
Le seul inconvénient sera que votre image sera statique jusqu’à ce que vous reconstruisiez le message, en supposant que l’image cible soit également mise à jour. Ainsi, si vous espérez montrer une miniature qui change dynamiquement, vous devrez peut-être faire preuve d’encore plus de créativité.
Écrire un plugin a été la première chose que j’ai faite, et cela a fonctionné à merveille — peu importe si je le mettais dans lib/onebox/engine ou comme un plugin séparé. Le hic, c’est que nous sommes sur un plan hébergé, où les plugins ne sont, de manière compréhensible, pas autorisés sur les plans multi-locataires, ce qui exclut le “cooking” dans Rails.
Cela nous laisse face à l’une des trois opportunités suivantes :
Faire tourner notre propre instance
Pirater quelque chose côté client, si cela peut fonctionner
Pour poser une question ici. Je ne suis pas sûr qu’une telle contribution serait acceptée, surtout si elle charge une image juste pour la cacher. Comment pourrais-je le savoir ?
J’ai peut-être fait quelques progrès à ce sujet. En regardant :
api.composerBeforeSave
Dont le rappel est géré dans composer.js. De là, nous pouvons voir que les méthodes createPost et editPost appellent getCookedHtml, qui renvoie plus ou moins simplement l’innerHTML de :
Ce qui signifie que si nous modifiions ce sélecteur, nous pourrions forcer l’insertion de HTML équivalent à un téléversement d’image normal. Cependant, il semble que la modification de editorPreviewNode.innerHTML n’entraîne aucun changement.
Pourquoi est-ce le cas, ou que puis-je modifier dans composerBeforeSave pour faire quelque chose de similaire ?
Cela me semble tout à fait logique, je pense que nous serions ouverts à accepter une PR pour le cœur afin d’avoir un moteur de onebox pour everviz.com (ou des services de visualisation similaires). Cependant, j’éviterais d’insérer et de cacher une image dans le message cooked, il existe une option plus légère. Le processeur de messages de Discourse recherchera un upload pour les éléments suivants :
Donc, ajouter la miniature comme une ancre sous l’iframe pourrait fonctionner ? Vous pourriez la garder visible, ou la cacher en utilisant une classe comme “hidden”.
Ce qui donne l’impression que le moteur image_onebox.rb s’exécute sur l’entrée uniquement si une image est liée en dehors du contexte d’un autre moteur onebox.
La conséquence est que la technique suggérée ne fonctionne pas pour le moment et il est nécessaire de lier et de masquer une image, ou de modifier Discourse pour en tenir compte.
Serait-il acceptable dans ce cas d’insérer et de masquer une image ? Ou est-il nécessaire de faire quelque chose de plus complexe ?
Je ne suis pas sûr de suivre, cela ne devrait pas passer par le moteur de rendu d’image onebox.
Est-ce que ceci :
<a class="hidden" href="https://app.everviz.com/thumbnails/[...].png" rel="nofollow ugc noopener"></a>
ne fonctionne pas ? Autrement dit, lorsqu’un premier message dans un sujet contient cela dans sa colonne “cooked”, l’image est-elle reconnue comme une miniature après traitement ?
Veuillez excuser la confusion, la sortie ressemblait au moteur onebox d’image.
Le lien suggéré (correctement doté d’un UUID) ne fonctionne pas. Pas plus que cette image que j’ai extraite de Google (et que j’écris ici comme une balise d’ancrage. Si le collage de HTML équivaut à avoir une sortie onebox, cela expliquerait nos résultats.
Ah, désolé, vous avez raison, cette approche ne fonctionne pas. Lorsque nous générons des miniatures, nous utilisons uniquement des images téléchargées, mais les images liées dans une balise d’ancrage ne sont pas téléchargées.
Une alternative ici pourrait être d’ajouter au cœur quelque chose de similaire à ce que @merefield a recommandé, mais encapsulé comme un oneboxer générique pour les iframes à chargement différé. Peut-être ajouter un nouveau réglage de site lazy_loaded_iframes, et le onebox peut initialement afficher l’image de la balise OG (qui devrait être capturée par les miniatures), et lorsqu’elle est cliquée, un peu de JS remplace l’image par l’iframe correct (similaire au remplacement de l’iframe Youtube).
Un détail délicat ici est que l’image utilisée et l’iframe doivent avoir la même hauteur, sinon cela peut introduire des sauts indésirables lors du défilement/de la navigation dans les publications.