Haruskah Pihak ke-3 Gunakan $ wp_scripts / $ wp_styles-> add_data?

31

Di dalam WP_Dependencieskelas ada metode bernama add_data. Fungsi ini menambahkan data ke skrip / gaya yang telah enqueued selama memuat WordPress. Penggunaan yang sering dikutip untuk fungsi ini adalah untuk menambahkan persyaratan saat menambahkan stylesheet yang ditargetkan pada versi IE yang berbeda. Misalnya, untuk menargetkan IE8 dan lebih rendah:

function test_wp_print_styles() {
    global $wp_styles;

    wp_enqueue_style( 'test-style', get_template_directory_uri() . '/css/test.css', array(), 1, 'all' );
    $wp_styles->add_data( 'test-style', 'conditional', 'lte ie8' );
}
add_action( 'wp_print_styles', 'test_wp_print_styles' );

Ini akan dirender sebagai:

<!--[if lte ie8]>
<link rel='stylesheet' id='test-style-css'  href='http://trunkosaurus.dev/wp-content/themes/twentyeleven/css/test.css?ver=1' type='text/css' media='all' />
<![endif]--> 

Ketika saya melihat melalui Core, saya melihat beberapa tempat di mana metode ini digunakan:

  • WP_Styles->add_inline_style(): menambahkan gaya sebaris setelah stylesheet yang direferensikan (dilakukan melalui WP_Styles->print_inline_style())

  • WP_Scripts->localize(): menambahkan objek yang dikodekan json (dibungkus oleh lebih banyak wp_localize_script()fungsi "publik" )

  • wp_plupload_default_settings() : menambahkan objek yang dikodekan json (dibuat dari larik multidimensi) untuk skrip 'wp-plupload' (perhatikan bahwa ini akan datang di 3.4)

  • Saat mendaftar / enqueueing skrip dan gaya Menambahkan data untuk skrip default ( wp-includes/script-loader.php)

Dari membaca melalui penggunaan metode ini, tampaknya tidak memiliki kasus penggunaan khusus. Dalam wp_plupload_default_settings, tampaknya memungkinkan untuk injeksi data yang sewenang-wenang. Dalam wp_register_script, tampaknya digunakan untuk membedakan antara skrip header dan footer. Dalam add_inline_style, ini digunakan untuk menunjukkan gaya sebaris yang harus ditambahkan setelah stylesheet yang ditentukan enqueued.

Penggunaan yang sangat baik untuk fungsi ini akan menjadi sesuatu seperti kode berikut di mana Anda meminta skrip eksternal tetapi perlu mengirimkannya beberapa konfigurasi, beberapa di antaranya berasal dari DB:

function zdt_enqueue_add_this() {
    global $wp_scripts;

    wp_enqueue_script( 'zdt-add-this', 'http://s7.addthis.com/js/250/addthis_widget.js#pubid=myidhere' );

    // Contrived example of database call to get a twitter handle stored in the db
    $author_twitter_handle = zdt_get_twitter_handle();

    $js = "var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @" . sanitize_key( $author_twitter_handle ) . "' } };\n";
    $js .= 'var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };';

    $wp_scripts->add_data( 'zdt-add-this', 'data', $js );
}
add_action( 'wp_enqueue_scripts', 'zdt_enqueue_add_this' );

Ini akan menghasilkan:

<script type='text/javascript'>
/* <![CDATA[ */
var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @tollmanz' } };
var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };
/* ]]> */
</script>
<script type='text/javascript' src='http://s7.addthis.com/js/250/addthis_widget.js?ver=3.4-beta4-20731#pubid=myidhere'></script>

Perhatikan bahwa ini tidak dapat diselesaikan dengan wp_localize_scriptkarena addthis_shareobjek tersebut memiliki properti di dalam properti ( saya memang menulis tentang cara yang agak membingungkan tentang ini sebelumnya ).

EDIT: Saya salah dalam menyatakan ini. wp_localize_scriptmenangani array multidimensi dengan baik.

Metode ini tampaknya berfungsi sangat baik karena alasan berikut:

  1. Hal ini memungkinkan Anda untuk melampirkan data ke pegangan skrip sehingga selalu benar dengan skrip. Lebih lanjut, ini akan menjadi cerdas tentang menghilangkan script, urutan skrip, dan penempatan skrip.
  2. Ini memungkinkan Anda untuk menggunakan PHP untuk mengirim vars ke JS.
  3. Tampaknya lebih terorganisir daripada menggunakan wp_print_stylesuntuk mencetak beberapa skrip sewenang-wenang yang ditindaklanjuti oleh skrip enqueued.

Ada beberapa hal yang tidak berfungsi seperti yang diharapkan yang membuat saya khawatir tentang metode ini. Salah satu isu tersebut adalah bahwa jika Anda menggunakan wp_localize_scriptbersama dengan $wp_scripts->add_data, Anda bisa mendapatkan hasil yang tidak diharapkan. Contohnya:

