Cum să adaugi atributul defer="defer" în scripturile JavaScript ale plugin-urilor?
Nu am putut adăuga atributul defer în scripturile JavaScript ale plugin-ului. Testul Google PageSpeed îmi sugerează să adaug atributul defer în scripturile Contact Form 7.
Iată cum include Contact Form 7 JavaScript-ul în header.
add_action( 'wp_enqueue_scripts', 'wpcf7_enqueue_scripts' );
function wpcf7_enqueue_scripts() {
// jquery.form.js inițial inclus cu WordPress este învechit și depreciat
// așa că trebuie să-l deînregistrăm și să re-înregistrăm ultima versiune
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' );
}
Acum, cum pot adăuga atributul defer="defer" în codul de mai sus?

Începând cu WordPress 4.1 există un filtru: script_loader_tag
. Îl puteți utiliza pentru a găsi scriptul corect:
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 );
Răspuns vechi
Nu există un filtru dedicat disponibil... cel puțin nu văd unul. Dar...
wp_print_scripts()
apeleazăWP_Scripts->do_items()
- care apelează
WP_Scripts->do_item()
- care folosește
esc_url()
- care are un filtru:
'clean_url'
.
Și iată cum:
function add_defer_to_cf7( $url )
{
if ( FALSE === strpos( $url, 'contact-form-7' )
or FALSE === strpos( $url, '.js' )
)
{ // nu este fișierul nostru
return $url;
}
// Trebuie să fie ', nu "!
return "$url' defer='defer";
}
add_filter( 'clean_url', 'add_defer_to_cf7', 11, 1 );
Atenție: netestat, doar o idee. :)
Actualizare
Am scris și testat un plugin cu acest cod.

Este un hack frumos și atât de simplu. Cred că ar fi bun și pentru adăugarea charset='utf-8' când este necesar!

@henrywright WordPress adaugă '
pe ambele părți ale șirului returnat, un "
ar rezulta în HTML invalid.

Probabil o idee bună, în cazul în care cineva dorește să adapteze acest lucru pentru a funcționa cu alte scripturi, ar fi să vă asigurați că validați utilizarea doar pe partea de front-end, eventual folosind if( ! is_admin() ){}
. Pluginuri populare cum ar fi ACF v-ar putea crea probleme.

Răspunsul acceptat este corect, dar am vrut să fac unele îmbunătățiri/actualizări pentru un caz mai general, pentru oricine, inclusiv pentru mine în viitor, care ar putea da peste acest lucru în timp ce caută un răspuns. Pentru cazurile generale care nu se referă la acest plugin contact-form-7, unde adăugați atributul defer la toate scripturile, probabil doriți să-l excludeți de pe paginile de administrare, deoarece acestea se bazează pe faptul că scripturile sunt executate într-o anumită ordine. De asemenea, pentru paginile non-administrative, doriți să excludeți jQuery, deoarece jQuery ar trebui încărcat în head înainte de orice altceva. În plus, în loc să manipulați șirul de tag-uri, o abordare mai bună ar fi să-l încărcați într-un obiect DOMDocument, să-l manipulați și apoi să-l convertiți înapoi într-un șir. De asemenea, versiunile mai noi de PHP au verificare de tip, așa că ar trebui să adăugați tipurile de parametri și return în apelul funcției.
<?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);
?>
