wp enqueue inline script due to dependancies

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.

Read More

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

Thanks in advance.

Related posts

Leave a Reply

6 comments

  1. 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. 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$jsn</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.

  3. 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.

  5. 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.