Je suis nouveau sur le theming Discourse et emberjs, et je travaille actuellement sur un thème qui contient des éléments de navigation du site principal.
Les éléments de navigation JSON proviennent d’une requête ajax et je dois les afficher à 2 endroits.
Le 1er endroit est header-buttons:before. J’ai réussi à le faire avec api.decorateWidget et en déclenchant les appEventssite-header:force-refresh.
Le 2ème endroit est via pluginOutlet, below-site-header.
Je pense que je ne peux pas faire la même chose qu’au-dessus, en utilisant api.decorateWidget, car il s’agit d’un pluginOutlet et non d’un widget(?).
Mes questions sont :
Comment insérer manuellement le contenu ajax dans le pluginOutlet ?
J’aimerais aussi savoir comment compiler un virtual-dom à la volée après mon appel ajax ? Par exemple, la variable ci-dessus, headerNav, j’aimerais obtenir une représentation HTML compilée. Je ne suis pas sûr de la bibliothèque / fonction à utiliser.
Si possible, comment également ré-rendre un pluginOutlet ? Similaire à appEvents.trigger("site-header:force-refresh");
Dans un thème, vous ajouteriez votre fichier widget-name.js à un répertoire javascripts/discourse/widgets.
Il y a plus d’informations sur les widgets dans A tour of how the Widget (Virtual DOM) code in Discourse works, mais notez que nous allons progressivement abandonner les widgets, donc tout ce que vous apprendrez dans ce processus ne sera pas utile à long terme.
Gardez votre décorateur de widget tel quel, et créez un composant Ember séparé qui fait ce que vous voulez dans le plugin outlet. Nous avons progressivement abandonné les widgets au profit des composants Ember (qui constituent la majeure partie de Discourse).
Ce processus ressemblerait à ceci :
Créez un fichier JS et HBS (template) de composant dans le répertoire javascripts/discourse/components de votre thème.
component-name.js
component-name.hbs
Construisez votre composant Ember… malheureusement, cette étape consiste essentiellement à « apprendre Ember » (Guides Ember) … mais je pense que cela vous donnera une idée générale pour commencer :
Dans component-name.js :
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
const endpoint = settings.site_navigation_links_endpoint;
export default class ComponentName extends Component {
@tracked navLinks = null;
@action
async fetchNavLinks() {
try {
const response = await fetch(endpoint);
const data = await response.json(); // en supposant que ce soit du json
this.navLinks = data;
} catch (error) {
console.error("Échec :", error);
}
}
}
Cela appellera l’action fetchNavLinks chaque fois que le composant sera inséré (dans ce cas, lorsque vous visiterez le site Discourse et que l’application s’affichera). Chaque fois que navLinks sera mis à jour, le contenu du composant sera mis à jour car il s’agit d’une propriété suivie.
Si vous souhaitez mettre à jour les liens plus souvent qu’au rendu du composant, vous devrez ajouter une logique supplémentaire au JS ici… en vérifiant si la route (page) actuelle remplit certaines conditions, par exemple.
Ce composant serait ajouté à un plugin outlet en l’ajoutant à l’outlet dans javascripts/discourse/connectors/below-site-header/my-component-connector.hbs :
J’ai opté pour la deuxième approche, en utilisant un composant, car les widgets sont progressivement abandonnés. Mis à part la petite faute de frappe dans l’appel de fonction, dans le fichier .hbs, il devrait s’agir de {{did-insert this. fetchNavLinks}}, tout fonctionne !
C’est formidable de savoir que nous avons did-insert, c’est un grand soulagement ! J’ai maintenant terminé la tâche.