// Contrived example of database call to get a twitter handle stored in the db
$author_twitter_handle = zdt_get_twitter_handle();

$js = "var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @" . sanitize_key( $author_twitter_handle ) . "' } };\n";
$js .= 'var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };';

$wp_scripts->add_data( 'zdt-add-this', 'data', $js );
wp_localize_script( 'zdt-add-this', 'addthis_share', array( 'var' => 'val' ) );

Menghasilkan:

<script type='text/javascript'>
/* <![CDATA[ */
var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @tollmanz' } };
var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };
var addthis_share = {"var":"val"};
/* ]]> */
</script>
<script type='text/javascript' src='http://s7.addthis.com/js/250/addthis_widget.js?ver=3.4-beta4-20731#pubid=myidhere'></script>

Sedangkan skrip ini:

// Contrived example of database call to get a twitter handle stored in the db
$author_twitter_handle = zdt_get_twitter_handle();

$js = "var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @" . sanitize_key( $author_twitter_handle ) . "' } };\n";
$js .= 'var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };';

wp_localize_script( 'zdt-add-this', 'addthis_share', array( 'var' => 'val' ) );
$wp_scripts->add_data( 'zdt-add-this', 'data', $js );

Menghasilkan:

<script type='text/javascript'>
/* <![CDATA[ */
var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @tollmanz' } };
var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };
/* ]]> */
</script>
<script type='text/javascript' src='http://s7.addthis.com/js/250/addthis_widget.js?ver=3.4-beta4-20731#pubid=myidhere'></script>

The datakunci yang diatur oleh wp_localize_scriptakhirnya ditimpa oleh panggilan untuk $wp_scripts->add_data, sedangkan jika Anda memanggil wp_localize_scriptdua kali untuk script yang sama, string akan digabungkan dengan baik.

Walaupun semua ini adalah cara yang sangat berguna untuk mencetak skrip yang sewenang-wenang untuk digunakan dengan skrip enqueued, itu membuat saya berpikir bahwa itu tidak boleh digunakan secara luas karena potensi konflik. Saya pasti dapat melihat argumen untuk menggunakan ini dalam proyek pribadi di mana kode tidak akan digunakan dalam plugin / tema komunitas.

