Quand utiliser add_action ('init') vs add_action ('wp_enqueue_scripts')

10

Dans le fichier functions.php de mon thème, j'appelle une add_action afin d'obtenir une mesure de contrôle sur l'endroit où jquery est chargé (dans le pied de page avec les autres scripts de mon thème).

Le problème que j'ai est que lorsque j'utilise add_action ('wp_enqueue_scripts'), il ne semble se déclencher que si aucun plugin n'est chargé. Cependant, la méthode add_action ('init') fonctionne dans tous les cas.

Je ne me souviens pas pourquoi, mais je crois que add_action ('wp_enqueue_scripts') est préféré dans ce cas. Si c'est vrai, comment puis-je le faire fonctionner dans tous les cas?

Dans functions.php

//if(!is_admin()){add_action('init', 'my_theme_init');} //THIS WORKS ALL THE TIME
//add_action('wp_enqueue_scripts', 'my_theme_init'); //THIS ONLY WORKS WHEN NO PLUGINS PRESENT

if(!is_admin())
{
    require_once(TEMPLATEPATH . '/functions_public.php');   
}

Dans functions_public.php

function my_theme_init()
{

/* PREVENT DUPLICATE COPIES OF JQUERY FROM PLUGINS
**************************************************/
wp_deregister_script('jquery');

/* LOAD THE LOCAL WORDPRESS COPY OF JQUERY AND THEME CUSTOM SCRIPTS IN THE FOOTER
***********************************************/
wp_register_script('jquery', get_bloginfo('template_directory').'/scripts.mythemescripts.js',false,false,true);

wp_enqueue_script('jquery');

}

La 2ème méthode, utilisant add_action ('wp_enqueue_scripts'), n'est apparemment pas exécutée dans des conditions où un plugin est présent qui écrit des dépendances de script dans le thème.

N2Mystic
la source
5
Veuillez ne pas enregistrer votre propre copie de jquery - utilisez la version fournie avec WordPress, sinon vous finirez par casser des plug-ins :)
Stephen Harris
Je suis d'accord, en fait j'utilise celui livré avec jQuery. Je le charge juste dans un seul .js (mythemescripts.js) avec les autres fichiers js dont mon thème a besoin, afin de réduire les requêtes http.
N2Mystic
Dans tous les navigateurs, une fois que le script est demandé une fois à votre site, il est mis en cache localement. Vous n'aurez que la demande HTTP supplémentaire lors du tout premier chargement de page. Si vous combinez tous les scripts en un seul, vous serez obligé de le changer à chaque fois que WP publiera une mise à jour avec une nouvelle version de jQuery. Ce cauchemar de maintenance ==.
EAMann
2
@EAMann, lorsque le thème est installé pour la première fois, et chaque fois que ma page d'options de thème est enregistrée par la suite, je réécris le mythemescripts.js, en y chargeant la dernière copie de la bibliothèque jquery. Si l'utilisateur met à jour sa version WP, ma routine d'options de thème charge le jquery qui l'accompagne. C'est toujours à jour.
N2Mystic
Le problème se produit toujours lorsqu'un appel jquery est contenu dans le corps du document avant le pied de page. Apparemment, jQuery (document) .ready se déclenche avant que le script .js ne soit chargé dans le pied de page.
N2Mystic

Réponses:

26

Beaucoup de développeurs de plugins ne font pas les choses correctement. La bonne façon est de vous accrocher à ce wp_enqueue_scriptsque vous essayez de faire.

Cependant, voici l'ordre des hooks exécutés dans une demande typique:

  • muplugins_loaded
  • Registered_taxonomy
  • registered_post_type
  • plugins_loaded
  • sanitize_comment_cookies
  • setup_theme
  • load_textdomain
  • after_setup_theme
  • auth_cookie_malformed
  • auth_cookie_valid
  • set_current_user
  • init
  • widgets_init
  • register_sidebar
  • wp_register_sidebar_widget
  • wp_default_scripts
  • wp_default_stypes
  • admin_bar_init
  • add_admin_bar_menus
  • wp_loaded
  • parse_request
  • send_headers
  • parse_query
  • pre_get_posts
  • posts_selection
  • wp
  • template_redirect
  • get_header
  • wp_head
  • wp_enqueue_scripts
  • wp_print_styles
  • wp_print_scripts
  • ... beaucoup plus

Le fait est que plusieurs développeurs devaient à l'origine se connecter à la mise en initfile d'attente de leurs scripts. Avant que nous ayons eu un wp_enqueue_scriptcrochet, c'était la façon "correcte" de faire les choses, et les didacticiels perpétuant la pratique flottent toujours sur Internet corrompant les bons développeurs autrement.

Ma recommandation serait de diviser votre fonction en deux parties. Faites votre wp_deregister_script/ wp_register_scriptsur le initcrochet et utilisez-le wp_enqueue_scriptslorsque vous mettez jQuery en file d'attente.

