Comment ajouter des blocs spécifiques JS (et CSS) - La manière _droite_?

9

J'ai donc passé littéralement des heures sur des heures à googler, lire, étudier les ect, mais personne (pas même Alan Storm!) Ne m'a expliqué cela. Il semble que l'ensemble de l'Internet soit intéressé par l'ajout de JS ou CSS à une page particulière de Magento 2, mais ce que je recherche, c'est l'ajout de JS / CSS à un bloc particulier .

Alors, voici ma question en bref:

Quelle est la meilleure façon d'ajouter JS (et en plus CSS) à un bloc particulier , de sorte que si le bloc est présent sur la page (*) le JS / CSS est chargé, si le bloc n'est pas là, pas de CSS / JS? ?

* Cela signifie que tout bloc peut être mis en place, sur une page / modèle via layout.xml, sur une page personnalisée de mon module, via la méthode toHtml d'un bloc / page ou surtout un bloc intégré dans un WYSIWYG d'une catégorie / description du produit / Bloc CMS / Page CMS.

J'ai lu BEAUCOUP de grands articles d' Alan (bravo encore à ce gars !!), sans parler des rames d'autres articles autour de cela , mais j'ai l'impression que tout le monde veut ajouter à une page, une page spécifique, pas où jamais le bloc est utilisé.

Je sens que je suis familier avec les différentes techniques, mais je pourrais manquer quelque chose ici, donc j'aimerais un consensus de la communauté, ainsi que peut-être un petit panneau de signalisation pour tous les front enders jusqu'à des développeurs de pile complets là-bas à la recherche des questions similaires et réfléchir aux options que je suis.

Auparavant, dans Magento 1, je regardais le constructeur de blocs, obtenais la disposition, obtenais la référence de tête et y appelais addJs / addCss, ou si possible utilisais les méthodes dans le layout.xml. Cela signifierait que JS a été "ajouté" à la liste de ressources sur le constructeur de blocs (avant que le niveau du thème ne produise le bloc de tête). Mais cela ne semble pas possible maintenant.

J'ai lu comment ajouter JS / CSS (ce n'est pas un simple "comment puis-je ???" c'est plus simple "quelle est la bonne façon / mag2 ???")) et je connais ces techniques:

  • /view/[area]/layout/[default/page_id].xml technique, en utilisant les <head></head>éléments racines
  • Ajout d'un bloc Head à mon module, ajouté dans head.additional, avec une sorte de logique pour savoir si mon bloc est chargé
  • en utilisant les \ Asset \ GroupedCollection et \ Asset \ Repository Objects pour injecter depuis le custructor d'une page / Template (cela ne semble cependant pas fonctionner avec des blocs), potentiellement l'ordre de chargement ??
  • Utiliser RequireJS et appliquer une configuration requireJS à mon module

Ai-je raté quelque chose ??

On pense que la bonne façon serait d'utiliser la bibliothèque RequireJS, et soit des attributs x-magento-init, soit juste un script avec une require("my_module", function(){ ... })syntaxe dans un script en ligne. Mais cela me semble maladroit? Je devrais mettre en place des scripts pour charger des scripts, je suis obligé d'inclure au moins une partie de mon JS, mais cela semble la façon la plus suspecte de dire "voici mon bloc, maintenant besoin de moi JS", en insérant ceci dans mon phtml.

Je voudrais cependant vraiment pouvoir le faire via PHP, en tant que programmeur backend / stack, j'aimerais idéalement encapsuler le JS et (idéalement) permettre à mon équipe front-end d'écrire cela comme ils le souhaitent. En bref, prenez soin du chargement (Back End Dev to Frond End Dev "heres the phtml, override in the theme if you like, heres the js file, its depend libs and heres the css for the block").

Cela suggère la __constructméthode avec les dépendances injectées sur le système des actifs. Je ne peux cependant pas faire fonctionner cela, cela semble être confirmé dans l'article rapide d'Alan Storms ici: Quickies de Magento: Magento 2: Ajout de fichiers d'actifs frontaux par programme

Notez la signature "Donc, toute idée de créer des blocs qui portent leurs ressources frontales avec eux est par la fenêtre." ... déception :(

Merci les gars d'avoir pris le temps de lire et de réfléchir . J'ai hâte d'entendre vos réponses!

PS> Évidemment, c'est StackExchange, donc je vais marquer la réponse comme le meilleur cours pour ce que j'essaie de réaliser (bloquer le chargement de ressources spécifiques) mais je m'efforcerai également de répertorier comme références au bas de mon message toutes les réponses qui ajoutent à la discussion ou suggèrent une solution solide!

cygnus digital
la source

Réponses:

5

Pour js, cela devrait être facile car magento 2 utilise require.js.
Cela signifie donc que vous pouvez inclure un js à la volée lorsque vous en avez besoin.

Un bloc doit être rendu (dans la plupart des cas) par un modèle.
Vous devez donc ajouter ceci dans votre modèle:

<script type="text/javascript">
    require([
        "jquery",
        .... //any other js dependencies you have
        "Namespace_Module/js/filename_here"
    ], function(){
        //some js code here. 
        //if you don't need any additional js code just have an empty function
    });
</script>

Créez maintenant votre fichier js view/adminhtml|frontend/web/js/filename_here.jsoù tout votre code js est présent.

require.js saura comment récupérer votre fichier à sa demande.

Pour les fichiers CSS, je ne sais pas si c'est possible.
Les fichiers css doivent aller dans la headsection de la page, mais par exemple si vous avez votre bloc à l'intérieur du contenu d'une page cms comme ceci {{block class="..." template="..."}}, lorsque le contenu de la page cms doit être traité, le html jusqu'à ce point est déjà rendu vous ne pouvez donc rien ajouter d'autre au bloc de tête via php. Vous pouvez essayer de l'ajouter dans le modèle comme<style... mais ce n'est pas ce que vous voulez (je suppose).

Marius
la source
Merci Marius, j'explore la route requireJS comme l'une des possibilités que j'ai énumérées ci-dessus, mais merci pour l'exemple consise! Je suis d'accord cependant, il n'offre pas de solution au problème CSS, mais cela peut être un point muet en raison de l'utilitaire de compilation Less de Magento. En outre, c'est un peu abstrait mais je suppose que nous pourrions utiliser requireJS pour charger notre JS qui à son tour pourrait ajouter un lien vers la feuille de style au DOM, son asyncrone au moins !!!
cygnus digital
En fait, je trouve cela sur les pages requirejs, comment charger CSS avec RequireJS! : requirejs.org/docs/faq-advanced.html#css
cygnus digital
@cygnusdigital. Agréable. Donc problème résolu :)
Marius
Salut Marius, eh bien oui et non, c'est certainement un bon candidat pour la solution, elle correspond aux exigences, donc je vous remercie pour votre contribution, mais je recherche des discussions et des alternatives. Peut-être que c'est juste moi étant un dinosaure mais je pense que c'est plus compliqué d'avoir un chargement JS / CSS dans un constructeur, c'est-à-dire. "si le bloc est construit / inclus, ajoutez-le à la tête." : DI ne me demande pas s'il est possible d'ajouter conditionnellement au bloc head.additional à la volée. (c'est-à-dire ajouter un bloc head de mon module à head.additional au stade du constructeur de bloc).
cygnus digital
vous pouvez le faire avec des blocs réguliers qui sont ajoutés via des fichiers de mise en page, mais comme je l'ai expliqué, vous ne pouvez pas le faire pour les blocs inclus dans le contenu de la page via des {{block}}directives, car la section head est déjà rendue lorsque la classe de bloc est instanciée.
Marius