Menambahkan JS ke tema Drupal 8 (pengganti drupal_add_js)

8

Di Drupal 7, saya bisa menggunakan file template.phpdrupal_add_js tema sebagai fungsi: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();

Dalam Drupal 8, saya sudah mencoba mengkonversi ini menggunakan attacheddalam tema saya .theme berkas seperti:

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

... tapi itu tidak berhasil dan tidak ada kesalahan dalam pengawas / konsol atau sebaliknya.

Menurut halaman D8 API untuk drupal_add_js:

Tidak digunakan lagi - mulai dari Drupal 8.0. Gunakan kunci #attached di render array sebagai gantinya.

Tidak ada info lebih lanjut tentang itu. Tampaknya drupal_add_cssjuga akan menggunakan metode ini. Saya tahu ini masih hari-hari awal untuk Drupal 8 tetapi saya berharap untuk melompat pada ini.

Danny Englander
sumber
1
Tebakan - mungkin Anda harus mencoba pendekatan perpustakaan? Dan tolong jangan menggunakan pernyataan "tidak berhasil". Tidakkah kamu membencinya ketika kamu harus menebak apa artinya? Peringatan? Kesalahan? Tidak ada dan file tidak termasuk?
Mołot
@ Mołot - tidak ada peringatan atau kesalahan dan saya juga memeriksa anjing penjaga. Saya juga melihat konsol di Chrome dan tidak ada kesalahan, jadi yang bisa saya laporkan adalah "itu tidak berhasil." Pelaporan kesalahan penuh dihidupkan dan saya pasti mendapat bagian yang adil dari mereka saat porting tema ini ke Drupal 8. Bagaimanapun, saya pikir pendekatan perpustakaan tampaknya menjadi cara untuk pergi dan bukan jawaban yang diberikan di bawah ini. Saya akan memilih beberapa modul Drupal 8 untuk melihat apakah saya bisa mengetahuinya.
Danny Englander
Anda dapat melaporkan "gagal berfungsi tanpa kesalahan dalam ..." - maka kami akan tahu tidak ada, dan Anda benar-benar melakukan bagian pekerjaan Anda sebelum bertanya. Itu saja yang saya inginkan dari Anda :) Terlalu banyak orang di sini yang bertanya bahkan tanpa memeriksa ...
Mołot
1
Oke terima kasih, diperbarui dengan ringkasan masalah yang lebih baik. :)
Danny Englander

Jawaban:

7

Tampaknya Anda dapat menggunakannya hook_preprocess_pagedengan melampirkan:

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

Ini berfungsi baik ( theme.inc menggunakan metode ini), perhatikan array bersarang ekstra di sekitar berat.

Danny Englander
sumber
Kode diperbarui untuk mencerminkan versi yang berfungsi penuh, berat dan semuanya.
Danny Englander
Persis apa yang saya butuhkan, sangat dihargai !!!
Yassin Tahtah
4

Titik kunci dalam dokumentasi adalah bit ini

Gunakan kunci #attached di render array sebagai gantinya.

Tekankan milikku.

The $variablesarray dalam fungsi tema / preprocess tidak array membuat, itu hanya sebuah array memegang variabel. Untuk menggunakan #attachedAnda akan membutuhkan sesuatu seperti ini di fungsi 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,
    ),
  ),
);

Dan ini di file templat:

{ foo }

Dengan kata lain, kurang lebih sama dengan di Drupal 7 (setidaknya pada titik waktu ini).

hook_preprocess_html()omong-omong sepertinya bukan tempat yang tepat untuk kode ini; jangan lupa file js / css benar-benar dirender dalam template itu, jadi sudah terlambat untuk menambahkan lagi hook_preprocess_page(), hook_preprocess_node()atau yang setara mungkin akan memberi Anda hasil yang lebih andal.

Lihat halaman Twig best practices - fungsi preproses dan templat untuk informasi lebih lanjut tentang variabel preproses.

Clive
sumber
1
Ini benar: Variabel yang diteruskan ke fungsi preprocess / proses tidak pernah menjadi render array.
kiamlaluno
Dengan segala hormat, saya hanya mencoba mencari pengganti di Drupal 8 untuk menambahkan file js ke tema, saya tidak mencoba membuat variabel di dalamnya. Bahkan jika saya melakukannya, itu akan dilakukan seperti {{ foo }}di dunia Twig, tidak ada lagi php / print render dalam templat tema, yaitu node.html.twig/page.html.twig
Danny Englander
1
Ya otak membeku di sana, salahku. Jawabannya sama saja. Anda hanya dapat menggunakan #attacheddalam konteks array render; dokumentasinya benar. Anda harus menggunakan metode di atas, bersamaan dengan ini untuk preprocess dan pra-render variabel, atau menggunakan file .info.yml tema Anda untuk memasukkan JS. Itulah satu-satunya pilihan yang bisa saya katakan sejauh ini, tanpa melewati rute perpustakaan
Clive
1
Saya pikir pendekatannya akan menjadi sesuatu yang mirip dengan ini: drupalcode.org/project/drupal.git/blob/refs/heads/8.x:/core/… - lihat baris 564 yang menggunakan hook_library_infodan yang tersirat Mołot di atas. Saya harus bermain-main dengan itu sedikit. Terima kasih.
Danny Englander
2

Dalam contoh ini Anda menggunakan array render nyata dan bukan yang dirender dalam fungsi itu sendiri.

Dengan cara ini modul lain, tema dll dapat mengubahnya.

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

Meskipun OP adalah tentang Drupal 8, ini bisa dilakukan dengan cara yang sama di Drupal 7 tanpa menggunakan drupal_add_js()untuk mulai terbiasa untuk tidak memiliki drupal_add_js()sekitar:

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

Opsi dapat didefinisikan dalam array kosong, lihat https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_add_js/7 .

lmeurs
sumber