40

Is there a way to use wp_enqueue_script() for inline scripts?

I'm doing this because my inline script depends on another script and i would like the flexibility of inserting it after it's loaded.

Also, It's an inline script because i'm passing php variables into the javascript (like theme path, etc)

Thanks in advance.

6 Answers 6

36

Well, you have wp_localize_script(), but that's only for passing data.

Otherwise, you can do this:

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

The idea is that you shouldn't rely on your inline script being printed exactly after the script it depends on, but later.

2
  • 4
    Surely this only works if the script you're depending on has already been output? If the script you're depending on is also registered in wp_footer, and executes after the inline script code, the inline script simply won't get written to the client, and hence executed?
    – Sam Peacey
    Commented May 31, 2014 at 4:19
  • 6
    As of wordpress 4.5 you can use wp_add_inline_script() wp_add_inline_script with wordpress jquery Commented Jun 25, 2016 at 6:41
7

Just don't make it an inline script and then pass the dynamic parameters to it as variables. Otto has written a great guide on how to do this effectively.

WordPress 3.3 will also make this more powerful: https://core.trac.wordpress.org/ticket/11520

7

This solution is similar to @scribu's answer, but it follows the form of wp_enquque_script(), and will place the script in the header if its dependencies are included in the header.

/**
 * 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: this uses use of anonymous functions, but for PHP versions prior to 5.3 this can be easily converted to a class.

7

Since WordPress 4.5 you can use 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' );
}
4

The better way I've found is using wp_localize_script(), as @scribu suggested.

Usually, I decided to use in-line Javascript because I needed to provide some PHP variables to my script. This can be solved with wp_localize_script(). I'll provide an example:

You have an array $aFoo with some options and need to pass it to a script.

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

Using in-line script:

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

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

Then, pathToScript/script.js would be:

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

In this way you don't need in-line scripts nevermore.

3

scribu is absolutely correct. Anyway, I want to add some info:

I want my function to output a script once, no matter how often it's called. It is a content-related function, so I cannot wait for any hooks. I used scribus infos and some reading of the WP core to come up with this:

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

Using this method I'm able to print an inline script once. In my case I have a function that creates a share-button and needs one script to be executed for all buttons. But only once.

1
  • The echo inline script approach is how the Twenty Seventeen theme was constructed, at least at one point. And I use this technique as well. Works great, and allows you to hook into different places.
    – vhs
    Commented Jun 1, 2017 at 1:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.