Create new product attribute programmatically in Woocommerce

How can I create attributes for WooCommerce from a plugin? I find only :

wp_set_object_terms( $object_id, $terms, $taxonomy, $append);

From this stack-question

But this approach required id of some product. I need to generate some attributes not attached to any products.

7

2 Answers

To create a term you can use wp_insert_term()

like so:

wp_insert_term( 'red', 'pa_colors' );

where colors is the name of your attribute. The taxonomy name of an attribute is always prepended by pa_.

Edit Attributes are merely custom taxonomies. Or you could say they are dynamic taxonomies that are manually created by the user in the back-end. Still, all the same, custom taxonomy rules apply.

You can see the source code here which loops through the attributes and runs register_taxonomy() on each. So to create a new attribute (remember it is just a taxonomy) then you need to run register_taxonomy() and simple prepend pa_ to the start of the taxonomy name.

Mimicking some of the values of the taxonomy args from core would get you something like this for a 'Colors' attribute.

/** * Register a taxonomy. */
function so_29549525_register_attribute() { $permalinks = get_option( 'woocommerce_permalinks' ); $taxonomy_data = array( 'hierarchical' => true, 'update_count_callback' => '_update_post_term_count', 'labels' => array( 'name' => __( 'My Colors', 'your-textdomain' ), 'singular_name' => __( 'Color', 'your-textdomain' ), 'search_items' => __( 'Search colors', 'your-textdomain' ), 'all_items' => __( 'All colors', 'your-textdomain' ), 'parent_item' => __( 'Parent color', 'your-textdomain' ), 'parent_item_colon' => __( 'Parent color:', 'your-textdomain' ), 'edit_item' => __( 'Edit color', 'your-textdomain' ), 'update_item' => __( 'Update color', 'your-textdomain' ), 'add_new_item' => __( 'Add new color', 'your-textdomain' ), 'new_item_name' => __( 'New color', 'your-textdomain' ) ), 'show_ui' => false, 'query_var' => true, 'rewrite' => array( 'slug' => empty( $permalinks['attribute_base'] ) ? '' : trailingslashit( $permalinks['attribute_base'] ) . sanitize_title( 'colors' ), 'with_front' => false, 'hierarchical' => true ), 'sort' => false, 'public' => true, 'show_in_nav_menus' => false, 'capabilities' => array( 'manage_terms' => 'manage_product_terms', 'edit_terms' => 'edit_product_terms', 'delete_terms' => 'delete_product_terms', 'assign_terms' => 'assign_product_terms', ) ); register_taxonomy( 'pa_my_color', array('product'), $taxonomy_data );
}
add_action( 'woocommerce_after_register_taxonomy', 'so_29549525_register_attribute' );

Update 2020-11-18

Attribute taxonomies are stored in the {$wpdb->prefix}woocommerce_attribute_taxonomies database table. And from there WooCommerce runs register_taxonomy() on each one that's found in the table. So in order to create an attribute taxonomy, a row should be added to this table. WooCommerce has a function wc_create_attribute() that will handle this for us. (Since 3.2+).

My conditional logic to test if the attribute exists is not the greatest and I would advise using some kind of version option in your plugin's update routine. But as an example of using wc_create_taxonomy() this should insert an attribute called "My Color".

/** * Register an attribute taxonomy. */
function so_29549525_create_attribute_taxonomies() { $attributes = wc_get_attribute_taxonomies(); $slugs = wp_list_pluck( $attributes, 'attribute_name' ); if ( ! in_array( 'my_color', $slugs ) ) { $args = array( 'slug' => 'my_color', 'name' => __( 'My Color', 'your-textdomain' ), 'type' => 'select', 'orderby' => 'menu_order', 'has_archives' => false, ); $result = wc_create_attribute( $args ); }
}
add_action( 'admin_init', 'so_29549525_create_attribute_taxonomies' );
10

2023 Update for Woocommerce 3.2 | Still works on WC 8.1+
Not to be used in a Multisite environment

To create a new product attribute from a label name use the following function:

function create_product_attribute( $label_name ){ $slugs = wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_name' ); $slug = sanitize_title( $label_name ); if ( ! in_array( $slug, $slugs ) ) { $data = array( 'name' => $label_name, 'slug' => $slug, 'type' => 'select', 'orderby' => 'menu_order', 'has_archives' => false, ); return wc_create_attribute( $data ); }
}

Code goes in function.php file of your child theme (or in a plugin). Tested and works.

Update based on @helgatheviking last update code


Old answer: for WooCommerce 3+ (2018) | Not to be used in a Multisite environment

function create_product_attribute( $label_name ){ global $wpdb; $slug = sanitize_title( $label_name ); if ( strlen( $slug ) >= 28 ) { return new WP_Error( 'invalid_product_attribute_slug_too_long', sprintf( __( 'Name "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { return new WP_Error( 'invalid_product_attribute_slug_reserved_name', sprintf( __( 'Name "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); } elseif ( taxonomy_exists( wc_attribute_taxonomy_name( $label_name ) ) ) { return new WP_Error( 'invalid_product_attribute_slug_already_exists', sprintf( __( 'Name "%s" is already in use. Change it, please.', 'woocommerce' ), $label_name ), array( 'status' => 400 ) ); } $data = array( 'attribute_label' => $label_name, 'attribute_name' => $slug, 'attribute_type' => 'select', 'attribute_orderby' => 'menu_order', 'attribute_public' => 0, // Enable archives ==> true (or 1) ); $results = $wpdb->insert( "{$wpdb->prefix}woocommerce_attribute_taxonomies", $data ); if ( is_wp_error( $results ) ) { return new WP_Error( 'cannot_create_attribute', $results->get_error_message(), array( 'status' => 400 ) ); } $id = $wpdb->insert_id; do_action('woocommerce_attribute_added', $id, $data); wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); delete_transient('wc_attribute_taxonomies');
}

Code goes in function.php file of your child theme (or in a plugin). Tested and works.


Based on:

Related: Create programmatically a product using CRUD methods in Woocommerce 3

2

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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.

You Might Also Like