Le terze parti dovrebbero usare $ wp_scripts / $ wp_styles-> add_data?


31

All'interno della WP_Dependenciesclasse esiste un metodo chiamato add_data. Questa funzione aggiunge dati a script / stili accodati durante il caricamento di WordPress. Un uso comunemente citato per questa funzione è quello di aggiungere un condizionale quando si aggiungono fogli di stile destinati a diverse versioni di IE. Ad esempio, per scegliere come target IE8 e versioni precedenti:

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

Questo renderà come:

<!--[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]--> 

Quando guardo attraverso Core, vedo una manciata di luoghi in cui viene utilizzato questo metodo:

  • WP_Styles->add_inline_style(): aggiunge lo stile in linea dopo il foglio di stile di riferimento (fatto tramite WP_Styles->print_inline_style())

  • WP_Scripts->localize(): aggiunge un oggetto codificato JSON (racchiuso dalla funzione più "pubblica" wp_localize_script())

  • wp_plupload_default_settings() : aggiunge un oggetto con codifica json (creato da un array multidimensionale) per lo script 'wp-plupload' (si noti che questo è in arrivo in 3.4)

  • Quando si registrano / accodano script e stili Aggiunta di dati per script predefiniti ( wp-includes/script-loader.php)

Dalla lettura agli usi del metodo, non sembra avere un caso d'uso specifico. In wp_plupload_default_settings, sembra consentire l'inserimento di dati arbitrari. In wp_register_script, sembra essere usato per distinguere tra script di intestazione e piè di pagina. In add_inline_style, viene utilizzato per indicare lo stile in linea che deve essere aggiunto dopo l'accodamento di un foglio di stile specificato.

Un uso eccellente di questa funzione sarebbe qualcosa di simile al seguente codice in cui si sta accodando uno script esterno ma è necessario inviargli alcune configurazioni, alcune delle quali provengono dal 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' );

Ciò comporterà:

<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>

Si noti che ciò non può essere realizzato wp_localize_scriptperché l' addthis_shareoggetto ha proprietà all'interno delle proprietà (in precedenza ho già scritto un modo un po 'confuso ).

EDIT: ho sbagliato a dichiararlo. wp_localize_scriptgestisce bene le matrici multidimensionali.

Questo metodo sembra funzionare davvero bene per i seguenti motivi:

  1. Ti consente di allegare i dati all'handle dello script in modo che siano sempre correttamente corretti con lo script. Inoltre, sarà intelligente deenqueueing dello script, ordine degli script e posizionamento degli script.
  2. Ti permette di usare PHP per inviare vars a JS.
  3. Sembra più organizzato che usare wp_print_stylesper stampare qualche sceneggiatura arbitraria che viene successivamente interpretata da una sceneggiatura accodata.

Ci sono alcune cose che non funzionano come previsto e che mi preoccupano per questo metodo. Uno di questi problemi è che se lo usi wp_localize_scriptinsieme $wp_scripts->add_data, puoi ottenere risultati inaspettati. Per esempio:

// 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' ) );

produce:

<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>

Considerando che questo script:

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

produce:

<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>

La datachiave impostata da wp_localize_scriptviene infine sovrascritta dalla chiamata a $wp_scripts->add_data, mentre se si chiama wp_localize_scriptdue volte per lo stesso script, la stringa verrà concatenata correttamente.

Sebbene tutto ciò sia un modo davvero utile per stampare script arbitrari da usare con uno script accodato, mi fa pensare che non dovrebbe essere ampiamente usato a causa del potenziale di conflitti. Sicuramente vedo un argomento per usarlo in progetti personali in cui il codice non verrà utilizzato nei plugin / temi della community.

Ho anche guardato Core Trac per vedere se c'erano indizi sullo scopo della funzione. Ho trovato un biglietto (http://core.trac.wordpress.org/ticket/11520) (uno epico in quello) che ha esplorato altri modi per aggiungere JS arbitrario. Quindi sembra che ci sia interesse a creare un modo migliore per aggiungere JS arbitrari, ma non sono sicuro esattamente se add_datadovrebbe far parte del processo.

La mia domanda principale è: gli sviluppatori dovrebbero usare questa funzione? In alcuni casi (ad es. wp_register_script), Sembra una funzione "privata" che terze parti non dovrebbero usare; tuttavia, in altri casi (ad es. wp_plupload_default_settings), sembra un modo perfettamente ragionevole per iniettare JS arbitrario prima di uno script accodato.

Non immagino che ci sia una risposta "corretta" a questo, ma mi piacerebbe sentire cosa pensano gli altri sviluppatori. Immagino anche che ci siano pezzi di questo puzzle che ho completamente ignorato e mi piacerebbe sentire ciò che gli altri hanno da dire al riguardo.

Risposte:


4

Questa funzione aggiunge dati a script / stili accodati durante il caricamento di WordPress.

Non proprio. Aggiunge dati agli script / stili che sono stati registered.

La chiave dati impostata da wp_localize_scriptviene infine sovrascritta dalla chiamata a $wp_scripts->add_data, mentre se si chiama wp_localize_scriptdue volte per lo stesso script, la stringa verrà concatenata correttamente.

Destra. Entrambi chiamano l'API sottostante (non accessibile, interna), quindi viene sovrascritto (come hai affermato). Questo succede quando chiama $this->get_data( $handle, 'data' );.

Domanda

La mia domanda principale è: gli sviluppatori dovrebbero usare questa funzione?

Risposta

Detto semplicemente: Sì, quando non hai altre possibilità di fare ciò di cui hai bisogno.

Un altro esempio: controlla se uno script è stato registrato (ad es. json2/jquery) E spostalo sul piè di pagina (controlla 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 );

Nota: questo ↑ funziona solo per i dati archiviati in extra!

Note aggiuntive

Contro-domanda: hai mai provato ad aggiungere dipendenze agli script registrati dal core? Ad esempio: prova ad aggiungere JSON2i deps necessari a jQuery. Questo non è possibile senza intercettare 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 );
}