Cela vous gardera dans le monde du «bien faire» pour mettre vos scripts en file d'attente, et vous aidera à vous protéger contre les centaines de développeurs qui «font encore mal» en échangeant jQuery pour votre version concaténée avant de l'ajouter à la file d'attente .

Vous voudrez également ajouter votre initcrochet avec une priorité élevée:

add_action( 'init', 'swap_out_jquery', 1 );
function swap_out_jquery() {
    // ...
}
EAMann
la source
2
J'allais le recommander, mais je me suis alors rendu compte que l'OP annulait réellement l'enregistrement de jQuery, puis enregistrait entièrement un script différent et l'appelait "jquery". Je ne pense pas que ce soit une bonne pratique à encourager, et je pense qu'un meilleur itinéraire serait simplement de retirer entièrement jQuery , puis de mettre en file d'attente le script personnalisé à l' aide d'un handle personnalisé .
Chip Bennett
Point à noter sur l' priorityajout d'actions. Tout dépend de la façon dont vous voyez la priorité. Si vous souhaitez que le vôtre s'exécute "en premier", un nombre inférieur est préférable - une priorité plus élevée dans l'ordre de la file d'attente d'exécution. Mais si vous voulez que l'effet de votre fonction prenne le pas sur les autres, vous voudrez qu'elle s'exécute plus tard - donc une priorité plus élevée par "effet". Et dans ce cas, c'est probablement un nombre plus élevé que vous souhaitez. Même s'il n'y a pas grand intérêt à échanger la version RTM de jquery, comme le suggère le commentateur précédent.
Paul G.
3

Il y a plusieurs problèmes ici, qui sont interdépendants.

  1. Le crochet d'action correct à utiliser pour mettre les scripts en file d'attente est wp_enqueue_scripts
  2. Pour imprimer des scripts dans le pied de page via wp_enqueue_script(), définissez le $footerparamètre surtrue
  3. Vos add_action( $hook, $callback )appels ne doivent être enveloppés dans rien; laissez-les s'exécuter directement à partir defunctions.php
  4. Vous devriez mettre vos is_admin()vérifications conditionnelles dans votre rappel
  5. Vous ne devez pas désenregistrer les scripts groupés d'un thème, pour quelque raison que ce soit. Même si votre objectif est la concaténation de scripts, c'est le territoire du plugin .
  6. Si vous devez annuler l'enregistrement de jquery, il wp_enqueue_scriptsest trop tard . Divisez votre code de désenregistrement / d'enregistrement en un rappel connecté init.
  7. Appeler un autre script "jquery" n'est probablement pas non plus une bonne pratique. Votre meilleur pari serait simplement de retirer de la file d' attente jQuery , puis de charger votre script personnalisé.
  8. Assurez-vous de donner une faible priorité à votre rappel, afin de remplacer les plugins
  9. Utilisez get_template_directory()plutôt queTEMPLATEPATH

Mettre tous ensemble:

<?php
function wpse55924_enqueue_scripts() {
    if ( ! is_admin() ) {

        // Dequeue jQuery
        wp_dequeue_script( 'jquery' );

        // Register/enqueue a custom script, that includes jQuery
        wp_register_script( 'mythemescripts', get_template_directory_uri() . '/scripts.mythemescripts.js', false, false,true );
        wp_enqueue_script( 'mythemescripts' ); 
    }
}
add_action( 'wp_enqueue_scripts', 'wpse55924_enqueue_scripts', 99 );

Mais encore une fois: ce n'est vraiment pas la meilleure approche. Votre meilleur pari est simplement de supprimer les rappels du plugin add_action () qui désenregistrent le noyau jQuery - ou d'utiliser des plugins qui ne font pas quelque chose d'aussi imprudent que de remplacer le jQuery intégré au noyau.

Chip Bennett
la source
L'OP combine la version WP-distribuée de jQuery avec d'autres scripts par programmation afin qu'une seule requête HTTP soit faite par son thème pour charger tous les fichiers JS. Ainsi, les scripts personnalisés contiennent jQuery et ne cassent rien s'ils sont chargés de cette façon. Il est nécessaire d'écraser le descripteur 'jquery' enregistré pour éviter de charger jQuery deux fois - une fois dans le fichier JS combiné et à nouveau par tous les plugins qui tentent de mettre en file d'attente jQuery par eux-mêmes.
EAMann
Il s'agit sémantiquement et pratiquement _doing_it_wrong()d'appeler quelque chose qui n'est pas seulement jQuery "jQuery". Aussi: jQuery lui-même peut simplement être retiré de la file d'attente afin de s'assurer qu'il n'est pas chargé deux fois. L' wp_dequeue_script()appel doit simplement se produire avec une priorité suffisante pour garantir que rien ne le met en file d'attente par la suite.
Chip Bennett