Thêm JS vào chủ đề Drupal 8 (thay thế cho drupal_add_js)


8

Trong Drupal 7, tôi có thể sử dụng drupal_add_jstrong tệp template.php của một chủ đề như một theme_preprocess_html(&$vars)hàm:

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

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

Trong Drupal 8, tôi đã thử chuyển đổi điều này bằng cách sử dụng tệp .themeattached của chủ đề của mình như sau:

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

... nhưng điều đó không hoạt động và không có lỗi trong watchdog / console hay nói cách khác.

Theo trang API D8 cho drupal_add_js:

Không dùng nữa - kể từ Drupal 8.0. Thay vào đó, hãy sử dụng khóa #attached trong mảng kết xuất.

Tuy nhiên, không có nhiều thông tin hơn thế. Có vẻ như drupal_add_csscũng sẽ sử dụng phương pháp này. Tôi biết vẫn còn sớm cho Drupal 8 nhưng tôi đã hy vọng có được một bước nhảy vọt về điều này.


1
Chỉ là một phỏng đoán - có lẽ bạn nên thử cách tiếp cận thư viện? Và xin vui lòng không sử dụng tuyên bố "không hoạt động". Bạn không ghét nó khi bạn phải đoán nó có nghĩa là gì? Cảnh báo? Lỗi? Không có gì và tập tin không được bao gồm?
Mołot

@ Mołot - không có cảnh báo hoặc lỗi và tôi cũng đã kiểm tra cơ quan giám sát. Tôi cũng đã xem bảng điều khiển trong Chrome và đơn giản là không có lỗi, vì vậy tất cả những gì tôi có thể báo cáo là "nó không hoạt động." Báo cáo lỗi đầy đủ được bật và tôi chắc chắn đã chia sẻ công bằng về chúng trong khi chuyển chủ đề này sang Drupal 8. Dù sao đi nữa, tôi nghĩ rằng cách tiếp cận thư viện dường như là cách để đi và không phải là câu trả lời dưới đây. Tôi sẽ chọn ra một số mô-đun Drupal 8 để xem liệu tôi có thể tìm ra nó không.
Daniel Englander

Bạn có thể đã báo cáo "nó không hoạt động mà không có lỗi trong ..." - sau đó chúng tôi sẽ biết là không có gì, và bạn thực sự đã làm một phần công việc trước khi hỏi. Đó là tất cả những gì tôi muốn từ bạn :) Quá nhiều người ở đây hỏi mà không cần kiểm tra ...
Mołot

1
Ok cảm ơn, cập nhật với một bản tóm tắt vấn đề tốt hơn. :)
Daniel Englander

Câu trả lời:


7

Có vẻ như bạn có thể sử dụng hook_preprocess_pagekèm theo như vậy:

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

Điều này hoạt động rất tốt ( theme.inc sử dụng phương pháp này), lưu ý mảng lồng thêm xung quanh trọng lượng.


Mã được cập nhật để phản ánh một phiên bản hoạt động đầy đủ, trọng lượng và tất cả.
Daniel Englander

Chính xác những gì tôi cần, đánh giá cao !!!
Yassin Tahtah

4

Điểm mấu chốt trong tài liệu là bit này

Thay vào đó, hãy sử dụng khóa #attached trong mảng kết xuất .

Nhấn mạnh mỏ.

Các $variablesmảng trong một chức năng theme / preprocess không phải là một mảng render, nó chỉ là một mảng cầm biến. Để sử dụng, #attachedbạn sẽ cần một cái gì đó như thế này trong chức năng tiền xử lý:

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

Và cái này trong tệp mẫu:

{ foo }

Nói cách khác, ít nhiều giống như trong Drupal 7 (ít nhất là tại thời điểm này).

hook_preprocess_html()có khả năng không phải là nơi thích hợp cho mã này; đừng quên các tệp js / css thực sự được hiển thị trong mẫu đó, vì vậy quá muộn để thêm nữa hook_preprocess_page(), hook_preprocess_node()hoặc tương đương có thể sẽ giúp bạn có kết quả đáng tin cậy hơn.

Xem Twig thực tiễn tốt nhất - trang chức năng và mẫu tiền xử lý để biết thêm thông tin về các biến tiền xử lý.


1
Điều này là chính xác: Các biến được truyền cho các hàm tiền xử lý / quy trình không bao giờ là mảng kết xuất.
kiamlaluno

Với tất cả sự tôn trọng, tôi chỉ đơn giản là cố gắng tìm một sự thay thế trong Drupal 8 để thêm tệp js vào một chủ đề, tôi không cố gắng đưa ra một biến trong đó. Ngay cả khi tôi là như vậy, nó sẽ được thực hiện như {{ foo }}trong thế giới Twig, không có kết xuất php / print nào trong các mẫu chủ đề, tức là node.html.twig/page.html.twig
Danny Englander

1
Vâng não đóng băng ở đó, xấu của tôi. Câu trả lời là như nhau mặc dù. Bạn chỉ có thể sử dụng #attachedtrong ngữ cảnh của một mảng render; các tài liệu là chính xác. Bạn có thể cần sử dụng phương thức trên, cùng với phương thức này để tiền xử lý và kết xuất trước biến hoặc sử dụng tệp .info.yml của chủ đề của bạn để bao gồm JS. Đó là những lựa chọn duy nhất mà tôi có thể nói cho đến nay, mà không cần đi xuống tuyến đường thư viện
Clive

1
Tôi nghĩ rằng cách tiếp cận sẽ tương tự như thế này: drupalcode.org/project/drupal.git/blob/refs/heads/8.x:/core/iêu - xem dòng 564 sử dụng hook_library_infovà Mołot ngụ ý ở trên. Tôi sẽ phải chơi xung quanh với điều đó một chút. Cảm ơn.
Daniel Englander


2

Trong ví dụ này, bạn đang sử dụng một mảng render thực sự chứ không phải một mảng được kết xuất trong chính hàm đó.

Bằng cách này, các mô-đun khác, chủ đề, vv có thể thay đổi nó.

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

0

Mặc dù OP nói về Drupal 8, nhưng điều này có thể được thực hiện theo cách tương tự trong Drupal 7 mà không sử dụng drupal_add_js()để bắt đầu làm quen với việc không có drupal_add_js()xung quanh:

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

Các tùy chọn có thể được xác định trong mảng trống, xem https://api.drupal.org/api/drupal/includes%21common.inc/feft/drupal_add_js/7 .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.