Ajout de JS à un thème Drupal 8 (remplacement de drupal_add_js)

8

Dans Drupal 7, je peux utiliser drupal_add_jsdans le fichier template.php d' un thème en tant que theme_preprocess_html(&$vars)fonction:

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

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

Dans Drupal 8, j'ai essayé de convertir ceci en utilisant attacheddans le fichier .theme de mon thème en tant que tel:

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

... mais cela n'a pas fonctionné et il n'y a eu aucune erreur dans watchdog / console ou autre.

Selon la page API D8 pour drupal_add_js:

Déconseillé - à partir de Drupal 8.0. Utilisez plutôt la clé #attached dans les tableaux de rendu.

Il n'y avait cependant pas beaucoup plus d'informations que cela. Il semble que drupal_add_cssva également utiliser cette méthode. Je sais que c'est encore tôt pour Drupal 8 mais j'espérais faire un saut là-dessus.

Danny Englander
la source
1
Juste une supposition - vous devriez peut-être essayer l'approche de la bibliothèque? Et veuillez vous abstenir d'utiliser la déclaration "n'a pas fonctionné". Ne détestez-vous pas cela quand vous devez deviner ce que cela signifie? Avertissements? Les erreurs? Rien et le fichier n'est pas inclus?
Mołot
@ Mołot - il n'y a eu aucun avertissement ni erreur et j'ai également vérifié le chien de garde. J'ai également regardé la console dans Chrome et tout simplement aucune erreur, donc tout ce que je peux signaler est "cela n'a pas fonctionné". Le rapport d'erreurs complet est activé et j'ai certainement ma juste part lors du portage de ce thème sur Drupal 8. En tout cas, je pense que l'approche de la bibliothèque semble être la voie à suivre et non la réponse donnée ci-dessous. Je vais séparer certains modules Drupal 8 pour voir si je peux le comprendre.
Danny Englander
Vous auriez pu signaler "cela n'a pas fonctionné sans erreur dans ..." - alors nous saurions qu'il n'y en avait pas, et vous avez fait votre part de travail avant de demander. C'est tout ce que je voulais de vous :) Trop de gars ici demandent sans même vérifier ...
Mołot
1
Ok merci, mis à jour avec un meilleur résumé du problème. :)
Danny Englander

Réponses:

7

Il semble que vous pouvez utiliser hook_preprocess_pageavec attaché en tant que tel:

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);
}

Cela fonctionne très bien ( theme.inc utilise cette méthode), notez le tableau imbriqué supplémentaire autour du poids.

Danny Englander
la source
Code mis à jour pour refléter une version entièrement fonctionnelle, le poids et tout.
Danny Englander
Exactement ce dont j'avais besoin, très apprécié !!!
Yassin Tahtah
4

Le point clé de la documentation est ce bit

Utilisez plutôt la clé #attached dans les tableaux de rendu .

Je souligne.

Le $variablestableau dans une fonction thème / prétraitement n'est pas un tableau de rendu, c'est juste un tableau contenant des variables. Pour l'utiliser, #attachedvous aurez besoin de quelque chose comme ceci dans la fonction de prétraitement:

$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,
    ),
  ),
);

Et cela dans le fichier modèle:

{ foo }

En d'autres termes, plus ou moins les mêmes que dans Drupal 7 (en ce moment, au moins).

hook_preprocess_html()n'est probablement pas le bon endroit pour ce code; n'oubliez pas que les fichiers js / css sont réellement rendus dans ce modèle, il est donc trop tard pour en ajouter d'autres hook_preprocess_page(), hook_preprocess_node()ou l'équivalent vous donnera probablement des résultats plus fiables.

Consultez la page Meilleures pratiques Twig - Fonctions de prétraitement et modèles pour plus d'informations sur les variables de prétraitement.

Clive
la source
1
C'est correct: les variables passées aux fonctions de prétraitement / traitement ne sont jamais un tableau de rendu.
kiamlaluno
Avec tout le respect que je vous dois, j'essaie simplement de trouver un remplacement dans Drupal 8 pour ajouter un fichier js à un thème, je n'essaie pas de rendre une variable dedans. Même si je l'étais, ce serait fait comme {{ foo }}dans le monde Twig, il n'y a plus de rendu php / print dans les modèles de thème, c'est node.html.twig-à- dire /page.html.twig
Danny Englander
1
Ouais, le cerveau y gèle, mon mauvais. Mais la réponse est la même. Vous ne pouvez utiliser que #attacheddans le contexte d'un tableau de rendu; la documentation est correcte. Vous devez soit utiliser la méthode ci-dessus, avec celle-ci pour prétraiter et pré-rendre la variable, soit utiliser le fichier .info.yml de votre thème pour inclure le JS. Ce sont les seules options que je peux dire jusqu'à présent, sans descendre sur la route de la bibliothèque
Clive
1
Je pense que l'approche va être quelque chose de similaire à ceci: drupalcode.org/project/drupal.git/blob/refs/heads/8.x:/core/… - voir la ligne 564 qui utilise hook_library_infoet que Mołot a impliqué ci-dessus. Je vais devoir jouer un peu avec ça. Merci.
Danny Englander
2

Dans cet exemple, vous utilisez un véritable tableau de rendu et non celui qui est rendu dans la fonction elle-même.

De cette façon, d'autres modules, thèmes, etc. peuvent le modifier.

/**
 * 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
la source
0

Bien que l'OP concerne Drupal 8, cela pourrait être fait de manière similaire dans Drupal 7 sans utiliser drupal_add_js()pour commencer à s'habituer à ne pas avoir drupal_add_js()autour:

/**
 * 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();
}

Les options peuvent être définies dans le tableau vide, voir https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_add_js/7 .

lmeurs
la source