php - Use wc_enqueue_js only on specific pages - nested add_action

In my plugin, I'm trying to add inline script using wc_enqueue_js only on the cart page. The rest of the plugin is

In my plugin, I'm trying to add inline script using wc_enqueue_js only on the cart page. The rest of the plugin is also executed only on the cart page.

The code below works fine, but I don't like the fact that I need to repeat if (! is_cart() ) return;. This may not look like a big issue, but my other plugin with a similar problem has several lines of conditions based on what the user selected in plugin settings, that are mixed with multiple actions:

// Run plugin.
add_action( 'template_redirect', function() use ( $args ) { ajax_cart_autoupdate( $args ); });
function ajax_cart_autoupdate( $args ) {    
    if (! is_cart() ) return; // Only if it's a cart page.  
    // Do stuff.    
}

// Enqueue js script inline using wc_enqueue_js.
add_action( 'template_redirect', function() use ( $args ) { acau_enqueue_script ( $args ); });
function acau_enqueue_script( $args ) { 
    if (! is_cart() ) return; // Only if it's a cart page.  
    wc_enqueue_js( '    
        <<<my jquery code>>>
    ' );    
}

The following doesn't work - the inline script doesn't appear in the HTML:

// Run plugin.
add_action( 'template_redirect', function() use ( $args ) { ajax_cart_autoupdate( $args ); });
function ajax_cart_autoupdate( $args ) {
    if (! is_cart() ) return; // Only if it's a cart page.
    // Enqueue js script inline using wc_enqueue_js.
    add_action( 'template_redirect', function() use ( $args ) { acau_enqueue_script ( $args ); });
    // Do stuff.    
}

function acau_enqueue_script( $args ) { 
    wc_enqueue_js( '    
        <<<my jquery code>>>
    ' );    
}

The following works, but the inline script appears in the HTML twice (one script directly below the other). If I put echo 'test'; in the first line of function acau_enqueue_script, it appears only one time on page:

// Run plugin.
add_action( 'template_redirect', function() use ( $args ) { ajax_cart_autoupdate( $args ); });
function ajax_cart_autoupdate( $args ) {
    if (! is_cart() ) return; // Only if it's a cart page.
    // Enqueue js script inline using wc_enqueue_js.
    add_action( 'wp_enqueue_script', function() use ( $args ) { acau_enqueue_script ( $args ); });
    // Do stuff.    
}

function acau_enqueue_script( $args ) { 
    wc_enqueue_js( '    
        <<<my jquery code>>>
    ' );    
}

Is there any smart way to make it work without repeating page conditions?

In my plugin, I'm trying to add inline script using wc_enqueue_js only on the cart page. The rest of the plugin is also executed only on the cart page.

The code below works fine, but I don't like the fact that I need to repeat if (! is_cart() ) return;. This may not look like a big issue, but my other plugin with a similar problem has several lines of conditions based on what the user selected in plugin settings, that are mixed with multiple actions:

// Run plugin.
add_action( 'template_redirect', function() use ( $args ) { ajax_cart_autoupdate( $args ); });
function ajax_cart_autoupdate( $args ) {    
    if (! is_cart() ) return; // Only if it's a cart page.  
    // Do stuff.    
}

// Enqueue js script inline using wc_enqueue_js.
add_action( 'template_redirect', function() use ( $args ) { acau_enqueue_script ( $args ); });
function acau_enqueue_script( $args ) { 
    if (! is_cart() ) return; // Only if it's a cart page.  
    wc_enqueue_js( '    
        <<<my jquery code>>>
    ' );    
}

The following doesn't work - the inline script doesn't appear in the HTML:

// Run plugin.
add_action( 'template_redirect', function() use ( $args ) { ajax_cart_autoupdate( $args ); });
function ajax_cart_autoupdate( $args ) {
    if (! is_cart() ) return; // Only if it's a cart page.
    // Enqueue js script inline using wc_enqueue_js.
    add_action( 'template_redirect', function() use ( $args ) { acau_enqueue_script ( $args ); });
    // Do stuff.    
}

function acau_enqueue_script( $args ) { 
    wc_enqueue_js( '    
        <<<my jquery code>>>
    ' );    
}

The following works, but the inline script appears in the HTML twice (one script directly below the other). If I put echo 'test'; in the first line of function acau_enqueue_script, it appears only one time on page:

// Run plugin.
add_action( 'template_redirect', function() use ( $args ) { ajax_cart_autoupdate( $args ); });
function ajax_cart_autoupdate( $args ) {
    if (! is_cart() ) return; // Only if it's a cart page.
    // Enqueue js script inline using wc_enqueue_js.
    add_action( 'wp_enqueue_script', function() use ( $args ) { acau_enqueue_script ( $args ); });
    // Do stuff.    
}

function acau_enqueue_script( $args ) { 
    wc_enqueue_js( '    
        <<<my jquery code>>>
    ' );    
}

Is there any smart way to make it work without repeating page conditions?

Share Improve this question edited Aug 14, 2019 at 4:41 Ryszard Jędraszyk asked Aug 14, 2019 at 0:55 Ryszard JędraszykRyszard Jędraszyk 3244 silver badges17 bronze badges 1
  • No idea why, but for the second snippet, changing the priority of the nested add_action from the default (10) to 20, causing the parent and child add_action to have a different priority solved the problem and now everything works perfectly: add_action( 'template_redirect', function() use ( $args ) { acau_enqueue_script ( $args ); }, 20); I would be grateful for an answer why this is the case. – Ryszard Jędraszyk Commented Aug 14, 2019 at 1:43
Add a comment  | 

1 Answer 1

Reset to default 2

No idea why, but for the second snippet, changing the priority of the nested add_action from the default (10) to 20, causing the parent and child add_action to have a different priority solved the problem and now everything works perfectly: add_action( 'template_redirect', function() use ( $args ) { acau_enqueue_script ( $args ); }, 20);

The reason is quite simple. Because WordPress supports nested hooks, which means you can add another callback to the same/parent hook (e.g. template_redirect in your case), and the additional callback would be called if the priority is greater than the parent callback's priority.

  • Case 1: In this case, only the some_func2() that would be executed. Because its priority is 12, which is greater than the parent callback (i.e. the closure).

    add_action( 'template_redirect', function(){
        add_action( 'template_redirect', 'some_func', 11 );  // first child hook
        add_action( 'template_redirect', 'some_func2', 12 ); // second child hook
    }, 11 ); // parent hook
    
  • Case 2: In this case, both some_func() and some_func2() would be executed. Because their priority is, once again, greater than the parent callback's.

    add_action( 'template_redirect', function(){
        add_action( 'template_redirect', 'some_func', 11 );  // first child hook
        add_action( 'template_redirect', 'some_func2', 12 ); // second child hook
    } ); // parent hook with the default priority (10)
    

So when registering nested hooks, make sure the callback's priority is greater than the parent's.

Alternatives to using nested hooks

So this is specific to the original question about wc_enqueue_js() only on the cart page.

You can try one of these, which worked well for me:

  • Hook to wp, then hook acau_enqueue_script() to template_redirect:

    add_action( 'wp', function(){
        if ( is_cart() ) {
            add_action( 'template_redirect', 'acau_enqueue_script' );
        }
    } );
    
  • Hook to template_redirect, then hook acau_enqueue_script to wp_footer (WooCommerce uses this hook to print custom JavaScript code added via wc_enqueue_js()):

    add_action( 'template_redirect', function(){
        if ( is_cart() ) {
            add_action( 'wp_footer', 'acau_enqueue_script' );
        }
    } );
    

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745244540a4618351.html

相关推荐

  • php - Use wc_enqueue_js only on specific pages - nested add_action

    In my plugin, I'm trying to add inline script using wc_enqueue_js only on the cart page. The rest of the plugin is

    5小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信