Javascript dans un composant de thème

Je tente de créer un composant de thème pour l’aperçu des fichiers STL. Il existe une excellente bibliothèque JavaScript pour cela, mais je ne suis pas sûr de savoir comment l’intégrer dans un composant de thème.

Il s’agit de JavaScript standard, pas de ES6, ce qui signifie, je pense, que je ne peux pas simplement le placer dans le répertoire « javascripts » et l’importer, n’est-ce pas ? De plus, la bibliothèque semble dépendre d’une importation via une balise script.

Je peux donc créer une balise script et l’ajouter à l’en-tête du document, mais comment trouver le nom du fichier JS de la bibliothèque ? Par ailleurs, la bibliothèque est constituée de plusieurs fichiers JS et suppose qu’ils seront disponibles dans le même répertoire. Elle crée ensuite d’autres balises script pour charger le reste de la bibliothèque.

Ces fichiers doivent-ils donc être placés dans le répertoire « javascripts » ? Ou doivent-ils être traités comme des assets ? La chose la plus proche que je trouve pour faire quelque chose de similaire est le plugin discourse-math, mais si possible, je préférerais garder cela comme un composant de thème.

Cela semble montrer comment procéder pour un plugin : How to ship javascript library with plugin?
Je n’ai toujours rien trouvé pour un composant de thème.

Je ne sais pas, mais vous n’avez aucune bonne réponse !

La prochaine chose à examiner est… l’élément… concernant l’inclusion d’autres fichiers dans le composant de thème.

Je pense que certains des grands composants de thème sont à étudier. En gros, je crois que la structure des fichiers du composant de thème est identique et qu’Ember chargera simplement ces fichiers de thème de la même manière qu’un plugin.

Je ne pense pas, chaque composant obtient son propre répertoire virtuel, je crois. Quelque chose comme discourse/theme-10/… Donc pour charger des éléments depuis là, je dois au moins savoir quel est le répertoire d’une manière ou d’une autre.

1 « J'aime »

Les noms des assets semblent être accessibles uniquement en tant que variables, et les vrais noms sont de longs et compliqués numéros, donc cela ne fonctionnera pas non plus.
On a l’impression qu’il n’existe actuellement aucun moyen de réaliser cela sous forme de composant, je vais donc charger manuellement les fichiers JS via nginx et y accéder de cette manière pour l’instant. Cela signifie probablement que ce composant ne fonctionnera que pour moi, malheureusement.

Vous pouvez ajouter la balise script normale au fichier header.html dans votre composant de thème.

Le sideloading fonctionne !
Une fois. :frowning:

Si je navigue vers un autre sujet puis reviens au sujet contenant le STL, cela ne fonctionne plus. Je ne sais pas pourquoi car il n’y a aucune erreur dans la console JavaScript. J’ai vu un sujet quelque part plus tôt qui parlait d’étranges problèmes de chargement (onload), et étant donné que ces scripts utilisent onload, peut-être que cela y est lié ?

C’est vrai, mais le code viewstl n’est pas conçu pour être intégré.
Avec le chargement latéral, j’ai ajouté une balise script comme celle-ci dans common/head_tag.html :

<script src="/xi/viewstl/stl_viewer.min.js"></script>

(/xi/ est servi depuis nginx)

Discourse est une SPA. Vous ne pouvez pas simplement ajouter un script qui s’exécute au chargement de la page, car cela ne fonctionnera pas. Vous devrez vous connecter à nos points de terminaison API. Consultez le Guide du développeur pour les thèmes Discourse

Bon, je vais essayer de remplacer le chargement basé sur les balises script obsolètes par autre chose.

J’ai lu cette page plusieurs fois maintenant, mais je n’arrive toujours pas à la faire fonctionner.
J’essaie de charger three.js avec des instructions d’importation, mais il semble que, quoi que je fasse, cela se plaint de ne pas pouvoir trouver l’importation. La partie étrange est que je peux importer d’autres fichiers sans problème, et le message d’erreur est totalement inutile.

De toute façon, voici ce que j’obtiens, peut-être que quelqu’un pourra m’aider :

Voici l’importation qui ne fonctionne pas :

Et voici l’erreur que j’obtiens :

_application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74333 Une erreur s'est produite dans le thème/composant "STL previews" : Error: Could not find module `discourse/theme-17/three/build/three.module` imported from `discourse/theme-17/stlviewer/StlViewer`
    at h (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74612)
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74581
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74665
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74490
    at require (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74663)
    at h (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74616)
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74581
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74665
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74490
    at require (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74663)
(anonymous) @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74333
u @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74325
initialize @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74304
i.initialize @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:7723
(anonymous) @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:49335
e.each @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67724
e.walk @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67638
e.each @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67568
e.topsort @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67576
_runInitializer @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:49361
runInitializers @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:49333
_bootSync @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:47768
domReady @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:47668
n._run @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67275
n._join @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67251
n.join @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:66968
f @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:53760
(anonymous) @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:53864
l @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3776
c @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3844
setTimeout (async)
(anonymous) @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3882
u @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3510
fireWith @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3640
fire @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3648
u @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3510
fireWith @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3640
ready @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:4120
z @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:4130

Est-ce que ‘.’ est un séparateur de module magique ou quelque chose comme ça ?

Je suppose que ‘.’ est magique, car lorsque je renomme three.module.js en three_module.js, j’obtiens un problème complètement différent : je ne peux plus charger le thème. (Erreur 500)

J’ai également essayé d’importer three.js directement depuis un CDN avec une URL complète, mais cela ne semble pas fonctionner non plus…

Si vous avez simplement besoin d’un chargement à la demande (Just In Time) d’un asset JavaScript, comme c’est le cas ici où j’ai besoin de la bibliothèque D3, vous pouvez utiliser ce modèle avec Loadscript :

et un peu plus haut :

Loadscript renvoie une Promise, vous devez donc appeler .then sur le résultat. (Je ne suis pas certain, mais je suppose que le résultat est mis en cache implicitement, ce qui le rendra plus rapide lors de la deuxième exécution, etc.)

Comme vous pouvez le constater, vous pouvez les enchaîner pour charger plusieurs scripts les uns après les autres.

Notez que cela s’exécute à l’intérieur d’un composant Ember et est déclenché par le hook didInsertElement. Pour en savoir plus sur les composants Ember, consultez : Templates are HTML - Components - Ember Guides

Notez également que les scripts eux-mêmes sont stockés dans le répertoire javascripts/assets.

Je me suis inspiré du code de @j.jaffeux utilisé quelque part pour charger un tout autre script (merci Joffrey ! :+1:)

Voici un exemple Discourse :

Astuce : fouillez toujours les TC officiels et Pavilion ainsi que les plugins qui font quelque chose de similaire pour voir comment ils réalisent leurs fonctionnalités :).

4 « J'aime »

Intéressant, merci pour les pistes.
Je vais essayer d’utiliser loadScript et voir si cela peut résoudre mon problème.

2 « J'aime »

J’ai décidé d’essayer une approche plus simple.
Je crée simplement une iframe qui charge une page HTML capable d’exécuter toutes les opérations de script complexes nécessaires au bon fonctionnement de l’aperçu. Pour l’instant, ce n’est pas dans un format réutilisable, mais il serait relativement simple de créer un plugin pour cela.