skip to Main Content

I’m creating a plugin for WordPress, when I use below code in plugin main file it load js in <head>, it works fine.

wp_enqueue_script ( 'custom-script', 'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-v4- rtl/4.6.0-1/js/bootstrap.bundle.min.jsf');

but when I use it inside a function (for example show_form() ):

function show_form()
{
    wp_enqueue_script ( 'custom-script', 'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-v4- rtl/4.6.0-1/js/bootstrap.bundle.min.js');
    require_once 'form.php';
}

it loads script at the bottom of the page (before </body>).
what’s wrong with my code?
I need to enqueue script inside the <head> only when my form.php loads.
I know I can load script directly in form.php but i need to load script via wp_enqueue_script

2

Answers


  1. When show_form() is called, you’re already too far along in the execution path to go back and insert code into the head section.

    Any JS you want to load should be fired on the wp_enqueue_scripts action. wp_enqueue_script() can be used to determine whether code loads in the head or footer of the site.

    If there are two points at which you can insert code using wp_enqueue_script() and it’s being inserted into the footer even though you haven’t specified that, it’s because you’re calling enqueue script after the head scripts have been inserted.

    You need to either determine whether a form is shown on the page earlier in the loading of the page or use your JS in a way that can be supported across the site.

    Example:

    function wpse_enqueue_form_scripts() {
        if ( has_form() ) { // EXAMPLE... You need a way of determining this
            wp_enqueue_script( 'custom-script', 'js url...');
        }
    }
    add_action( 'wp_enqueue_scripts', 'wpse_enqueue_form_scripts' );
    
    Login or Signup to reply.
  2. You’re not following best practices.

    Any script should be added to the WordPress firing sequence via wp_enqueue_scripts() firing hook.

    Fires when scripts and styles are enqueued.

    Furthermore, when you take a look at the wp_enqueue_script() function CODEX page you can see that it accept a bunch of arguments including a $in_footer variable.

    $in_footer

    (bool) (Optional) Whether to enqueue the script before instead of in the . Default false.

    As a reminder you can also set a $deps variable.

    $deps

    (string[]) (Optional) An array of registered script handles this script depends on. Default value: array().

    The proper way to enqueue for example Bootstrap 4.6.0 (in your case) is to add a dependency to Jquery and load both of them in the footer, not the header. As most of the time any related js action are unnecessary before the DOM as been fully loaded. In the following example I will be enqueuing both Jquery and Bootstrap in the footer, tho you can alway change true to false.

    As you’re using a CDN you should be checking is the source is available and have a fallback locally waiting. you should also include integrity and crossorigin attributes.

    add_action( 'wp_enqueue_scripts', 'plugin_scripts' );
    function plugin_scripts() {
            /**
            * Deregister WordPress jquery core version.
            * @link https://developer.wordpress.org/reference/functions/wp_deregister_script/
            */
            wp_deregister_script( 'jquery' );
    
    
            /**
            * Register then enqueue jquery_js (Bootstrap 4.6.x required).
            * @link https://developer.wordpress.org/reference/functions/wp_register_script/
            * @link https://developer.wordpress.org/reference/functions/wp_enqueue_script/
            *
            * Check if CDN's url is valid, if not return fallback.
            * @link https://www.php.net/manual/en/function.fopen.php
            *
            * Add rel='preload prefetch' <link> and required attributes to bootstrap_bundle_js.
            * Filters the HTML link tag of an enqueued style & add required attributes.
            * @link https://developer.wordpress.org/reference/hooks/script_loader_tag/
            */
            $url_jquery_js = 'https://code.jquery.com/jquery-3.5.1.slim.min.js';
            $ver_jquery_js = '3.5.1-slim-min';
            $tst_jquery_js = @fopen( $url_jquery_js, 'r' );
            $hnd_jquery_js = 'jquery_js';
    
            if ( $tst_jquery_js !== false )
                wp_register_script( $hnd_jquery_js, $url_jquery_js, [], $ver_jquery_js, true );
            else
                wp_register_script( $hnd_jquery_js, trailingslashit( get_template_directory_uri() ) . 'assets/js/jquery-3.5.1.slim.min.js', [], $ver_jquery_js, true );
    
            wp_enqueue_script( $hnd_jquery_js );
            
            add_filter( 'script_loader_tag', 'data_jquery_js', 10, 3 );
            function data_jquery_js( $tag, $handle, $src ) {
                if ( $handle === 'jquery_js' ) {
                    $integrity = 'sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj';
                    $tag = str_replace(
                        [ "<script", 
                        "></script>", ],
                        [ "<link rel='preload prefetch' href='" . esc_url( $src ) . "' as='script' integrity='" . $integrity . "' crossorigin='anonymous' />" . PHP_EOL . "<script", 
                        "integrity='" . $integrity . "' crossorigin='anonymous'></script>", ],
                        $tag
                    );
                };
                return $tag;
            };
    
            /**
            * Register then enqueue bootstrap_bundle_js (Bootstrap 4.6.x required).
            * @link https://developer.wordpress.org/reference/functions/wp_register_script/
            * @link https://developer.wordpress.org/reference/functions/wp_enqueue_script/
            *
            * Check if CDN's url is valid, if not return fallback.
            * @link https://www.php.net/manual/en/function.fopen.php
            *
            * Add rel='preload prefetch' <link> and required attributes to bootstrap_bundle_js.
            * Filters the HTML link tag of an enqueued style & add required attributes.
            * @link https://developer.wordpress.org/reference/hooks/script_loader_tag/
            */
            $url_bootstrap_bundle_js = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js';
            $ver_bootstrap_bundle_js = '4.6.0';
            $tst_bootstrap_bundle_js = @fopen( $url_bootstrap_bundle_js, 'r' );
            $hnd_bootstrap_bundle_js = 'bootstrap_bundle_js';
    
            if ( $tst_bootstrap_bundle_js !== false )
                wp_register_script( $hnd_bootstrap_bundle_js, $url_bootstrap_bundle_js, [ 'jquery_js', ], $ver_bootstrap_bundle_js, true );
            else
                wp_register_script( $hnd_bootstrap_bundle_js, trailingslashit( get_template_directory_uri() ) . 'assets/js/bootstrap.bundle.min.js', [ 'jquery_js', ], $ver_bootstrap_bundle_js, true );
    
            wp_enqueue_script( $hnd_bootstrap_bundle_js );
            
            add_filter( 'script_loader_tag', 'data_bootstrap_bundle_js', 10, 3 );
            function data_bootstrap_bundle_js( $tag, $handle, $src ) {
                if ( $handle === 'bootstrap_bundle_js' ) {
                    $integrity = 'sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns';
                    $tag = str_replace(
                        [ "<script", 
                        "></script>", ],
                        [ "<link rel='preload prefetch' href='" . esc_url( $src ) . "' as='script' integrity='" . $integrity . "' crossorigin='anonymous' />" . PHP_EOL . "<script", 
                        "integrity='" . $integrity . "' crossorigin='anonymous'></script>", ],
                        $tag
                    );
                };
                return $tag;
            };
    
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search