Ordre de priorité des composants de thème

Je remarque que les composants de thème semblent s’exécuter dans l’ordre de leur installation. Par exemple, si j’installe A puis B, les scripts de A sont inclus dans les pages générées avant ceux de B.

Puis-je m’appuyer là-dessus ? Existe-t-il une vue quelque part qui affiche cet ordre ? Lors de l’affichage des composants installés, ils semblent être listés par ordre alphabétique.

Je préférerais un moyen d’exécuter explicitement des actions avant un composant particulier. Dans mon cas, je souhaite exécuter des actions avant le composant TOC (lié à ce sujet). D’après la documentation Ember, il semble que les fonctions planifiées pour une file d’attente donnée soient exécutées dans l’ordre de leur planification. Cela rend l’ordre de planification essentiel dans mon cas.

2 « J'aime »

Ce n’est pas quelque chose sur quoi vous pouvez compter ; ce sont plutôt les bonnes API qui devraient gérer cela. Vous pouvez utiliser des initialisateurs Ember pour le contrôler dans une certaine mesure. @eviltrout pourrait avoir des idées précises si vous pouvez coller l’exemple de code que vous essayez de planifier.

7 « J'aime »

Voici le code que j’exécute :

<script type="text/discourse-plugin" version="0.8">
    const { run } = Ember;
    
    api.decorateCooked($elem => {
        run.scheduleOnce("actions", () => {
          // Doit s'exécuter avant les actions planifiées par le composant TOC.
        });
    })

Le composant TOC utilise la même interface pour planifier ses actions.

Selon la documentation d’Ember, l’interface de planification :

Ajoute la cible/méthode passée ainsi que tout argument facultatif à la file d’attente nommée pour être exécutée à la fin de la RunLoop.

Ce terme « ajouter » suggère un ordre FIFO pour les actions planifiées. Par conséquent, l’ordre dans lequel l’appel à schedule est effectué est ici critique.

J’ai remarqué que, lors de ma tentative de réorganiser l’exécution du JavaScript en désinstallant puis en réinstallant le composant TOC (ce qui a apparemment l’heureux effet secondaire d’exécuter le JavaScript du TOC en dernier), les règles CSS sont désormais appliquées dans cet ordre :slight_smile:

Je pense que la question de l’ordre de placement du code des composants de thème est très importante. Si l’ordre est officiellement « indéfini », les composants ne peuvent espérer interagir.

Peut-être que l’interaction entre les composants n’est pas un objectif. Mais je pense qu’avec une heuristique d’ordre (par exemple, déclarer qu’un fichier de composant doit apparaître avant ou après le fichier d’un autre composant portant le même nom — cela serait probablement défini dans about.json), ce problème n’est pas si difficile à résoudre.

Pour ma part, je commence à penser que le fork du composant TOC est la bonne approche, compte tenu de ce que je tente de réaliser.

Chaque fois que vous créez ou installez un thème ou un composant, Discourse lui attribue un identifiant. Si vous visitez la page de ce composant, vous devriez voir cet identifiant dans l’URL (le nombre à la fin).

identifiant du composant dans l'URL

Lorsque ce composant est ajouté à votre thème, son ordre d’exécution semble être basé sur son identifiant — de manière très basique (en effectuant un console.log sans aucun report). Ainsi, 233 s’exécutera avant 234, et ainsi de suite.

Cela fonctionne pour la plupart des cas car les modifications ultérieures sont généralement ajoutées dans de nouveaux composants, ce qui fait que tout fonctionne simplement.

À long terme, nous pourrions faire en sorte que l’ordre respecte celui de la liste des composants que vous avez ajoutés au thème.

mais cela ne figure sur aucune feuille de route pour le moment.

Ce dont vous avez vraiment besoin, c’est d’un ordre d’initialisation. Je ne pense pas que vous puissiez le faire sauf si vous déplacez votre code vers la nouvelle méthode de création de JS de thème. Cette méthode vous permet de donner un nom et un ordre d’exécution à l’initialiseur. Par exemple, disons que j’ai ce fichier

/javascripts/discourse/initializers/initialize-for-foo.js

et qu’il ressemble à ceci

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "foo",
  initialize() {
    withPluginApi("0.8.7", api => {
      console.log("foo")
    });
  }
}

et que j’ai un autre initialiseur qui ressemble à ceci

/javascripts/discourse/initializers/initialize-for-bar.js

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "bar",
  initialize() {
    withPluginApi("0.8.7", api => {
      console.log("bar")
    });
  }
}

Si je veux m’assurer que bar s’exécute après foo, je peux ajouter un argument after: à celui-ci, ce qui garantira qu’il s’exécute après le nom de l’initialiseur que je passe. Ainsi, pour faire en sorte que bar s’exécute après foo, je ferais ceci dans

/javascripts/discourse/initializers/initialize-for-bar.js

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "bar",
+ after: "foo",
  initialize() {
    withPluginApi("0.8.7", api => {
      console.log("bar");
    });
  }
};
6 « J'aime »

Merci beaucoup pour ces indications détaillées ! Étant donné mes problèmes liés au composant TOC (auxquels vous avez également répondu – merci encore), j’ai bifurqué le TOC et déplacé le code dépendant dans ce composant. Cela concerne les identifiants des titres, en particulier la nécessité de les contrôler depuis l’article pour gérer les doublons et les conflits avec les identifiants des éléments de base.

Compte tenu de ce que je fais avec la documentation, dont une partie s’écarte un peu des sentiers battus, je pense que c’est la bonne approche.

1 « J'aime »