Come usare api.onPageChange con api.createWidget?

Ciao, sto cercando di aggiungere un banner immagine a tutte le pagine che sceglie casualmente tra due immagini casuali. Funziona quando lo aggiungo alla sezione Head del mio tema e ricarico la homepage:\n\nEDIT: Il mio tentativo che si avvicina di più alla soluzione è qui:\n https://meta.discourse.org/t/how-to-use-api-onpagechange-with-api-createwidget/242744/2\n\nHai qualche idea di cosa sto sbagliando? Grazie!

Questo è il mio tentativo più corretto. Quando lo eseguo senza la funzione api.onPageChange(() funziona, ma non randomizza l’immagine finché non aggiorno la pagina con un refresh forzato. Quando aggiungo la funzione api.onPageChange(() non viene visualizzata alcuna immagine. Qualche consiglio su cosa sto sbagliando?

<script type="text/discourse-plugin" version="0.8">

api.onPageChange(() => {
        doStuff();
});

function doStuff() {

const h = require("virtual-dom").h;

let banners = new Array();
banners[0]="https://example.com/uploads/default/original/1X/9d9762a4129c78c478d14ff857c3bd1f2be0322a.jpg";
banners[1]="https://example.com/uploads/default/original/1X/04ede2abd9ac117c64988a5b0bcf033474381527.jpg";

let GoTo = new Array();
GoTo[0]="https://google.com";
GoTo[1]="https://brave.com";

let Number = Math.round(1 * Math.random());
let TheLink = GoTo[Number];
let TheImage = banners[Number];

  api.createWidget("top-banner-widget", {
    tagName: "div.top-banner",
    html() {
    return h("div#top-banner", [
      h(
        "a.custom-ad-link",
        { href: TheLink },
        h("img", { src: TheImage })
      )
    ]);
    }
  });
}
</script>

<script type="text/x-handlebars" data-template-name="/connectors/above-main-container/inject-widget">
  {{mount-widget widget="top-banner-widget"}}
</script>
1 Mi Piace

Penso che il pezzo mancante fosse attivare un re-render del widget… se ricordo bene i widget si ri-renderizzano all’interazione, quindi ho aggiunto this.scheduleRerender(); per farlo ri-renderizzare al cambio pagina.

Questo funziona per me localmente:

api.createWidget("top-banner-widget", {
    tagName: "div.top-banner",

    html() {
        let Number = Math.round(1 * Math.random());
        
        let banners = new Array();
        banners[0]="https://placekitten.com/500/500";
        banners[1]="https://placekitten.com/500/300";

        let GoTo = new Array();
        GoTo[0]="https://google.com";
        GoTo[1]="https://brave.com";
  
        let TheLink = GoTo[Number];
        let TheImage = banners[Number];
        
        api.onPageChange(() => {
            this.scheduleRerender();
        });
  
        return h("div#top-banner", [
          h(
            "a.custom-ad-link",
            { href: TheLink },
            h("img", { src: TheImage })
          )
        ]);
    }
});
5 Mi Piace

Fantastico! Grazie mille, non ci sarei mai arrivato!

Ecco il codice completo dell’Head per il componente del tema:

<script type="text/discourse-plugin" version="0.8">

const h = require("virtual-dom").h;

api.createWidget("top-banner-widget", {
    tagName: "div.top-banner",

    html() {
        let Number = Math.round(1 * Math.random());
        
        let banners = new Array();
        banners[0]="https://example.com/uploads/default/original/1X/9d9762a4129c78c478d14ff857c3bd1f2be0322a.jpg";
        banners[1]="https://example.com/uploads/default/original/1X/04ede2abd9ac117c64988a5b0bcf033474381527.jpg";

        let GoTo = new Array();
        GoTo[0]="https://google.com";
        GoTo[1]="https://brave.com";
  
        let TheLink = GoTo[Number];
        let TheImage = banners[Number];
        
        api.onPageChange(() => {
            this.scheduleRerender();
        });
  
        return h("div#top-banner", [
          h(
            "a.custom-ad-link",
            { href: TheLink },
            h("img", { src: TheImage })
          )
        ]);
    }
});

</script>

<script type="text/x-handlebars" data-template-name="/connectors/above-main-container/inject-widget">
  {{mount-widget widget="top-banner-widget"}}
</script>
1 Mi Piace

Vale la pena menzionare anche che questo potrebbe essere un componente Ember. A lungo termine, inizieremo a fare più affidamento su Ember che sul nostro sistema di widget personalizzato. Stiamo ancora lavorando agli aggiornamenti di Ember, quindi la nostra documentazione sulla personalizzazione di Discourse è un po’ indietro su questo.

Ho messo insieme un componente tematico che mostra un esempio di come questo può funzionare come componente Ember: GitHub - awesomerobot/discourse-component-example

Ci sono 3 file importanti qui:

  1. Il connettore (/javascripts/discourse/connectors/custom-header-banner-connector.hbs)

  2. Il componente (/javascripts/discourse/components/custom-header-banner.js)

  3. Il template del componente (/javascripts/discourse/templates/components/custom-header-banner.hbs)

Il connettore è dove viene aggiunto il componente, quindi deve contenere solo <CustomHeaderBanner />. Il componente è dove rileviamo i cambi di pagina (cambi di route) e impostiamo la logica per quale immagine/link appare casualmente. Il template del componente è come i dati vengono presentati in HTML.

3 Mi Piace

Ah, bene a sapersi, molte grazie anche per questo. Confermo che funziona quando installato dal tuo repository come componente del tema sul mio sito.

In alternativa, potrei aggiungerlo manualmente come componente del tema Ember tramite l’interfaccia Personalizza > Installa > Crea Nuovo e poi Modifica CSS / HTML? Ciò renderebbe più facile cambiare rapidamente immagini e link secondo necessità. Presumo che il contenuto di custom-header-banner.js andrebbe sotto Head, e poi \u003cCustomHeaderBanner /\u003e in After Header o Body, ma non sono sicuro dove aggiungere il contenuto di custom-header-banner.hbs.

1 Mi Piace

È un po’ più complicato di così tradurre in un componente tema installato localmente, ma un modo per aggiungere un po’ di flessibilità a un tema remoto sarebbe utilizzare le impostazioni del tema (Add settings to your Discourse theme).

Ciò comporta l’aggiunta di un file settings.yml e l’aggiornamento di alcuni valori nel componente e/o nel template. Quindi ottieni le impostazioni sulla tua pagina di amministrazione del componente tema come questa:

Va bene anche attenersi all’implementazione del widget sopra e aggiornare tramite il pannello di amministrazione, ma tendiamo a consigliare l’uso di git quando possibile; è più facile da condividere se è necessario risolvere i problemi e rende facile tenere traccia delle modifiche.

1 Mi Piace

Eccellente, apprezzo molto la tua spiegazione paziente e chiara, è fantastico avere anche quell’opzione.

1 Mi Piace

Ciao di nuovo, sto cercando di capire il modo migliore per far apparire il widget solo su un URL specifico, come la homepage.

Il modo più semplice è utilizzare un plugin outlet che esiste solo sulla homepage, il che funziona per quello di cui ho bisogno per ora (in particolare, discovery-navigation-bar-above). Ma sono ancora curioso di sapere come farlo programmaticamente in un modo che sia sensibile all’URL specifico della pagina.

Ho trovato questo argomento molto utile, anche da @awesomerobot:

Ho provato ad adattarlo alla soluzione precedente in questo post:

        api.onPageChange((url) => {
            if (url === "/" || url === homeRoute ){
               this.scheduleRerender();
            }
        });

Ma questo fa comunque apparire l’immagine su tutte le pagine. Ho anche provato a inserire le mie variabili e il codice di selezione casuale all’interno della clausola if, ma non funziona affatto.

C’è anche la sezione <script type="text/x-handlebars" ... dell’esempio, ma sembra consentire solo HTML e non so come inserire le variabili da esso dallo script precedente.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.