Добавление JS в тему Drupal 8 (замена для drupal_add_js)

8

В Drupal 7 я могу использовать drupal_add_jsв файле template.php темы как theme_preprocess_html(&$vars)функцию:

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

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

В Drupal 8 я попытался преобразовать это, используя attachedв файле моей темы .theme, например:

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

... но это не сработало, и не было ошибок в сторожевом таймере / консоли или иным образом.

Согласно странице API D8 для drupal_add_js:

Устаревший - начиная с Drupal 8.0. Вместо этого используйте ключ #attached в массивах рендеринга.

Там было не намного больше информации, что это, однако. Кажется, что drupal_add_cssтакже будет использовать этот метод. Я знаю, что для Drupal 8 еще рано, но я надеялся на это прыгнуть.

Дэнни Энгландер
источник
1
Просто предположение - может быть, вам стоит попробовать библиотечный подход? И, пожалуйста, воздержитесь от использования заявления "не сработало". Разве ты не ненавидишь, когда приходится догадываться, что это значит? Предупреждения? Ошибки? Ничего и файл не включен?
Молот
@ Молот - предупреждений и ошибок не было, и я также проверил сторожевой таймер. Я также посмотрел на консоли в Chrome и просто нет ошибок, поэтому все, что я могу сообщить, это «это не сработало». Полные отчеты об ошибках включены, и я, конечно, получил свою долю от них, когда портирую эту тему на Drupal 8. В любом случае, я думаю, что библиотечный подход, кажется, является подходом, а не ответом, приведенным ниже. Я собираюсь разобрать несколько модулей Drupal 8, чтобы посмотреть, смогу ли я понять это.
Дэнни Энгландер
Вы могли бы сообщить, что «это не сработало без ошибок в ...» - тогда мы бы знали, что их не было, и вы фактически выполнили свою часть работы, прежде чем спрашивать. Это все, что я хотел от вас :) Слишком много парней спрашивают здесь, даже не проверяя ...
Mołot
1
Хорошо, спасибо, обновлено с улучшенным резюме проблемы. :)
Дэнни Энгландер

Ответы:

7

Кажется, вы можете использовать hook_preprocess_pageс прикрепленными как так:

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

Это прекрасно работает ( theme.inc использует этот метод), обратите внимание на дополнительный вложенный массив вокруг веса.

Дэнни Энгландер
источник
Код обновлен, чтобы отразить полностью рабочую версию, вес и все.
Дэнни Энгландер,
Именно то, что мне было нужно, высоко ценится !!!
Ясин Тахта
4

Ключевым моментом в документации является этот бит

Вместо этого используйте ключ #attached в массивах рендеринга .

Акцент мой.

$variablesМассив в функции темы / Preprocess не делают массив, это просто массив , содержащий переменные. Для использования #attachedвам понадобится что-то вроде этого в функции preprocess:

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

И это в файле шаблона:

{ foo }

Другими словами, более или менее так же, как в Drupal 7 (на данный момент, по крайней мере).

hook_preprocess_html()скорее всего, это не то место для этого кода; не забывайте, что файлы js / css на самом деле отображаются в этом шаблоне, так что уже слишком поздно добавлять их hook_preprocess_page(), hook_preprocess_node()иначе эквивалент, вероятно, даст вам более надежные результаты.

Посмотрите лучшие практики Twig - страницу функций и шаблонов предварительной обработки для получения дополнительной информации о переменных предварительной обработки.

Клайв
источник
1
Это правильно: переменные, переданные функциям предварительной обработки / процесса, никогда не являются массивом рендеринга.
kiamlaluno
При всем уважении, я просто пытаюсь найти замену в Drupal 8 для добавления файла js в тему, я не пытаюсь отобразить в нем переменную. Даже если бы я был, это было бы сделано, как {{ foo }}в мире Twig, больше нет рендера php / print в шаблонах тем, т.е. node.html.twig/page.html.twig
Дэнни Энгландер,
1
Ага, мозги там, мой плохой. Ответ тот же, хотя. Вы можете использовать только #attachedв контексте массива рендеринга; документация правильная. Вам нужно либо использовать описанный выше метод вместе с этим для предварительной обработки и предварительного рендеринга переменной, либо использовать файл .info.yml вашей темы для включения JS. Это единственные варианты, которые я могу сказать до сих пор, не спускаясь по библиотечному маршруту
Клайв
1
Я думаю , что этот подход будет что - то похожее на это: drupalcode.org/project/drupal.git/blob/refs/heads/8.x:/core/... - см линию 564 , которая использует hook_library_infoи которая подразумеваемой выше МОЛОТ. Я должен немного поиграть с этим. Спасибо.
Дэнни Энгландер
2

В этом примере вы используете реальный массив визуализации, а не тот, который отображается в самой функции.

Таким образом, другие модули, темы и т. Д. Могут изменить его.

/**
 * 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
источник
0

Хотя ОП касается Drupal 8, это можно сделать аналогичным образом в Drupal 7 без использования, drupal_add_js()чтобы начать привыкать к отсутствию drupal_add_js():

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

Параметры могут быть определены в пустом массиве, см. Https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_add_js/7 .

lmeurs
источник