Charger un script avec une dépendance, c'est décharger la dépendance d'un autre script

9

Tout d'abord, je suis conscient que ma question se pose dans le contexte de mon travail avec le plugin WooCommerce, ce qui le rendrait normalement hors sujet. Cependant, je pense que ma question concerne wp_enqueue_script, donc j'espère qu'elle est toujours sur le sujet.

WooCommerce enregistre donc un script sur le admin_enqueue_scriptscrochet. Ce script nécessite un tas de dépendances:

wp_register_script( 'wc-admin-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes' . $suffix . '.js', array( 'jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'accounting', 'round', 'ajax-chosen', 'chosen', 'plupload-all' ), WC_VERSION );

(il est mis en file d'attente spécifiquement sur la page post.php et post-new.php pour le type de publication de produit un peu plus loin dans le code)

Dans le plugin personnalisé que j'écris pour travailler avec WooCommerce, je charge également un script sur le même crochet.

wp_enqueue_script( 'My_Plugin_Metabox', My_Plugin_Class()->plugin_url() . '/assets/js/mnm-write-panel.js', array( 'jquery', 'wc-admin-meta-boxes'), My_Plugin_Class()->version, true );

Si je mets en file d'attente le script de mon plugin et que je définis le $in_footerparamètre sur truealors inexplicablement, le script jQuery UI Datepicker n'est pas chargé (pas du tout dans le code source) et la console affiche les erreurs de script correspondantes.

Si je charge mon script dans l'en-tête, ce n'est pas un problème. Si je charge mon script sans la wc-admin-meta-boxesdépendance, cela résout également le problème

Donc, ce que je me demande, c'est pourquoi le chargement de mon script dans le pied de page affecte-t-il le chargement du script principal de datepicker? (Je n'utilise pas du tout datepicker dans mon script.) Ou pourquoi ne pas avoir le script Woo comme dépendance affecterait également le script datepicker? Il me semble que le script datepicker devrait être chargé quelle que soit la dépendance du script de la metabox Woo, mais cela ne se produit pas.

Selon le commentaire de Kaiser, j'ai créé le plugin MU suivant (ajusté à partir des commentaires car $GLOBALS['wp_scripts']c'est un objet:

/* Plugin Name: Dump jQUI Dp */ 

add_action( 'shutdown', 'so_dump_query_ui_dependencies' );
function so_dump_query_ui_dependencies() {  
    echo 'Does jQuery UI DatePicker script exist per default in&hellip;?<br>';  
    $s = 'jquery-ui-datepicker';    
    printf( 'The registered Dependencies Array: %s', isset( $GLOBALS['wp_scripts']->registered[ $s ] ) ? 'yep ' : 'nope ' );    
    printf( 'The Dependencies loaded in the footer: %s', isset( $GLOBALS['wp_scripts']->in_footer[ $s ] ) ? 'yep ' : 'nope ' );     
    printf( 'The Dependencies printed to the DOM: %s', isset( $GLOBALS['wp_scripts']->done[ $s ] ) ? 'yep ' : 'nope ' );    
    echo 'All nope? Well, then&hellip;'; 
}

Avec uniquement WooCommerce 2.2.8 actif, le résultat se lit comme suit:

Le tableau des dépendances enregistrées: yep
Les dépendances chargées dans le pied de page: nope
Les dépendances imprimées sur le DOM: nope

Avec WooCommerce 2.2.8 plus mon nouveau plugin "factice", le résultat est le même (que mon script soit chargé dans le pied de page ou non):

Le tableau des dépendances enregistrées: yep
Les dépendances chargées dans le pied de page: nope
Les dépendances imprimées sur le DOM: nope

Plugin factice

Toujours dans les commentaires, voici un plugin factice pour reproduire, espérons-le, le problème pour les autres. J'ai complètement supprimé mon plugin existant pour ne charger qu'un script sur les pages d'administration du type de publication du produit. Je vois toujours que datepicker se charge quand $in_footerest faux et ne se charge pas quand $in_footerc'est vrai.

<?php
/*
Plugin Name: WooCommerce Dummy Plugin
Plugin URI: http://wordpress.stackexchange.com/q/168688/6477
Author: helgatheviking
Description: Enqueue a script, miraculously dequeue datepicker
*/


/**
 * The Main My_Dummy_Plugin class
 **/
if ( ! class_exists( 'My_Dummy_Plugin' ) ) :

class My_Dummy_Plugin {

    /**
     * @var My_Dummy_Plugin - the single instance of the class
     */
    protected static $_instance = null;

    /**
     * variables
     */
    public $version = '1.0.0';

    /**
     * Main My_Dummy_Plugin instance.
     *
     * Ensures only one instance of My_Dummy_Plugin is loaded or can be loaded
     *
     * @static
     * @return My_Dummy_Plugin - Main instance
     */
    public static function instance() {
        if ( is_null( self::$_instance ) ) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }


    /**
     * Cloning is forbidden.
     */
    public function __clone() {
        _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?' ) );
    }


    /**
     * Unserializing instances of this class is forbidden.
     */
    public function __wakeup() {
        _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?' ) );
    }


    /**
     * My_Dummy_Plugin Constructor
     *
     * @access  public
     * @return  My_Dummy_Plugin
     */
    public function __construct() {

        add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );

    }


    /*-----------------------------------------------------------------------------------*/
    /* Helper Functions */
    /*-----------------------------------------------------------------------------------*/

    /**
     * Get the plugin url.
     *
     * @return string
     */
    public function plugin_url() {
        return untrailingslashit( plugins_url( '/', __FILE__ ) );
    }


    /**
     * Get the plugin path.
     *
     * @return string
     */
    public function plugin_path() {
        return untrailingslashit( plugin_dir_path( __FILE__ ) );
    }

    /*-----------------------------------------------------------------------------------*/
    /* Load scripts */
    /*-----------------------------------------------------------------------------------*/

    public function admin_scripts() {

        // Get admin screen id
        $screen = get_current_screen();

        // Product post type page only
        if ( in_array( $screen->id, array( 'product' ) ) ) {

            wp_enqueue_script( 'My_Dummy_Plugin_Metabox', $this->plugin_url() . '/assets/js/metabox.js', array( 'jquery', 'wc-admin-meta-boxes'), $this->version, true );

        }

    }

} //end class: do not remove or there will be no more guacamole for you

endif; // end class_exists check


/**
 * Returns the main instance of My_Dummy_Plugin
 *
 * @return WooCommerce
 */
function My_Dummy_Plugin() {
    return My_Dummy_Plugin::instance();
}

// Launch the whole plugin
My_Dummy_Plugin();
helgatheviking
la source
1
Juste curieux. Avez-vous tenté de définir la priorité de votre action en mettant vos scripts en file d'attente au-dessus ou en dessous de celle de WooCommerce lors de la mise en file d'attente dans le pied de page? J'ai rencontré des instances avec des plugins utilisant des dépendances identiques et il a annulé l'enregistrement de chaque instance, et pour une raison quelconque, cela l'a corrigé. (Je n'y ai pas beaucoup réfléchi). Je n'ai jamais fait de différence entre la mise en file d'attente dans l'en-tête et le pied de page.
BODA82
Je me demande ce qui est arrivé à tous les autres commentaires? Quoi qu'il en soit, @ BODA82, non, je n'avais pas essayé ça. Mais l'ajout d'une priorité permet de garder le chargement de datepicker correctement même lorsque $in_footerc'est vrai sur mon propre script.
helgatheviking
1
Cela ressemble à un bogue dans WP pour moi - je n'ai pas suivi la logique mais si vous regardez la fonction do_itemsdans "wp-includes / class.wp-dependencies.php", aux lignes 122-125, le code désactive simplement l'élément dans la liste to_do do_itemréussit ou non . Si vous changez ces lignes en if ( $this->do_item( $handle, $group ) ) { $this->done[] = $handle; unset( $this->to_do[$key] ); }alors le bug disparaît ...
bonger
2
Il s'agit d'un bogue WP - voir trac # 25247 . J'ai proposé un patch (gitlost c'est moi).
bonger
@bonger Merci pour la réponse définitive. Si vous vouliez déplacer votre commentaire vers une réponse, je l'accepterais. Apparemment, les dépendances sont un enfer.
helgatheviking

Réponses:

2

Actuellement, vous pouvez forcer un chargement pour les bibliothèques en utilisant wp_enqueue_script (), comme ceci:

wp_enqueue_script('jquery');
wp_enqueue_script('jquery-ui');

Je sais que cela devrait se charger automatiquement, mais cela fonctionne de cette façon.

Leo Caseiro
la source