Como adicionar JS (e CSS) de bloco específico - O caminho certo?

9

Então, eu passei literalmente horas e horas pesquisando, lendo, estudando etc., mas ninguém (nem mesmo Alan Storm!) Me explicou isso. Parece que toda a Internet está interessada em adicionar JS ou CSS a uma página específica do Magento 2, mas o que estou procurando é adicionar JS / CSS a um bloco específico .

Então, aqui está a minha pergunta em poucas palavras:

Qual é a melhor maneira de adicionar JS (e adicionalmente CSS) a um bloco específico , para que, se o bloco estiver presente na página (*), o JS / CSS seja carregado, se o bloco não estiver lá, não haverá CSS / JS? ?

* Isso significa que qualquer lugar em que um bloco possa ser configurado, em uma página / modelo via layout.xml, em uma página personalizada do meu módulo, pelo método toHtml de um bloco / página ou, mais importante, em um bloco incorporado no WYSIWYG de uma categoria / descrição do produto / Bloco CMS / Página CMS.

Eu li vários ótimos artigos de Alan (parabéns de novo para esse cara !!), sem mencionar as resmas de outros artigos , mas tenho a sensação de que todos querem adicionar a uma página, uma página específica, nunca onde bloco é usado.

Sinto que estou familiarizado com as várias técnicas, no entanto, posso estar faltando alguma coisa aqui, por isso gostaria de obter um consenso da comunidade, bem como, talvez, um post de sinalização para todos os front-ends até os desenvolvedores de pilha cheia por aí procurando perguntas semelhantes e ponderando as opções como eu.

Anteriormente, no Magento 1, eu procurava no construtor de blocos, obtinha o layout, obtinha a referência principal e chamava addJs / addCss lá, ou, se possível, usava os métodos no layout.xml. Isso significaria que o JS foi "adicionado" à lista de recursos no construtor de blocos (antes que o nível do tema produzisse o bloco principal). Mas isso não parece possível agora.

Eu li sobre como proceder para adicionar JS / CSS (este não é um simples "como é que eu ???", este é um resumo mais "do que é a maneira correta / mag2 ???") e estou familiarizado com estes técnicas:

  • /view/[area}/layout/[default/page_idExit.xml, usando os <head></head>elementos raiz
  • Adicionando um bloco Head ao meu módulo, adicionado em head.additional, com algum tipo de lógica sobre se meu bloco está carregado
  • usando os objetos \ Asset \ GroupedCollection e \ Asset \ Repository para injetar do fabricante de uma página / modelo (embora isso não pareça estar com blocos), potencialmente a ordem de carregamento?
  • Usando RequireJS e aplicando uma configuração requireJS ao meu módulo

Perdi alguma coisa ??

Acredita-se que a maneira correta seria usar a biblioteca RequireJS e os atributos x-magento-init ou apenas um script com uma require("my_module", function(){ ... })sintaxe em um script embutido. Mas isso me parece desajeitado? Eu teria que configurar scripts para carregar scripts, sou forçado a incorporar pelo menos parte do meu JS, no entanto, parece a maneira mais sustentável de dizer "aqui está meu bloco, agora é necessário um pouco de JS", inserindo-o no meu phtml.

No entanto, eu realmente gostaria de poder fazer isso via PHP, como um programador de back-end / stack que eu gostaria idealmente de encapsular o JS de distância e (idealmente) permitir que minha equipe de front-end escreva isso como quiser. Resumindo, cuide do carregamento (Back Back Dev to Frond End Dev "aqui está o phtml, substitua o tema, se quiser, da mesma forma o arquivo js, ​​suas bibliotecas dependentes e o CSS para o bloco").

Isso sugere o __constructmétodo com dependências injetadas no sistema de ativos. No entanto, não consigo fazer isso funcionar, isso parece confirmado no artigo rápido de Alan Storms aqui: Magento Quickies: Magento 2: Adicionando arquivos de recursos de front-end programaticamente

Observe a inscrição "Portanto, qualquer ideia de criar blocos que carregam seus recursos de front-end está fora da janela". ... chatice :(

Obrigado por reservar um tempo para ler e considerar . Estou ansioso para ouvir suas respostas!

PS> Obviamente, esse é o StackExchange, por isso vou marcar a resposta como o melhor caminho para o que estou tentando alcançar (bloquear o carregamento de recursos específicos). No entanto, tentarei também listar como referências na parte inferior do meu post todas e quaisquer respostas que aumentam a discussão ou sugerem uma solução sólida!

cygnus digital
fonte

Respostas:

5

Para js, deve ser fácil porque o magento 2 usa require.js.
Portanto, isso significa que você pode incluir um js rapidamente quando precisar.

Um bloco deve ser renderizado (na maioria dos casos) por um modelo.
Então, você precisa adicionar isso ao seu modelo:

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

Agora crie seu arquivo js view/adminhtml|frontend/web/js/filename_here.jsonde todo o seu código js está presente.

require.js saberá como pegar seu arquivo quando for solicitado.

Para arquivos CSS, não sei se é possível.
Os arquivos css devem ir para a headseção da página, mas, por exemplo, se você tiver seu bloco dentro do conteúdo de uma página cms como esta {{block class="..." template="..."}}, quando o conteúdo da página cms deve ser processado, o html até esse ponto já será renderizado então você não pode adicionar mais nada ao bloco principal via php. Você pode tentar adicioná-lo no modelo como <style...mas não é isso que você deseja (presumo).

Marius
fonte
Obrigado Marius, estou explorando a rota requireJS como uma das possibilidades listadas acima, mas obrigado pelo exemplo conciso! Concordo, no entanto, ele não oferece uma solução para a questão CSS, no entanto, este pode ser um ponto mudo devido ao ect do compilador Less do Magento. Além disso, é um resumo abstrato, mas suponho que poderíamos usar o requireJS para carregar nosso JS, o que por sua vez poderia adicionar um link à folha de estilo para o DOM, pelo menos assíncrono !!!
cygnus digitais
Na verdade, acho isso nas páginas requirejs, como carregar CSS com o RequireJS! : requirejs.org/docs/faq-advanced.html#css
cygnus digital
@cygnusdigital. Agradável. Assim problema resolvido :)
Marius
Olá Marius, bem, sim e não, é certamente um bom candidato para a solução, atende aos requisitos. Por isso, agradeço sua contribuição, mas estou procurando por discussões e alternativas. Talvez seja apenas eu um dinossauro, no entanto, sinto que é mais consenso ter o carregamento de JS / CSS dentro de um construtor, ou seja. "se o bloco for construído / incluído, adicione isso na cabeça." : DI me pergunto se é possível adicionar condicionalmente ao bloco head.additional em tempo real. (ou seja, adicione um bloco principal do meu módulo para head.additional no estágio do construtor do bloco).
cygnus digitais
você pode fazer isso com blocos regulares adicionados por meio de arquivos de layout, mas, como expliquei, não é possível fazer isso com blocos incluídos no conteúdo da página por meio de {{block}}diretivas, porque a seção head já é renderizada quando a classe de bloco é instanciada.
Marius