I have a request to be able to duplicate a product attribute in WooCommerce. Think: duplicating a product (with already existing functionality), or plugins that allow you to duplicate a post.

However, I think this relates to WP in general as I am trying to figure out how to add a "Clone" link to go along with the "Edit" and "Delete" links for each WooCommerce product attribute in the Products > Attributes admin page.

I have seen several articles about using the post_row_actions filter.

I can add a "Clone" link to products just fine (I use "Clone" since WC already provides a "Duplicate" link for products) using that filter, using something like this:

// Add "Clone" link to each row in the Woo Attributes admin page
function my_duplicate_post_link($actions, $post)
    if ($post->post_type=='product' )
     $actions['duplicate'] = '<a href="#" title="" rel="permalink">Clone</a>';
return $actions;
add_filter('post_row_actions', 'my_duplicate_post_link', 10, 2);

I then added another argument to the post_type test like this:

if ($post->post_type=='product' && $post->page=='product_attributes')

Obviously (to me now), that not only didn't provide the "Clone" link to attributes, it removed the link from the quick links area on each product on the products listing page. Which implies that post_row_actions only works at the top level of post_type. As in, page as a post request negates the post_row_actions filter.

The HTML for the product attributes page is generated with the /woocommerce/includes/admin/class-wc-admin-attributes.php file. Woo is, of course, famous for its ability to handle hooks and actions, so I thought "No problem."

However, I can't find any info on how to create child theme versions of those Woo admin scripts. Everything else, it appears, but not those. I put a copy of that file in several child theme folders, starting with the root, and down to a replica of the Woo folder structure itself. No luck.

So next, why not extend the WC_Admin_Attributes class and write my own function? Then I have something like this:

class Cloneable_WC-Admin_attributes extends WC-Admin_Attributes {

And I copy the entire public static function edit_attribute() function into that, adding the "Clone" link in the part of the code that generates the "Edit" and "Delete" links.

That doesn't work either. I guessing because all the functions in the parent class are called by self::.

My last resort is to use jQuery to edit the innerHTML of the row-actions class of the containing DIV to add the "Clone" link. That is such a hack, though.

Actually executing PHP to duplicate the attribute is not a problem. I just can't figure out how to to add a link in the first place!

enter image description here

1 Answer 1


WooCommerce have not anticipate the need of adding a new action in this place so there is neither filters nor actions for doing this

there is 2 others solutions :

  • adding the link with JavaScript
  • parsing the HTML result to add the link at this place


To add the link in the HTML code, you can try this

add_action("admin_menu", function () {

    $menu_slug = "edit.php?post_type=product";
    $submenu_slug = "product_attributes";

    $hookname = get_plugin_page_hookname($submenu_slug, $menu_slug);

    // removing the original page call

    // adding the hook for the new page
    add_action($hookname, "display_newPage_product_attributes");


function display_newPage_product_attributes() {

    // original page

    $wc_Admin_Menus = new WC_Admin_Menus();

    $content = ob_get_clean();

    // adding the links, to improve

    $link = "<a href=\"a\">Attack of the Clone</a>";

    $content = str_replace(
        , "</a></span> | $link</div>"
        , $content

    // display

    echo $content;


I write "to improve" in a comment because you will certainly have to personalise each link and maybe you can think about a remplacement which will work even if the future version of WooCommerce make changes on this page

  • Thanks @mmm. I figured I'll have to go the JS route if no one comes up with a PHP solution to extend the class that contains the code generating the links.
    – Terry Hale
    Mar 16, 2016 at 20:36
  • I was thinking about extending the class when I speak about parsing HTML. Because the method which make this page is 157 lines long, I think it's more efficient to parse and add instead of copying / pasting the method in the new class
    – mmm
    Mar 16, 2016 at 21:02
  • Yes, I think that's a good idea. But one of the points of my question was actually how to do that when the original class functions are referenced by self::
    – Terry Hale
    Mar 17, 2016 at 17:46
  • Before the call of "self::..." there is a call of WC_Admin_Menus, which is hooked in the menu during the "admin_menu" hook. So you can unhook this page of the menu to replace it by your. I have edited the answer with this example.
    – mmm
    Mar 17, 2016 at 20:30
  • This is an astounding bit of coding. After a little quick reading, I understand how and why it works, but I would probably never have come across all that obscure stuff. I can't thank you enough for the time and effort you put into this, as well as your expertise. I don't yet have enough rep yet to upvote this because I don't ask very many questions. But one day... Cheers mate! :)
    – Terry Hale
    Mar 20, 2016 at 2:04

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.