Estamos lanzando un foro para nuestro producto, cuyos embeds externos ya funcionan con OneBox después de permitir Iframes desde nosotros.
Un enlace directo a un embed, se transforma elegantemente en el resultado de nuestro endpoint oembed.
Ahora, nuestra preocupación principal es que nos gustaría que aparecieran miniaturas cuando Topic List Thumbnails esté activo. No estoy seguro de por qué no se capta la miniatura.
Para añadir, el comportamiento predeterminado funciona en su mayor parte hoy en día, salvo por no admitir nuestros embeds dinámicos. Nos gustaría cargar JS en lugar de un Iframe. Es cierto que existe una solución diferente, que es redimensionar opcionalmente el iframe con algo de JS, pero no planeamos implementar eso de forma genérica para oEmbeds a corto plazo.
Tras una discusión con el equipo de Discourse por correo electrónico, actualizo aquí.
El principal descubrimiento es que las miniaturas no se cargan si un enlace que se convierte en un onebox se renderiza como un iframe.
Esto significa que el enlace:
https://app.everviz.com/embed/N0dDTJaOQ
Renderizará o no una miniatura dependiendo de si los iframes están permitidos desde el dominio (allowed iframes). La solución a esto es inyectar de alguna manera un iframe en la publicación. He creado un plugin que hace esto y se asegura de que se establezca display: none en la imagen, para evitar que aparezca en la publicación.
Imagino que es posible generalizar esto a:
Para todos los oneboxes genéricos, cargar y ocultar silenciosamente una imagen junto a él si get_oembed.thumbnail_url existe.
Probablemente una mejor solución, añadir soporte general para extraer get_oembed.thumbnail_url y asociarlo con la publicación, sin que sea parte del área cooked en sí.
No estoy muy contento con este comportamiento modal, es decir, ¿está habilitado allowed iframes o no? Sería bueno que Discourse extrajera y utilizara todas las propiedades de un punto final oembed dado cuando lo llama por primera vez con un GET.
Parece que está sucediendo una de estas dos cosas:
Llegamos tarde y Discourse ya ha recuperado y generado la miniatura.
Nos faltan algunos atributos en nuestra imagen que hacen que el mecanismo de generación de miniaturas no la detecte.
Esperemos que sea lo último. Una cosa a tener en cuenta aquí es que la imagen nunca se carga en nuestra instancia de Discourse, sino que simplemente se hace referencia a ella desde nuestro propio servidor.
¿Has probado esto? Escribir un onebox específico para tu caso podría permitirte proporcionar una imagen de onebox a la publicación cocinada. Entonces las miniaturas funcionarían automáticamente.
Observo que los onebox de Youtube, creo, son contenido estático en el sitio, hasta que haces clic en el botón de reproducir y luego muestra un iframe. El contenido presentado antes del clic incluye una imagen que se capta y luego se convierte en miniatura. Obviamente, Discourse no puede leer desde un iframe, por lo que esta técnica es un buen enfoque.
Observo que tu ejemplo incluye una og:image en las etiquetas de encabezado, lo cual es perfecto.
Mi sugerencia es que te alejes de javascript aquí y cocines en Rails.
La única desventaja de esto será que tu imagen será estática hasta que reconstruyas la publicación, asumiendo que la imagen de destino también se actualiza. Por lo tanto, si esperas mostrar una miniatura que cambie dinámicamente, podrías tener que ser aún más creativo.
Escribir un plugin fue lo primero que hice, y funcionó fantásticamente, sin importar si lo ponía en lib/onebox/engine o como un plugin separado. La advertencia es que estamos en un plan alojado, donde los plugins, comprensiblemente, no están permitidos en planes multi-inquilino, lo que deja la personalización en Rails fuera de discusión.
Eso nos deja con una de las tres oportunidades:
Ejecutar nuestra propia instancia
Hackear algo del lado del cliente, si pudiera funcionar
Para plantear una pregunta aquí. No estoy seguro de si tal contribución sería aceptada, especialmente si carga una imagen solo para ocultarla. ¿Cómo podría averiguarlo?
Es posible que haya logrado algún tipo de progreso en esto. Mirando a:
api.composerBeforeSave
Cuya devolución de llamada se maneja en composer.js. Desde allí, podemos ver que los métodos createPost y editPost llaman a getCookedHtml, que más o menos simplemente devuelve el innerHTML de:
Lo que significa que si modificáramos este selector, podríamos forzar la entrada de algún HTML que sea equivalente a una carga de imagen normal. Sin embargo, parece que modificar editorPreviewNode.innerHTML no produce ningún cambio.
¿Por qué es esto, o qué puedo modificar en composerBeforeSave para hacer algo similar?
Esto tiene bastante sentido para mí, creo que estaríamos abiertos a aceptar una PR para el núcleo para un motor de onebox para everviz.com (o servicios de visualización similares). Sin embargo, evitaría insertar y ocultar una imagen en la publicación cooked, hay una opción más ligera. El procesador de publicaciones de Discourse buscará una carga de los siguientes elementos:
Entonces, ¿añadir la miniatura como un ancla debajo del iframe podría funcionar? Podrías mantenerla visible, u ocultarla usando una clase como “hidden”.
Haciendo que parezca que el motor image_onebox.rb se está ejecutando en la entrada solo si se enlaza una imagen fuera del contexto de otro motor onebox.
La consecuencia de esto es que la técnica sugerida no funciona por ahora y es necesario enlazar y ocultar una imagen, o modificar Discourse para tener esto en cuenta.
¿Sería aceptable una PR en este caso para insertar y ocultar una imagen? ¿O es necesario hacer algo más complejo?
No estoy seguro de seguir, esto no debería pasar por el motor de onebox de imágenes.
¿Esto:
<a class="hidden" href="https://app.everviz.com/thumbnails/[...].png" rel="nofollow ugc noopener"></a>
no funciona? Es decir, cuando la primera publicación en un tema tiene esto en su columna “cooked”, ¿la imagen se reconoce como miniatura después del procesamiento?
Disculpas por la confusión, la salida se parecía al motor onebox de imágenes.
El enlace sugerido (adecuadamente adaptado con un UUID) no funciona. Tampoco lo hace esta imagen que extraje de Google (y que aquí estoy escribiendo como una etiqueta de anclaje. Si pegar algo de HTML es equivalente a tener una salida onebox, esto explicaría nuestros resultados.
Ah, lo siento, tienes razón, ese enfoque no funciona. Cuando generamos miniaturas, usamos solo imágenes descargadas, pero las imágenes enlazadas en una etiqueta de anclaje no se descargan.
Una alternativa aquí podría ser añadir al núcleo algo similar a lo que @merefield recomendó, pero envuelto como un oneboxer genérico para iframes de carga diferida. Quizás añadir una nueva configuración del sitio lazy_loaded_iframes, y el onebox puede generar inicialmente la imagen de la etiqueta OG (que debería ser capturada por las miniaturas), y cuando se hace clic, un poco de JS reemplaza la imagen con el iframe correcto (similar al reemplazo del iframe de YouTube).
Un detalle complicado aquí es que la imagen utilizada y el iframe deben tener la misma altura, de lo contrario, esto puede introducir saltos no deseados al desplazarse/navegar por las publicaciones.