Le miniature sono mancanti per i nostri embed esterni quando si utilizzano le miniature degli argomenti

Stiamo lanciando un forum per il nostro prodotto, i cui embed esterni funzionano già con OneBox dopo aver consentito gli Iframe da noi.

Un link diretto a un embed, viene trasformato ordinatamente nel risultato del nostro endpoint oembed.
Ora, la nostra preoccupazione principale è che vorremmo che le miniature apparissero quando Topic List Thumbnails è attivo. Non sono sicuro del motivo per cui la miniatura non viene rilevata.

Dovremmo aggiungere un’integrazione a lib/onebox/engine?

Da aggiungere, il comportamento predefinito funziona per lo più oggi, a parte il mancato supporto per i nostri embed dinamici. Vorremmo caricare JS invece di un Iframe. Ammesso che ci sia una soluzione diversa, ovvero ridimensionare opzionalmente l’iframe con un po’ di JS, non abbiamo in programma di implementare genericamente questo per gli oEmbed nel breve termine.

Sono a conoscenza di Using onebox images for topic thumbnails - #20 by david, che non ho trovato utile nel mio caso.

1 Mi Piace

Dopo alcune discussioni con il team di Discourse via email, sto aggiornando qui.

La scoperta principale è che le miniature non vengono caricate se un link che diventa un onebox viene renderizzato come un iframe.

Ciò significa che il link:

https://app.everviz.com/embed/N0dDTJaOQ

Renderizzerà o non renderizzerà una miniatura a seconda che gli iframe siano consentiti dal dominio (allowed iframes). La soluzione a questo è in qualche modo iniettare un iframe nel post. Ho creato un plugin che fa proprio questo e si assicura che a display: none sia impostato sull’immagine, per evitare che appaia nel post.

Immagino sia possibile generalizzare questo a:

  1. Per tutti i onebox generici, caricare silenziosamente e nascondere un’immagine accanto ad esso se get_oembed.thumbnail_url esiste.
  2. Probabilmente una soluzione migliore, aggiungere supporto generale per l’estrazione di get_oembed.thumbnail_url e associarlo al post, senza che faccia parte dell’area cooked stessa.

Luoghi pertinenti:

  1. https://oembed.com/
  2. discourse/lib/onebox/engine at main · discourse/discourse · GitHub
  3. discourse/lib/onebox/engine/standard_embed.rb at main · discourse/discourse · GitHub

Non sono molto soddisfatto di questo comportamento modale, ovvero, allowed iframes è abilitato o no? Sarebbe bello se Discourse estraesse e utilizzasse tutte le proprietà da un dato endpoint oembed quando gli invia per la prima volta una GET.

Aggiornamento

Ho avuto l’idea di utilizzare l’API dei plugin lato client per caricare un’immagine nel post.

api.decorateCooked($elem => {
    $elem[0].querySelectorAll('.my-iframe')
    .forEach(function (iframe) {

      //lavoro

      iframe.insertAdjacentElement('beforebegin', thumbnail);
    });

  }, {id: 'unique_string'});

Ma Discourse non rileva nulla.

Sembra che stia succedendo una delle due cose:

  1. Siamo in ritardo e Discourse ha già eseguito il recupero e la generazione delle miniature.
  2. Ci mancano alcuni attributi sulla nostra immagine che causano il mancato funzionamento del meccanismo di generazione delle miniature.

Speriamo sia quest’ultima. Una cosa da notare qui è che l’immagine non viene mai caricata nella nostra istanza Discourse, ma semplicemente referenziata dal nostro server.

Hai provato questo? Scrivere un onebox specifico per il tuo caso potrebbe permetterti di fornire un’immagine onebox al post cotto? Quindi le miniature funzionerebbero automaticamente.

Noto che i onebox di Youtube, credo, sono contenuti statici in-site, finché non fai clic sul pulsante di riproduzione e quindi mostra un iframe. Il contenuto presentato prima del clic include un’immagine che viene quindi acquisita e ridimensionata. Ovviamente Discourse non può leggere da un iframe, quindi questa tecnica è un buon approccio.

Noto che il tuo esempio include un og:image nei tag di intestazione che è perfetto.


Il mio suggerimento è di allontanarsi da javascript qui e cucinare in Rails.

L’unico svantaggio di questo sarà che la tua immagine sarà statica finché non ricostruirai il Post, assumendo che anche l’immagine di destinazione venga aggiornata. Pertanto, se speri di mostrare una miniatura che cambia dinamicamente, potresti dover essere ancora più creativo.

3 Mi Piace

Ciao Robert, grazie per la tua risposta!

