¿Cómo agregar JS específico de bloque (y CSS) - la forma _derecha_?

9

Así que he pasado literalmente horas en horas buscando en Google, leyendo, estudiando ect, pero nadie (¡ni siquiera Alan Storm!) Me lo ha explicado. Parece que todo Internet está interesado en agregar JS o CSS a una página en particular de Magento 2, pero lo que estoy buscando es agregar JS / CSS a un bloque en particular .

Entonces, aquí está mi pregunta en pocas palabras:

¿Cuál es la mejor manera de agregar JS (y adicionalmente CSS) a un bloque en particular , de modo que si el bloque está presente en la página (*) se carga JS / CSS, si el bloque no está allí, no hay CSS / JS? ?

* Esto significa que en cualquier momento se puede configurar un bloque, en una página / plantilla a través de layout.xml, en una página personalizada desde mi módulo, a través del método toHtml de un bloque / página o, lo más importante, un bloque incrustado en un WYSIWYG de una categoría / descripción del producto / CMS Block / CMS Page.

He leído MUCHOS artículos geniales de Alan (¡Felicitaciones de nuevo a este tipo!), Sin mencionar las resmas de otros artículos sobre esto , sin embargo, tengo la sensación de que todos quieren agregar a una página, una página específica, no donde sea que Se utiliza el bloque.

Siento que estoy familiarizado con las diversas técnicas, sin embargo, es posible que me falte algo aquí, así que me gustaría un consenso de la comunidad, así como tal vez un poco de una señal para todos los participantes en el frente a los desarrolladores de pila completa que buscan preguntas similares y reflexionando sobre las opciones como soy.

Anteriormente, en Magento 1, buscaba el constructor de bloques, obtenía el diseño, obtenía la referencia principal y llamaba a addJs / addCss allí, o si era posible, usaba los métodos en el layout.xml. Esto significaría que JS fue "agregado" a la lista de recursos en el constructor de bloques (antes de que el nivel del tema produjera el bloque principal). Pero esto no parece posible ahora.

He leído sobre cómo agregar JS / CSS (esto no es un simple "¿cómo lo hago ???" esto es más concisa "¿cuál es la forma correcta / mag2 ???") y estoy familiarizado con estos tecnicas:

  • /view/[areafont>/layout/[default/page_idfont>.xml técnica, utilizando los <head></head>elementos raíz
  • Agregar un bloque Head a mi módulo, agregado a head.additional, con algún tipo de lógica con respecto a si mi bloque está cargado
  • usando \ Asset \ GroupedCollection y \ Asset \ Repository Objects para inyectar desde el custructor de una página / plantilla (aunque esto no parece ork con bloques), ¿potencialmente el orden de carga?
  • Usando RequireJS y aplicando una configuración requireJS a mi módulo

¿Me he perdido algo?

Uno cree que la forma correcta sería usar la biblioteca RequireJS y los atributos x-magento-init o simplemente un script con una require("my_module", function(){ ... })sintaxis en un script en línea. ¿Pero esto me parece torpe? Tendría que configurar scripts para cargar scripts, me veo obligado a incorporar al menos algunos de mis JS, sin embargo, parece la forma más segura de decir "aquí está mi bloque, ahora necesita un poco de JS", introduciendo esto en mi phtml.

Sin embargo, realmente me gustaría poder hacer esto a través de PHP, como programador de backend / stack, idealmente me gustaría encapsular el JS y (idealmente) permitir que mi equipo front-end escriba esto como lo deseen. En resumen, cuide la carga (Back End Dev to Frond End Dev "aquí está el phtml, anule el tema si lo desea, del mismo modo, aquí está el archivo js, ​​sus libs dependientes y aquí está el CSS para el bloque").

Esto sugiere el __constructmétodo con dependencias inyectadas en el sistema de activos. Sin embargo, no puedo hacer que esto funcione, esto parece confirmarse en el artículo rápido de Alan Storms aquí: Magento Quickies: Magento 2: Agregar archivos de activos frontend mediante programación

Tenga en cuenta el cierre de sesión "Entonces, cualquier idea de crear bloques que lleven sus activos frontend con ellos está fuera de la ventana". ... fastidio :(

Gracias a todos por tomarse el tiempo de leer y considerar . ¡Espero escuchar sus respuestas!

PD> Obviamente, este es StackExchange, así que marcaré la respuesta como el mejor curso para lo que estoy tratando de lograr (bloquear la carga de recursos específicos), sin embargo, me esforzaré por enumerar también como referencias en la parte inferior de mi publicación todas y cada una de las respuestas que se suman a la discusión o sugieren una solución sólida!

cygnus digital
fuente

Respuestas:

5

Para js debería ser fácil porque usa magento 2 require.js.
Esto significa que puede incluir un js sobre la marcha cuando lo necesite.

Un bloque debe representarse (en la mayoría de los casos) mediante una plantilla.
Por lo tanto, debe agregar esto en su plantilla:

<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>

Ahora cree su archivo js view/adminhtml|frontend/web/js/filename_here.jsdonde esté presente todo su código js.

require.js sabrá cómo recoger su archivo cuando se lo solicite.

Para los archivos CSS no sé si es posible.
Los archivos css deben ir a la headsección de la página, pero por ejemplo si tiene su bloque dentro del contenido de una página cms como esta {{block class="..." template="..."}}, cuando el contenido de la página cms debe procesarse, el html hasta ese punto ya está representado por lo que no puede agregar nada más al bloque de cabeza a través de php. Puede intentar agregarlo en la plantilla como, <style...pero eso no es lo que quiere (supongo).

Marius
fuente
Gracias Marius, estoy explorando la ruta requireJS como una de las posibilidades que mencioné anteriormente, ¡pero gracias por el buen ejemplo! Estoy de acuerdo, sin embargo, no ofrece una solución al problema de CSS, sin embargo, este puede ser un punto de silencio debido al ect del compilador Less de Magento. Además, es un poco abstracto, pero supongo que podríamos usar requireJS para cargar nuestro JS, lo que a su vez podría agregar un enlace a la hoja de estilo al DOM, ¡al menos es asíncrono!
cygnus digital
De hecho, encuentro esto en las páginas requirejs, ¡cómo cargar CSS con RequireJS! : requirejs.org/docs/faq-advanced.html#css
cygnus digital
@cygnusdigital. Agradable. Entonces problema resuelto :)
Marius
Hola Marius, bueno, sí y no, es un buen candidato para la solución, cumple con los requisitos, así que agradezco tu aporte, pero estoy buscando discusiones y alternativas. Quizás solo soy yo un dinosaurio, sin embargo, creo que es más consistente tener JS / CSS cargando dentro de un constructor, es decir. "si el bloque está construido / incluido, agrégalo a la cabeza". : DI me pregunto si es posible agregar condicionalmente al bloque head.additional sobre la marcha. (es decir, agregar un bloque de cabeza desde mi módulo a head.additional en la etapa de construcción del bloque).
cygnus digital
puede hacerlo con bloques regulares que se agregan a través de archivos de diseño, pero como le expliqué, no puede hacerlo para los bloques incluidos en el contenido de la página a través de {{block}}directivas, porque la sección de encabezado ya se representa cuando se instancia la clase de bloque.
Marius