Adicionando JS a um tema Drupal 8 (substituto para drupal_add_js)

8

No Drupal 7, posso usar drupal_add_jso arquivo template.php de um tema como uma theme_preprocess_html(&$vars)função:

   drupal_add_js(drupal_get_path('theme', 'mytheme') . '/js/scripts.js',
        array(
          'group' => JS_THEME,
          'preprocess' => TRUE,
          'weight' => '999',
        ));

  $vars['scripts'] = drupal_get_js();

No Drupal 8, tentei converter isso usando attachedo arquivo .theme do meu tema da seguinte forma:

  $vars['#attached']['js'] = array(
    array(
      'data' => drupal_get_path('theme', 'mytheme') . '/js/scripts.js',
      'options' => array(
        'group' => JS_THEME,
        'preprocess' => TRUE,
        'every_page' => TRUE,
      ),
    ),
  );

... mas isso não funcionou e não houve erros no watchdog / console ou de outra forma.

De acordo com a página da API D8 para drupal_add_js:

Descontinuado - a partir do Drupal 8.0. Use a chave #attached nas matrizes de renderização.

No entanto, não havia muito mais informações do que isso. Parece que drupal_add_csstambém usará esse método. Eu sei que ainda é cedo para o Drupal 8, mas eu esperava dar um salto nisso.

Danny Englander
fonte
11
Apenas um palpite - talvez você deva tentar a abordagem da biblioteca? E evite usar a declaração "não funcionou". Você não odeia quando você tem que adivinhar o que isso significa? Avisos? Erros? Nada e o arquivo não está incluído?
Mołot 28/11
@ Mołot - não houve avisos ou erros e eu verifiquei o watchdog também. Eu também olhei para o console no Chrome e simplesmente sem erros, então tudo o que posso denunciar é "ele não funcionou". O relatório completo de erros está ativado e eu certamente tenho a minha parte justa ao portar esse tema para o Drupal 8. De qualquer forma, acho que a abordagem da biblioteca parece ser o caminho a percorrer, e não a resposta dada abaixo. Vou separar alguns módulos do Drupal 8 para ver se consigo descobrir.
Danny Englander
Você poderia ter relatado "não funcionou sem erros em ..." - então saberíamos que não havia nenhum, e você realmente fez sua parte do trabalho antes de perguntar. Isso é tudo que eu queria de você :) Muitos caras aqui perguntam sem nem checar ...
Mołot 28/11
11
Ok, obrigado, atualizado com um resumo melhor do problema. :)
Danny Englander

Respostas:

7

Parece que você pode usar hook_preprocess_pagecom anexado como tal:

function MYTHEME_preprocess_page(&$vars, $hook) {
  $path = drupal_get_path('theme', 'MYTHEME');
     // Render the main scripts file.
  $local_js = array(
    '#attached' => array(
      'js' => array(
        $path . '/js/scripts.js' => array(
          'group' => JS_THEME,
          'weight' => 9999),
      ),
    ),
  );
  \Drupal::service('renderer')->renderRoot($local_js);
}

Isso funciona muito bem ( theme.inc usa esse método), observe a matriz extra aninhada em torno do peso.

Danny Englander
fonte
Código atualizado para refletir uma versão totalmente funcional, peso e tudo.
Danny Englander
Exatamente o que eu precisava, muito apreciado !!!
Yassin Tahtah
4

O ponto chave na documentação é este bit

Use a chave #attached nas matrizes de renderização .

Ênfase minha.

A $variablesmatriz em uma função de tema / pré-processo não é uma matriz de renderização, é apenas uma matriz contendo variáveis. Para usar, #attachedvocê precisará de algo assim na função pré-processo:

$vars['foo'] = array(
  '#markup' => '<p>Bar</p>',
  '#attached' => array(
    'data' => drupal_get_path('theme', 'mytheme') . '/js/scripts.js',
    'options' => array(
      'group' => JS_THEME,
      'preprocess' => TRUE,
      'every_page' => TRUE,
    ),
  ),
);

E isso no arquivo de modelo:

{ foo }

Em outras palavras, mais ou menos o mesmo que no Drupal 7 (neste momento, pelo menos).

hook_preprocess_html()provavelmente não é o lugar certo para esse código; não esqueça que os arquivos js / css são renderizados naquele modelo; portanto, é tarde demais para adicionar mais hook_preprocess_page(), hook_preprocess_node()ou o equivalente provavelmente obterá resultados mais confiáveis.

Consulte a página Melhores práticas do Twig - funções de pré-processamento e modelos para obter mais informações sobre variáveis ​​de pré-processamento.

Clive
fonte
11
Isso está correto: As variáveis ​​transmitidas às funções de pré-processo / processo nunca são uma matriz de renderização.
kiamlaluno
Com todo o respeito, estou simplesmente tentando encontrar uma substituição no Drupal 8 para adicionar um arquivo js a um tema, não estou tentando renderizar uma variável nele. Mesmo se eu fosse, seria feito como {{ foo }}no mundo Galho, não há mais php / imprimir tornar no tema modelos, ou seja, node.html.twig/page.html.twig
Danny Englander
11
Sim, o cérebro congela lá, meu mal. A resposta é a mesma. Você só pode usar #attachedno contexto de uma matriz de renderização; a documentação está correta. Você precisa usar o método acima, juntamente com isso para pré-processar e pré-renderizar a variável, ou usar o arquivo .info.yml do seu tema para incluir o JS. Essas são as únicas opções que posso dizer até agora, sem seguir a rota da biblioteca
Clive
11
Eu acho que a abordagem será algo semelhante a isto: drupalcode.org/project/drupal.git/blob/refs/heads/8.x:/core/… - veja a linha 564 que usa hook_library_infoe que Mołot implicava acima. Vou ter que brincar um pouco com isso. Obrigado.
Danny Englander
2

Neste exemplo, você está usando uma matriz de renderização real e não uma que é renderizada na própria função.

Dessa forma, outros módulos, temas etc. podem alterá-lo.

/**
 * Implements hook_page_alter().
 */
function db_jacket_page_alter(&$page) {
  $page['#attached']['js'][] = drupal_get_path('theme', 'db_jacket') . '/js/jquery.image-depth.js';
}
user24831
fonte
0

Embora o OP seja sobre o Drupal 8, isso pode ser feito de maneira semelhante no Drupal 7 sem usar drupal_add_js()para começar a se acostumar a não ter por drupal_add_js()perto:

/**
 * Implements hook_preprocess_page().
 */
function YOURMODULE_preprocess_page(&$variables) {
  $module_path = drupal_get_path('module', 'YOURMODULE');
  $variables['page']['content']['#attached']['js'][$module_path . '/js/YOURMODULE.js'] = array();
}

As opções podem ser definidas na matriz vazia, consulte https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_add_js/7 .

lmeurs
fonte