wp pone en línea script en línea debido a dependencias

35

¿Hay alguna manera de usar wp_enqueue_script () para los scripts en línea?

Estoy haciendo esto porque mi secuencia de comandos en línea depende de otra secuencia de comandos y me gustaría la flexibilidad de insertarla después de cargarla.

Además, es un script en línea porque estoy pasando variables php al javascript (como la ruta del tema, etc.)

Gracias por adelantado.

chrisjlee
fuente

Respuestas:

33

Bueno, tienes wp_localize_script (), pero eso es solo para pasar datos.

De lo contrario, puede hacer esto:

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' );

La idea es que no debe confiar en que su script en línea se imprima exactamente después del script del que depende, sino más tarde.

scribu
fuente
44
¿Seguramente esto solo funciona si el script del que depende ya se ha publicado? Si el script del que depende también está registrado en wp_footer y se ejecuta después del código del script en línea, el script en línea simplemente no se escribirá en el cliente y, por lo tanto, ¿se ejecutará?
Sam Peacey
66
A partir de wordpress 4.5 puede usar wp_add_inline_script() wp_add_inline_script con wordpress jquery
Dhinju Divakaran
7

Esta solución es similar a la respuesta de @ scribu , pero sigue la forma de wp_enquque_script()y colocará el script en el encabezado si sus dependencias se incluyen en el encabezado.

/**
 * 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'));

Nota: esto utiliza el uso de funciones anónimas, pero para las versiones de PHP anteriores a 5.3 se puede convertir fácilmente a una clase.

Stephen M. Harris
fuente
5

Desde WordPress 4.5 puede usar 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' );
}
cybmeta
fuente
4

La mejor manera que he encontrado es usar wp_localize_script(), como sugirió @scribu.

Por lo general, decidí usar Javascript en línea porque necesitaba proporcionar algunas variables PHP a mi script. Esto se puede resolver conwp_localize_script() . Proporcionaré un ejemplo:

Tiene una matriz $aFoocon algunas opciones y necesita pasarla a un script.

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

Usando script en línea:

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

Utilizando 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' );    

Entonces, pathToScript/script.jssería:

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

De esta manera, ya no necesita scripts en línea.

Manolo
fuente
3

scribu es absolutamente correcto. De todos modos, quiero agregar alguna información:

Quiero que mi función muestre un script una vez, sin importar con qué frecuencia se llame. Es una función relacionada con el contenido, por lo que no puedo esperar a ningún gancho. Utilicé información de scribus y algunas lecturas del núcleo de WP para llegar a esto:

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);

Con este método, puedo imprimir una secuencia de comandos en línea una vez. En mi caso, tengo una función que crea un botón para compartir y necesita que se ejecute un script para todos los botones. Pero solo una vez.

Julian F. Weinert
fuente
El echoenfoque del guión en línea es cómo se construyó el tema Twenty Seventeen, al menos en un punto. Y también uso esta técnica. Funciona muy bien y le permite engancharse en diferentes lugares.
Josh Habdas