Scrivere un plugin è stata la prima cosa che ho fatto, e ha funzionato fantasticamente, non importa se l’ho messo in lib/onebox/engine o come plugin separato. Il problema è che siamo su un piano ospitato, dove i plugin non sono comprensibilmente permessi sui piani multi-tenant, il che esclude la personalizzazione in Rails.

Questo ci lascia con una delle tre opportunità:

  1. Eseguire la nostra istanza
  2. Fare un hack sul lato client, se potesse funzionare
  3. Inviare una PR a Discourse principale

Per formulare una domanda qui. Non sono sicuro se un tale contributo sarebbe accettato, specialmente se carica un’immagine solo per nasconderla. Come potrei scoprirlo?

2 Mi Piace

Potrei aver fatto qualche progresso. Guardando:\n\napi.composerBeforeSave\n\nIl cui callback è gestito in composer.js. Da lì, possiamo vedere che i metodi createPost e editPost chiamano getCookedHtml, che più o meno restituisce semplicemente l’innerHTML di:\n\njs\nconst editorPreviewNode = document.querySelector(\n \"#reply-control .d-editor-preview\"\n);\n\n\nCiò significa che se modificassimo questo selettore, potremmo essere in grado di forzare l’inserimento di un HTML equivalente a un normale caricamento di immagini. Tuttavia, sembra che la modifica di editorPreviewNode.innerHTML non produca alcun cambiamento.\n\nPerché è così, o cosa posso modificare in composerBeforeSave per fare qualcosa di simile?

Questo ha senso per me, penso che saremmo aperti ad accettare una PR al core per un motore onebox per everviz.com (o servizi di visualizzazione simili). Tuttavia, eviterei di inserire e nascondere un’immagine nel post cooked, c’è un’opzione più leggera. Il post processor di Discourse cercherà un caricamento per i seguenti elementi:

Quindi aggiungere la miniatura come ancora sotto l’iframe potrebbe funzionare? Potresti mantenerla visibile o nasconderla usando una classe come “hidden”.

5 Mi Piace

Ciao, Penar, grazie per la risposta.

Usando

  <div>
   #{get_oembed.html}
   <a class="hidden" href="https://app.everviz.com/thumbnails/#{match[:uuid]}.png"></a>
  </div>

come mio metodo to_html, produce il seguente output:

  <div class="...">
    <iframe>
      ...
    </iframe>
    <a class="hidden" href="https://app.everviz.com/thumbnails/[...].png" rel="nofollow ugc noopener"></a>
  </div>

Collegare un’immagine direttamente, produce:

<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>

Facendo sembrare che il motore image_onebox.rb venga eseguito sull’input solo se un’immagine è collegata al di fuori del contesto di un diverso motore onebox.

La conseguenza di ciò è che la tecnica suggerita non funziona al momento ed è necessario collegare e nascondere un’immagine, o modificare Discourse per tenerne conto.

Sarebbe accettabile una PR in questo caso per inserire e nascondere un’immagine? O è necessario fare qualcosa di più complesso?

Non sono sicuro di capire, questo non dovrebbe passare attraverso il motore di image onebox.

Questo:

<a class="hidden" href="https://app.everviz.com/thumbnails/[...].png" rel="nofollow ugc noopener"></a>

non funziona? Cioè, quando un primo post in un argomento ha questo nella sua colonna “cooked”, l’immagine viene riconosciuta come anteprima dopo l’elaborazione?

2 Mi Piace

Mi scuso per la confusione, l’output assomigliava al motore onebox dell’immagine.

Il link suggerito (correttamente dotato di un UUID) non funziona. Né questa immagine che ho estratto da Google (e che sto qui scrivendo come tag di ancoraggio. Se l’incollaggio di un HTML equivale ad avere un output onebox, ciò spiegherebbe i nostri risultati.


https://static-cse.canva.com/blob/1031184/1600w-wK95f3XNRaM.jpg

1 Mi Piace

Ah, ho sbagliato, hai ragione, quell’approccio non funziona. Quando generiamo le miniature, utilizziamo solo immagini scaricate, ma le immagini collegate in un tag di ancoraggio non vengono scaricate.

Un’alternativa qui potrebbe essere quella di aggiungere al core qualcosa di simile a quanto raccomandato da @merefield, ma incapsulato come un oneboxer generico per iframe a caricamento lazy. Forse aggiungere una nuova impostazione del sito lazy_loaded_iframes, e il onebox può inizialmente generare l’immagine dal tag OG (che dovrebbe essere rilevata dalle miniature), e quando viene cliccata, un po’ di JS sostituisce l’immagine con l’iframe corretto (simile alla sostituzione dell’iframe di Youtube).

Un dettaglio complicato qui è che l’immagine utilizzata e l’iframe dovrebbero avere la stessa altezza, altrimenti ciò può introdurre salti indesiderati durante lo scorrimento/navigazione dei post.

3 Mi Piace