C'è un sacco di cose che la classe non può fare. Quindi, utilizzando qualcosa di simile ->add_data()è imo pienamente valida. Usa solo quello che hai, dato che è ancora meglio che vivere senza le lezioni di base.


"Aspetta che il core aggiunga la possibilità di aggiungere dipendenze agli script predefiniti e integrati" Hai aperto un ticket in trac?
scribu,

@scribu Grazie, ma no, non l'ho fatto e no, non lo farò. Tutti i miei biglietti marciscono semplicemente lì, quindi ho fatto un passo indietro dallo sforzo di investire in biglietti trac. Non è un'offesa, semplicemente una conclusione da ciò che ho vissuto finora. Ma per non iniziare a litigare con te, lo rimuoverò poiché questo è appena lasciato da una semplice copia / incolla da uno dei miei plugin.
Kaiser

Bene, allora suppongo che dovrò chiedere qui: quale sarebbe il vantaggio di caricare JSON2 prima di jQuery?
scribu,

Niente, in quanto è un esempio astratto. Se provi a trovare un esempio più dettagliato, puoi immaginare una libreria che ha bisogno JSON2, ma deve anche essere caricata prima jQuery: chiamiamola UberjQuery. Btw: Mentre stai andando abbastanza bene a scavare nel core, perché non ti prendi il tempo e scrivi una risposta? Immagino che varrebbe la pena leggere.
Kaiser

Grazie per il tuo pensiero Kaiser! Sto sicuramente cercando metodi per aggiungere JS supportato dall'API. Mentre so che posso piegarlo per fare ogni sorta di cose, questo può portare a codice instabile. È bello sapere a cosa è destinato anziché a cosa può fare e, sicuramente, si può fare molto con esso.
tollmanz,

1

C'è stato un grande dibattito in WP 3.3 su come gestire i dati degli script:

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

Nota che ora puoi passare array nidificati wp_localize_data():

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

Quindi, userei add_data()se non ci fosse un'API di livello superiore per quello che dovevo fare, con la consapevolezza che il suo comportamento potrebbe cambiare in alcuni casi limite, come quando è coinvolta la concatenazione.


Grazie per il tuo contributo Scribu! Divertente che ti colleghi a quel biglietto! Mi sono collegato ad esso nel mio post, ma c'era così tanto da fare che non ho capito che gli array multidimensionali sono ora supportati.
tollmanz,

Ah ... bella modifica! Non ero confuso da quel biglietto come pensavo.
tollmanz,

@tollmanz Sì, è abbastanza confuso, specialmente se non eri in IRC al momento.
scribu,

Il signor @ungestaltbar mi ha mostrato un modo per aggiungere array multidimensionali qualche mese fa. Non sapevo, questo è già nel nocciolo.
Kaiser,

@scribu - non esiste già supporto per array multidimensionali? - almeno li uso senza problemi ...
Stephen Harris,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.