Come aggiungere il tag defer="defer" negli script javascript dei plugin?
Non riesco ad aggiungere il tag defer negli script javascript dei plugin. Il test di Google PageSpeed mi suggerisce di aggiungere il tag defer negli script di Contact Form 7.
Ecco come Contact Form 7 include javascript nell'header.
add_action( 'wp_enqueue_scripts', 'wpcf7_enqueue_scripts' );
function wpcf7_enqueue_scripts() {
// jquery.form.js originariamente incluso in WordPress è obsoleto e deprecato
// quindi dobbiamo deregistrarlo e registrare nuovamente l'ultima versione
wp_deregister_script( 'jquery-form' );
wp_register_script( 'jquery-form', wpcf7_plugin_url( 'jquery.form.js' ),
array( 'jquery' ), '2.52', true );
$in_footer = true;
if ( 'header' === WPCF7_LOAD_JS )
$in_footer = false;
wp_enqueue_script( 'contact-form-7', wpcf7_plugin_url( 'scripts.js' ),
array( 'jquery', 'jquery-form' ), WPCF7_VERSION, $in_footer );
do_action( 'wpcf7_enqueue_scripts' );
}
Come posso aggiungere il tag defer="defer" nel codice sopra riportato?

A partire da WordPress 4.1 c'è un filtro: script_loader_tag
. Puoi usarlo per trovare lo script corretto:
add_filter( 'script_loader_tag', function ( $tag, $handle ) {
if ( 'contact-form-7' !== $handle )
return $tag;
return str_replace( ' src', ' defer="defer" src', $tag );
}, 10, 2 );
Risposta precedente
Non esiste un filtro dedicato disponibile... almeno non riesco a vederne uno. Ma...
wp_print_scripts()
chiamaWP_Scripts->do_items()
- che chiama
WP_Scripts->do_item()
- che utilizza
esc_url()
- che offre un filtro:
'clean_url'
.
Ed eccoci qui:
function add_defer_to_cf7( $url )
{
if ( FALSE === strpos( $url, 'contact-form-7' )
or FALSE === strpos( $url, '.js' )
)
{ // non è il nostro file
return $url;
}
// Deve essere un ', non "!
return "$url' defer='defer";
}
add_filter( 'clean_url', 'add_defer_to_cf7', 11, 1 );
Avvertenza: non testato, solo un'idea. :)
Aggiornamento
Ho scritto e testato un plugin con questo codice.

È un bel trucco, e così semplice. Penso che sarebbe utile anche per aggiungere charset='utf-8' quando necessario!

@henrywright WordPress aggiunge '
su entrambi i lati della stringa restituita, un "
risulterebbe in HTML non valido.

Probabilmente è una buona idea, nel caso qualcuno volesse adattare questo codice per funzionare con altri script, assicurarsi di validare l'uso solo sul front-end magari usando if( ! is_admin() ){}
. Plugin popolari come ACF potrebbero causare problemi.

La risposta accettata è corretta, ma volevo apportare alcuni miglioramenti/aggiornamenti per un caso più generale, utile a chiunque, incluso il mio futuro io, che dovesse imbattersi in questa soluzione durante una ricerca. Per casi generali che non riguardano il plugin contact-form-7, dove si vuole aggiungere l'attributo defer a tutti gli script, è probabile che si voglia escluderlo dalle pagine di amministrazione, poiché queste si basano sull'esecuzione degli script in un ordine specifico. Inoltre, per le pagine non di amministrazione, è bene escludere jQuery, poiché jQuery dovrebbe probabilmente essere caricato nell'head prima di qualsiasi altro script. Inoltre, invece di manipolare la stringa del tag, un approccio migliore sarebbe caricarla in un oggetto DOMDocument, manipolarlo e poi riconvertirlo in stringa. Inoltre, le versioni più recenti di PHP supportano il type checking, quindi è consigliabile aggiungere i tipi dei parametri e del valore di ritorno nella chiamata della funzione.
<?php
add_filter('script_loader_tag', function (string $tag, string $handle, string $src):string {
if (is_admin()) {
return $tag;
}
if (in_array($handle, array('jquery-core', 'jquery-migrate'))) {
return $tag;
}
$dom = new \DomDocument();
$dom->loadHTML($tag, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$dom->getElementsByTagName('script')[0]->setAttribute("defer", "defer");
$tag = $dom->saveHTML();
return $tag;
}, 10, 3);
?>
