wp enfileirar script em linha devido a dependências

35

Existe uma maneira de usar wp_enqueue_script () para scripts embutidos?

Estou fazendo isso porque meu script in-line depende de outro script e gostaria de ter a flexibilidade de inseri-lo depois que ele for carregado.

Além disso, é um script in-line porque eu estou passando variáveis php para o javascript (como caminho do tema, etc)

Obrigado antecipadamente.

    
por chrisjlee 03.08.2011 / 23:11

6 respostas

33

Bem, você tem wp_localize_script (), mas isso é apenas para passar dados.

Caso contrário, você pode fazer isso:

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

A idéia é que você não deve confiar em seu script in-line sendo impresso exatamente após o script do qual ele depende, mas depois.

    
por scribu 04.08.2011 / 00:18
7

Apenas não o torne um script in-line e passe os parâmetros dinâmicos para ele como variáveis. Otto escreveu um ótimo guia sobre como fazer isso de forma eficaz.

O WordPress 3.3 também tornará isso mais poderoso: enlace

    
por Viper007Bond 04.08.2011 / 01:02
7

Esta solução é semelhante à resposta do @ scribu, mas segue a forma de wp_enquque_script() e coloque o script no cabeçalho se suas dependências estiverem incluídas no cabeçalho.

/**
 * 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: isso usa o uso de funções anônimas, mas para versões do PHP anteriores a 5.3 isso pode ser facilmente convertido para uma classe.

    
por Stephen M. Harris 28.03.2014 / 15:02
4

A melhor maneira que encontrei é usar wp_localize_script() , como sugerido @scribu.

Normalmente, eu decidi usar o Javascript em linha porque eu precisava fornecer algumas variáveis PHP para o meu script. Isso pode ser resolvido com wp_localize_script() . Eu vou dar um exemplo:

Você tem uma matriz $aFoo com algumas opções e precisa passá-la para um script.

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

Usando o script in-line:

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

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

Então, pathToScript/script.js seria:

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

Desta forma, você não precisa mais de scripts in-line.

    
por Manolo 18.08.2014 / 16:29
4

Desde o WordPress 4.5, você pode 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' );
}
    
por cybmeta 15.05.2016 / 17:18
3

scribu está absolutamente correto. De qualquer forma, quero adicionar algumas informações:

Eu quero que minha função gere um script uma vez, não importa com que frequência ele seja chamado. É uma função relacionada ao conteúdo, então não posso esperar por nenhum gancho. Eu usei infas scribus e alguma leitura do núcleo do WP para chegar a este:

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

Usando esse método, posso imprimir um script in-line uma vez. No meu caso eu tenho uma função que cria um botão de compartilhamento e precisa de um script para ser executado para todos os botões. Mas apenas uma vez.

    
por Julian F. Weinert 29.01.2014 / 13:29