Saya juga melihat Core Trac untuk melihat apakah ada petunjuk tentang tujuan fungsi. Saya menemukan satu tiket (http://core.trac.wordpress.org/ticket/11520) (satu epik pada saat itu) yang mengeksplorasi cara lain untuk menambahkan JS sewenang-wenang. Jadi sepertinya ada minat dalam menciptakan cara yang lebih baik untuk menambahkan JS sewenang-wenang, tetapi tidak yakin persis apakah add_dataharus menjadi bagian dari proses.

Pertanyaan utama saya adalah: haruskah pengembang menggunakan fungsi ini? Dalam beberapa kasus (misalnya, wp_register_script), sepertinya fungsi "pribadi" yang tidak boleh digunakan oleh pihak ke-3; Namun, dalam kasus lain (misalnya, wp_plupload_default_settings), sepertinya cara yang masuk akal untuk menyuntikkan JS sewenang-wenang sebelum skrip enqueued.

Saya tidak membayangkan ada jawaban yang "benar" untuk ini, tetapi akan senang mendengar apa yang dipikirkan para dev lainnya. Saya juga membayangkan ada potongan-potongan pada teka-teki ini yang telah saya abaikan dan ingin mendengar apa yang orang lain katakan tentangnya.

tollmanz
sumber

Jawaban:

4

Fungsi ini menambahkan data ke skrip / gaya yang telah enqueued selama memuat WordPress.

Tidak juga. Itu menambah data ke skrip / gaya yang sudah registered.

Kunci data yang ditetapkan oleh wp_localize_scriptpada akhirnya ditimpa oleh panggilan ke $wp_scripts->add_data, sedangkan jika Anda memanggil wp_localize_scriptdua kali untuk skrip yang sama, string akan digabungkan dengan benar.

Kanan. Keduanya memanggil API yang mendasarinya (tidak dapat diakses, internal), sehingga ditimpa (seperti yang Anda nyatakan). Ini terjadi ketika panggilan $this->get_data( $handle, 'data' );.

Pertanyaan

Pertanyaan utama saya adalah: haruskah pengembang menggunakan fungsi ini?

Menjawab

Cukup berkata: Ya, ketika Anda tidak punya kesempatan lain untuk melakukan apa yang Anda butuhkan.

Contoh lain: Periksa apakah skrip terdaftar (misalnya json2/jquery) dan pindahkan ke footer (centang extra['group']).

// Move scripts to the footer - in case it isn't already there
if ( ! $wp_scripts->get_data( 'json2', 'group' ) )
    $wp_scripts->add_data( 'json2', 'group', 1 );

if ( ! $wp_scripts->get_data( 'jquery', 'group' ) )
    $wp_scripts->add_data( 'jquery', 'group', 1 );

Catatan: Ini ↑ hanya berfungsi untuk data yang diajukan di bawah extra!

Catatan tambahan

Pertanyaan Balik: Apakah Anda pernah mencoba menambahkan dependensi ke skrip yang terdaftar dengan inti? Untuk misalnya: Coba tambahkan JSON2deps yang diperlukan jQuery. Ini tidak mungkin dilakukan tanpa menyadap global $wp_scripts:

global $wp_scripts;

$scripts = array( 
     'jquery'      => array( 'json2' )
    ,'jquery-form' => array( 'json2' ) 
);

foreach ( $scripts as $handle => $deps )
{
    // Ugly hack: Intercept the global to force the "natural"/needed order: JSON2 » jQuery
    $deps_default =& $wp_scripts->registered[ $handle ]->deps;
    $wp_scripts->registered[ $handle ]->deps = array_merge( $deps_default, $deps );
}

Ada banyak hal yang tidak bisa dilakukan kelas. Jadi menggunakan sesuatu seperti ->add_data()ini adalah imo sepenuhnya valid. Cukup gunakan apa yang Anda dapatkan, karena masih lebih baik daripada hidup tanpa kelas inti.

kaisar
sumber
"Tunggu sampai core menambahkan kemungkinan untuk menambahkan dependensi ke skrip bawaan & bawaan" Apakah Anda membuka tiket di trac?
scribu
@ langganan Terima kasih, tapi tidak, saya belum dan tidak, saya tidak akan. Semua tiket saya membusuk di sana, jadi saya mundur dari upaya investasi ke tiket trac. Itu bukan pelanggaran, hanya kesimpulan dari apa yang saya alami sejauh ini. Tetapi untuk tidak mulai berdebat dengan Anda, saya akan menghapusnya karena ini hanya tersisa dari salinan / tempel sederhana dari salah satu plugin saya.
kaiser
Nah, kalau begitu saya kira saya harus bertanya di sini: apa manfaat dari memuat JSON2 sebelum jQuery?
scribu
Tidak ada, karena ini adalah contoh abstrak. Jika Anda mencoba menemukan contoh yang lebih rinci, maka Anda dapat membayangkan satu perpustakaan yang perlu JSON2, tetapi juga perlu dimuat sebelumnya jQuery: Mari beri nama UberjQuery. Btw: Ketika Anda melakukannya dengan cukup baik dengan menggali inti, mengapa Anda tidak meluangkan waktu dan menulis jawaban? Saya kira itu akan bernilai saat membaca.
kaiser
Terima kasih atas pemikiran Anda, Kaiser! Saya pasti mencari metode untuk menambahkan JS yang didukung oleh "API". Sementara saya tahu saya bisa membengkokkannya untuk melakukan segala macam hal, itu dapat menyebabkan kode tidak stabil. Sangat menyenangkan mengetahui apa yang dimaksudkan daripada apa yang bisa dilakukan, dan, tentu saja, banyak yang bisa dilakukan dengannya.
tollmanz
1

Ada perdebatan besar di WP 3.3 tentang cara menangani data skrip:

http://core.trac.wordpress.org/ticket/11520

Perhatikan bahwa Anda dapat meneruskan array bersarang ke wp_localize_data()sekarang:

wp_localize_script( 'jquery', 'jQueryL10n', array(
    'foo' => array(
        'bar' => array( 'apple', 'orange' )
    ),
) );

Jadi, saya akan menggunakan add_data()jika tidak ada API tingkat yang lebih tinggi untuk apa yang perlu saya lakukan, dengan pemahaman bahwa perilakunya mungkin berubah dalam beberapa kasus tepi, seperti ketika penyatuan terlibat.

scribu
sumber
Terima kasih atas masukan Anda Scribu! Lucu bahwa Anda menautkan ke tiket itu! Saya menautkannya di posting saya, tetapi ada banyak hal yang terjadi sehingga saya tidak mengetahui bahwa array multidimensi sekarang didukung.
tollmanz
Ha ... sunting bagus! Saya tidak bingung dengan tiket itu seperti yang saya pikirkan.
tollmanz
@tollmanz Ya, ini cukup membingungkan, terutama jika Anda tidak berada di IRC saat itu.
scribu
Mr. @ungestaltbar menunjukkan kepada saya cara untuk menambahkan array multidimensi beberapa bulan yang lalu. Tidak tahu, bahwa ini sudah dalam inti.
kaiser
@scribu - bukankah sudah ada dukungan untuk array multi-dimensi? - setidaknya saya menggunakannya tanpa masalah ...
Stephen Harris