Hinzufügen von JS zu einem Drupal 8-Thema (Ersatz für drupal_add_js)

8

In Drupal 7 kann ich drupal_add_jsdie Datei template.php eines Themas als theme_preprocess_html(&$vars)Funktion verwenden:

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

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

In Drupal 8 habe ich versucht, dies mithilfe attachedder .theme- Datei meines Themas als solche zu konvertieren :

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

... aber das hat nicht funktioniert und es gab keine Fehler im Watchdog / in der Konsole oder auf andere Weise.

Laut der D8-API-Seite für drupal_add_js:

Veraltet - ab Drupal 8.0. Verwenden Sie stattdessen den Schlüssel #attached in Render-Arrays.

Es gab jedoch nicht viel mehr Informationen darüber. Es scheint, dass drupal_add_cssauch diese Methode verwendet wird. Ich weiß, dass es für Drupal 8 noch sehr früh ist, aber ich hatte gehofft, einen Sprung darauf zu machen.

Danny Englander
quelle
1
Nur eine Vermutung - vielleicht sollten Sie den Bibliotheksansatz ausprobieren? Und bitte verzichten Sie auf die Anweisung "hat nicht funktioniert". Hassen Sie es nicht, wenn Sie raten müssen, was es bedeutet? Warnungen? Fehler? Nichts und die Datei ist nicht enthalten?
Mołot
@ Mołot - es gab keine Warnungen oder Fehler und ich habe auch Watchdog überprüft. Ich habe mir auch die Konsole in Chrome angesehen und einfach keine Fehler. Ich kann also nur berichten, dass "es nicht funktioniert hat". Die vollständige Fehlerberichterstattung ist aktiviert, und ich habe sicherlich einen angemessenen Anteil davon, als ich dieses Thema auf Drupal 8 portierte. Auf jeden Fall scheint der Bibliotheksansatz der richtige Weg zu sein und nicht die unten angegebene Antwort. Ich werde einige Drupal 8-Module auseinander nehmen, um zu sehen, ob ich es herausfinden kann.
Danny Englander
Sie hätten melden können, dass "es ohne Fehler in ... nicht funktioniert hat" - dann würden wir wissen, dass es keine gab, und Sie haben tatsächlich Ihren Teil der Arbeit erledigt, bevor Sie gefragt haben. Das ist alles, was ich von dir wollte :) Zu viele Leute hier
fragen
1
Ok, danke, aktualisiert mit einer besseren Zusammenfassung der Probleme. :)
Danny Englander

Antworten:

7

Es scheint, dass Sie hook_preprocess_pagemit angehängten als solche verwenden können:

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

Dies funktioniert hervorragend ( theme.inc verwendet diese Methode). Beachten Sie das zusätzliche verschachtelte Array um das Gewicht.

Danny Englander
quelle
Code aktualisiert, um eine voll funktionsfähige Version, Gewicht und alles wiederzugeben.
Danny Englander
Genau das, was ich brauchte, sehr geschätzt !!!
Yassin Tahtah
4

Der entscheidende Punkt in der Dokumentation ist dieses Bit

Verwenden Sie stattdessen den Schlüssel #attached in Render-Arrays .

Hervorhebung von mir.

Das $variablesArray in einer Theme / Preprocess-Funktion ist kein Render-Array, sondern nur ein Array mit Variablen. Zur Verwendung #attachedbenötigen Sie Folgendes in der Vorverarbeitungsfunktion:

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

Und das in der Vorlagendatei:

{ foo }

Mit anderen Worten, mehr oder weniger das gleiche wie in Drupal 7 (zumindest zu diesem Zeitpunkt).

hook_preprocess_html()ist übrigens wahrscheinlich nicht der richtige Ort für diesen Code; vergessen Sie nicht , die js / CSS - Dateien sind tatsächlich in dieser Vorlage gemacht, so dass es zu spät ist mehr hinzuzufügen hook_preprocess_page(), hook_preprocess_node()oder gleichwertig wahrscheinlich Sie zuverlässigere Ergebnisse erzielen.

Sehen Sie sich die Zweig Best Practices - Vorprozess Funktionen und Vorlagen Seite für weitere Informationen über die Vorverarbeitung Variablen.

Clive
quelle
1
Dies ist richtig: Die an Vorverarbeitungs- / Prozessfunktionen übergebenen Variablen sind niemals ein Render-Array.
Kiamlaluno
Bei allem Respekt versuche ich einfach, in Drupal 8 einen Ersatz für das Hinzufügen einer js-Datei zu einem Thema zu finden. Ich versuche nicht, eine Variable darin zu rendern. Selbst wenn ich es wäre, würde es wie {{ foo }}in der Twig-Welt gemacht werden, es gibt kein PHP / Print-Rendering mehr in Themenvorlagen, dh node.html.twig/page.html.twig
Danny Englander
1
Ja, dort friert das Gehirn ein, mein Schlimmes. Die Antwort ist jedoch dieselbe. Sie können nur #attachedim Kontext eines Render-Arrays verwenden. Die Dokumentation ist korrekt. Sie müssen entweder über die Methode zu verwenden, zusammen mit dieser vorverarbeitet und die Variable vorrendern oder Ihr Thema der .info.yml - Datei zu verwenden , um die JS zu umfassen. Dies sind die einzigen Optionen, die ich bisher
Clive
1
Ich denke, der Ansatz wird ähnlich sein: drupalcode.org/project/drupal.git/blob/refs/heads/8.x:/core/… - siehe Zeile 564, die verwendet hook_library_infound die Mołot oben impliziert hat. Ich muss ein bisschen damit herumspielen. Vielen Dank.
Danny Englander
2

In diesem Beispiel verwenden Sie ein echtes Render-Array und nicht eines, das in der Funktion selbst gerendert wird.

Auf diese Weise können andere Module, Themen usw. dies ändern.

/**
 * 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
quelle
0

Obwohl es im OP um Drupal 8 geht, könnte dies in Drupal 7 auf ähnliche Weise geschehen, ohne sich daran drupal_add_js()zu gewöhnen, nicht in der Nähe zu drupal_add_js()sein:

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

Optionen können im leeren Array definiert werden, siehe https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_add_js/7 .

lmeurs
quelle