Encolar scripts en línea en WordPress debido a dependencias

4 ago 2011, 00:11:23
Vistas: 37.7K
Votos: 40

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

Estoy haciendo esto porque mi script en línea depende de otro script y me gustaría tener la flexibilidad de insertarlo después de que este se haya cargado.

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

Gracias de antemano.

Sí, puedes usar una combinación de wp_enqueue_script() y wp_add_inline_script(). Aquí te muestro cómo:

// Primero, encola el script del que dependes
wp_enqueue_script('mi-dependencia', 'ruta/a/mi-dependencia.js', array(), '1.0', true);

// Crea tu script en línea con las variables PHP
$script_inline = "
    const THEME_PATH = '" . get_template_directory_uri() . "';
    const SITE_URL = '" . site_url() . "';
    // Tu código JavaScript aquí
";

// Añade el script en línea después de la dependencia
wp_add_inline_script('mi-dependencia', $script_inline, 'after');

De esta manera, tu script en línea se cargará después de que se cargue el script del que depende, y podrás pasar variables PHP de forma segura a tu JavaScript.

0
Todas las respuestas a la pregunta 6
2
36

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

De lo contrario, puedes hacer esto:

function print_my_inline_script() {
  if ( wp_script_is( 'some-script-handle', 'done' ) ) {
?>
<script type="text/javascript">
// aquí va el código js
</script>
<?php
  }
}
add_action( 'wp_footer', 'print_my_inline_script' );

La idea es que no deberías depender de que tu script en línea se imprima exactamente después del script del que depende, sino más tarde.

4 ago 2011 01:18:38
Comentarios

¿Seguramente esto solo funciona si el script del que dependes ya ha sido cargado? Si el script del que dependes también está registrado en wp_footer, y se ejecuta después del código del script en línea, simplemente el script en línea no se escribirá en el cliente y, por lo tanto, no se ejecutará?

Sam Peacey Sam Peacey
31 may 2014 07:19:32

A partir de WordPress 4.5 puedes usar wp_add_inline_script() wp_add_inline_script con jQuery de WordPress

Dhinju Divakaran Dhinju Divakaran
25 jun 2016 09:41:03
0

Simplemente no lo conviertas en un script en línea y luego pases los parámetros dinámicos como variables. Otto ha escrito una excelente guía sobre cómo hacer esto de manera efectiva.

WordPress 3.3 también hará esto más potente: https://core.trac.wordpress.org/ticket/11520

4 ago 2011 02:02:08
0

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

/**
 * Encola JavaScript en línea. @see wp_enqueue_script().
 * 
 * ERROR CONOCIDO: Los scripts en línea no pueden ser encolados antes 
 *  que cualquier script en línea del que dependan (a menos que se coloquen
 *  en el encabezado y el dependiente en el pie de página).
 * 
 * @param string      $handle    Nombre identificador del script
 * @param string      $src       El código JavaScript
 * @param array       $deps      (opcional) Array de nombres de scripts de los que depende este script
 * @param bool        $in_footer (opcional) Si se debe encolar el script antes de </head> o antes de </body>
 * 
 * @return null
 */
function enqueue_inline_script( $handle, $js, $deps = array(), $in_footer = false ){
    // Callback para imprimir el script en línea.
    $cb = function()use( $handle, $js ){
        // Asegura que el script solo se incluya una vez.
        if( wp_script_is( $handle, 'done' ) )
            return;
        // Imprime el script y lo marca como incluido.
        echo "<script type=\"text/javascript\" id=\"js-$handle\">\n$js\n</script>\n";
        global $wp_scripts;
        $wp_scripts->done[] = $handle;
    };
    // (`wp_print_scripts` se llama en el encabezado y pie de página, pero $cb tiene protección de reinclusión.)
    $hook = $in_footer ? 'wp_print_footer_scripts' : 'wp_print_scripts';

    // Si no hay dependencias, simplemente se engancha al encabezado o pie de página.
    if( empty($deps)){
        add_action( $hook, $cb );
        return;
    }

    // Retrasa la impresión del script hasta que todas las dependencias hayan sido incluidas.
    $cb_maybe = function()use( $deps, $in_footer, $cb, &$cb_maybe ){
        foreach( $deps as &$dep ){
            if( !wp_script_is( $dep, 'done' ) ){
                // Las dependencias no están incluidas en el encabezado, intenta nuevamente en el pie de página.
                if( ! $in_footer ){
                    add_action( 'wp_print_footer_scripts', $cb_maybe, 11 );
                }
                else{
                    // Las dependencias no fueron incluidas en `wp_head` o `wp_footer`.
                }
                return;
            }
        }
        call_user_func( $cb );
    };
    add_action( $hook, $cb_maybe, 0 );
}

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

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

28 mar 2014 16:02:40
0

Desde WordPress 4.5 puedes 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', 'Tu código JavaScript inline va aquí' );
}
15 may 2016 18:18:08
0

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

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

Tienes un array $aFoo con algunas opciones y necesitas pasarlo 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'] ?>;            
    //hacer algunas cosas con oFoo
</script>

Usando wp_localize_script():

wp_register_script( 'script_name', 'pathToScript/script.js', array( 'jquery' )); //si jQuery no es necesario, simplemente elimina el último argumento.
wp_localize_script( 'script_name', 'object_name', $aFoo ); //pasa 'object_name' a script.js
wp_enqueue_script( 'script_name' );    

Entonces, pathToScript/script.js sería:

var oFoo = {};
oFoo.option1 = object_name.option1;   
oFoo.option2 = object_name.option2;            
//hacer algunas cosas con oFoo (no se necesita PHP)

De esta manera ya no necesitas scripts en línea nunca más.

18 ago 2014 17:29:45
1

scribu tiene toda la razón. De todos modos, quiero añadir algo de información:

Quiero que mi función imprima un script una sola vez, sin importar cuántas veces sea llamada. Es una función relacionada con el contenido, así que no puedo esperar por ningún hook. Usé la información de scribu y algo de lectura del núcleo de WP para llegar a esto:

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

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

29 ene 2014 14:29:13
Comentarios

El enfoque de script en línea con echo es como se construyó el tema Twenty Seventeen, al menos en algún momento. Y yo también uso esta técnica. Funciona muy bien y permite engancharse a diferentes lugares.

vhs vhs
1 jun 2017 04:05:58