web-dev-qa-db-fra.com

wp met en file d'attente le script en ligne en raison de dépendances

Est-il possible d'utiliser wp_enqueue_script () pour les scripts en ligne?

Je le fais parce que mon script en ligne dépend d'un autre script et j'aimerais pouvoir l'insérer après l'avoir chargé.

En outre, c'est un script en ligne parce que je passe des variables php dans le javascript (comme le chemin du thème, etc.)

Merci d'avance.

35
chrisjlee

Eh bien, vous avez wp_localize_script (), mais ce n'est que pour transmettre des données.

Sinon, vous pouvez faire ceci:

function print_my_inline_script() {
  if ( wp_script_is( 'some-script-handle', 'done' ) ) {
?>
<script type="text/javascript">
// js code goes here
</script>
<?php
  }
}
add_action( 'wp_footer', 'print_my_inline_script' );

L'idée est que vous ne devriez pas vous fier à l'impression de votre script en ligne exactement après le script dont il dépend, mais plus tard.

33
scribu

Cette solution est similaire à answer de @ scribu, mais elle suit la forme de wp_enquque_script() et placera le script dans l'en-tête si ses dépendances sont incluses dans l'en-tête.

/**
 * Enqueue inline Javascript. @see wp_enqueue_script().
 * 
 * KNOWN BUG: Inline scripts cannot be enqueued before 
 *  any inline scripts it depends on, (unless they are
 *  placed in header, and the dependant in footer).
 * 
 * @param string      $handle    Identifying name for script
 * @param string      $src       The JavaScript code
 * @param array       $deps      (optional) Array of script names on which this script depends
 * @param bool        $in_footer (optional) Whether to enqueue the script before </head> or before </body> 
 * 
 * @return null
 */
function enqueue_inline_script( $handle, $js, $deps = array(), $in_footer = false ){
    // Callback for printing inline script.
    $cb = function()use( $handle, $js ){
        // Ensure script is only included once.
        if( wp_script_is( $handle, 'done' ) )
            return;
        // Print script & mark it as included.
        echo "<script type=\"text/javascript\" id=\"js-$handle\">\n$js\n</script>\n";
        global $wp_scripts;
        $wp_scripts->done[] = $handle;
    };
    // (`wp_print_scripts` is called in header and footer, but $cb has re-inclusion protection.)
    $hook = $in_footer ? 'wp_print_footer_scripts' : 'wp_print_scripts';

    // If no dependencies, simply hook into header or footer.
    if( empty($deps)){
        add_action( $hook, $cb );
        return;
    }

    // Delay printing script until all dependencies have been included.
    $cb_maybe = function()use( $deps, $in_footer, $cb, &$cb_maybe ){
        foreach( $deps as &$dep ){
            if( !wp_script_is( $dep, 'done' ) ){
                // Dependencies not included in head, try again in footer.
                if( ! $in_footer ){
                    add_action( 'wp_print_footer_scripts', $cb_maybe, 11 );
                }
                else{
                    // Dependencies were not included in `wp_head` or `wp_footer`.
                }
                return;
            }
        }
        call_user_func( $cb );
    };
    add_action( $hook, $cb_maybe, 0 );
}

// Usage
enqueue_inline_script('test','alert(\'enqueue inline script test\');',array( 'jquery'));

Note: ceci utilise des fonctions anonymes, mais pour PHP versions antérieures à 5.3, ceci peut être facilement converti en classe.

7
Stephen M. Harris

Il suffit de ne pas en faire un script en ligne, puis de lui transmettre les paramètres dynamiques en tant que variables. Otto a écrit un excellent guide sur la manière de le faire efficacement.

WordPress 3.3 rendra également cela plus puissant: https://core.trac.wordpress.org/ticket/11520

7
Viper007Bond

Depuis WordPress 4.5, vous pouvez utiliser wp_add_inline_script () :

add_action( 'wp_enqueue_scripts', 'cyb_enqueue_scripts' );
function cyb_enqueue_scripts() {
   wp_enqueue_script( 'myscript', 'url/to/myscript.js', array(), '1.0' );
   wp_add_inline_script( 'myscript', 'Your inline javascript code gos here' );
}
5
cybmeta

La meilleure façon que j'ai trouvée consiste à utiliser wp_localize_script(), comme @scribu l'a suggéré.

D'habitude, j'ai décidé d'utiliser le Javascript en ligne car je devais fournir des variables PHP à mon script. Ceci peut être résolu avec wp_localize_script(). Je vais donner un exemple:

Vous avez un tableau $aFoo avec quelques options et vous devez le transmettre à un script.

$aFoo = array( 'option1' => $option1Value, 'option2' => $option2Value ); 

Utiliser un script en ligne:

<script> 
    var oFoo = {};
    oFoo.option1 = <?php echo $aFoo['option1'] ?>;  
    oFoo.option2 = <?php echo $aFoo['option2'] ?>;            
    //do some stuff with oFoo
</script>

Utilisation de wp_localize_script():

wp_register_script( 'script_name', 'pathToScript/script.js', array( 'jquery' )); //if jQuery is not needed just remove the last argument. 
wp_localize_script( 'script_name', 'object_name', $aFoo ); //pass 'object_name' to script.js
wp_enqueue_script( 'script_name' );    

Alors, pathToScript/script.js serait:

var oFoo = {};
oFoo.option1 = object_name.option1;   
oFoo.option2 = object_name.option2;            
//do some stuff with oFoo (no PHP needed)

De cette façon, vous n'avez plus jamais besoin de scripts en ligne.

4
Manolo

scribu est absolument correct. Quoi qu'il en soit, je veux ajouter quelques informations:

Je veux que ma fonction génère un script une fois, quelle que soit la fréquence à laquelle il est appelé. C'est une fonction liée au contenu, je ne peux donc pas attendre de hooks. J'ai utilisé scribus infos et un peu de lecture du WP core pour en arriver à ceci:

function print_script_once() {
    if(!wp_script_is('my-handle', 'done')) {
        echo "<script>alert('once!');</script>";
        global $wp_scripts;
        $wp_scripts->done[] = 'my-handle';
    }
}
add_action('get_footer', print_script_once);

En utilisant cette méthode, je suis capable d'imprimer un script en ligne une fois. Dans mon cas, j'ai une fonction qui crée un bouton de partage et nécessite qu'un script soit exécuté pour tous les boutons. Mais une seule fois.

3
Julian F. Weinert