0

I'm trying to remove the navigation between products that appears right after the product title in my products pages.

The navigation is set in the woocommerce.php file of my theme:

/**
 * Class for all WooCommerce template modification
 *
 * @version 1.0
 */
class MrBara_WooCommerce {

    ...

    /**
     * Hooks to WooCommerce actions, filters
     *
     * @since  1.0
     * @return void
     */
    function hooks() {
        ...

        // Add prev/next product
        if ( in_array( mrbara_theme_option( 'product_page_layout' ), array( '1', '2', '8', '9', '12' ) ) ) {
            add_action( 'woocommerce_single_product_summary', array( $this, 'products_links' ), 0 );
        }

        ...

    /**
     * Display products link
     *
     * @since 1.0
     */
    function products_links() {
        if ( function_exists( 'is_product' ) && ! is_product() ) {
            return;
        }

        $prev_link = '<span class="ion-ios-arrow-back"></span>';
        $next_link = '<span class="ion-ios-arrow-forward"></span>';

        ...

        ?>
        <div class="products-links">
            <?php
            previous_post_link( '<div class="nav-previous">%link</div>', $prev_link );
            next_post_link( '<div class="nav-next">%link</div>', $next_link );
            ?>
        </div>
        <?php
    }
}

I'm just starting understand how Wordpress work, and for what I've learn until now, I think I have to remove the action products_links.

Test 1

So, in my functions.php in my child theme, I've wrote this:

// Remove previous and next link in the product title
add_action('woocommerce_single_product_summary', 'remove_products_links');
function remove_products_links() {
    remove_action('products_links', 'woocommerce_single_product_summary' );
}

I added my "remove function" to the woocommerce_single_product_summary as the action that adds the products links is hooked to it.

But this doesn't work.

So I gone deeper in the documentation

But this not worked.

So, digging deeper in the Wordpress' documentation, I read this:

If an action has been added from within a class, for example by a plugin, removing it will require accessing the class through a variable that holds the class instance. Unless the function is static in which case you could call the class and function directly.

So, this is my case! My action is added by the class MrBara_WooCommerce in the method hooks() and the action's method products_links() isn't static, so I need to call the class, too.

Test 2

add_action('woocommerce_single_product_summary', 'remove_products_links');
function remove_products_links() {
    remove_action('products_links', ['MrBara_WooCommerce', 'woocommerce_single_product_summary'] );
}

Also this didn't work.

I've also tried to play with priorities, setting my remove_products_links at 9, at 11, at 10 and at 0 (to match the priority of the original added action) but nothing of this worked.

I think I'm very close to the solution but my inexperience causes me to miss some relevant settings.

Can you help me better understand why my remove_action doesn't work?

UPDATE

Continuing reading I've discovered that the functions.php file of my child theme is loaded BEFORE the files of the parent theme (https://wordpress.stackexchange.com/a/170665/57145).

I've had a perception of this printing the entire $wp_filter variable using the functions.php file of the child theme.

So, printing, I saw the remove_products_links action that I registered, but didn't saw the products_links action that I'm trying to remove.

So I thought that there must be some problems in the registered order.

Now, I think that I can't remove the action as when I register the remove action the action that I want to remove doesn't exist.

The question, so, becomes: how can I remove an action from the parent theme using the child theme?

1
  • I've added some things to look at based on your update. In and out today, but those hooks may help. I'll clean up my answer later on ;)
    – hwl
    May 27, 2017 at 16:06

1 Answer 1

1

First, you're correct that removing the action calling the products_links method would work, and that this is specifically MrBara_WooCommerce->products_links().

In your functions.php, you can just use remove_action without wrapping it in a function used as a callback for another add_action, btw.

so: remove_action('products_links, array('MrBara_WooCommerce', 'woocommerce_single_product_summary, 0) 10 is default priority, and while we may assume your priority needs to be higher than the add_action so it is called to remove it after it is included, WP codex notes this:

To remove an action the priority must match the priority with with the function was originally added.

And

You cannot successfully remove the action before it has been added.

You also cannot remove an action after it has been run.

So, one issue you're having may be that by hooking an add_action with a default priority (10) to call a function that does the remove action with a 0 priority, is doing so after the action with a zero priority has been run.

Child versus Parent

Since child theme functions.php runs before the parent, you need to hook this after the theme is set up. [wp_loaded]1, [after_setup_theme]1, and init are possible options here.

an example using our earlier back and forth:

function remove_products_links() {
    global $mrbara;
    remove_action('product_links', array($mrbara, 'woocommerce_single_product_summary') );
}

add_action('after_setup_theme', 'remove_products_links');

original answer

The second argument needs to be an array like so:

remove_action('products_links', array('MrBara_WooCommerce', 'woocommerce_single_product_summary' ) );

To access it from a global variable that holds the class, something like:

global $mrbara;
$mrbara = new MrBara_WooCommerce();
function remove_product_links() {
    global $mrbara;
    remove_action('product_links', array($mrbara, 'woocommerce_single_product_summary') );
}

add_action('woocommerce_single_product_summary', 'remove_products_links');
8
  • ['MrBara_WooCommerce', 'woocommerce_single_product_summary' is an array: is the short syntax. Anyway I've just tried to use global $mrbara but it doesn't work. In your example you use once $mbara to instantiate the class and $mrbara to assign it as a global variable: is mistyping or is intended?
    – Aerendir
    May 27, 2017 at 14:22
  • the $mbara/$mrbara was just a typo. I realize that's the array short syntax, just trying to eliminate issues. Also, - not solving the above, but possibly achieving your end goal -, since woocommerce.php is a theme file, you could just override it with your child theme and remove that bit.
    – hwl
    May 27, 2017 at 14:45
  • I don't like to completely override the woocommerce.php file as this is a dirty way of achieving my result. Wordpress provides a powerful system to do things and I'd like to use it... My primary goal is to better understand how does it work... and for the moment I haven't reached the goal! -.-' I want to use hooks and add/remove_action() as this is the correct way to do things...
    – Aerendir
    May 27, 2017 at 14:50
  • 1
    It's not dirty at all, it's the intended use of the template system. I admit it's off topic though. :) without trying it, I would think priority 0 may be needed. I'll look at it again and add some details when at a computer.
    – hwl
    May 27, 2017 at 14:59
  • I've update my question: there is a problem in the order of loading functions.php: the child theme's one is loaded before the parent theme's one and this causes the issue: I cannot remove an action that doesn't already exist. The question now is how to intercept the parent's action from the child's functions.php file...
    – Aerendir
    May 27, 2017 at 15:31

Your Answer

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

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