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.
72 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' );
102023 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:
- Product Attribute
wc_create_attribute()
function code (Woocommerce 3.2+). - Create programmatically a variable product and two new attributes in WooCommerce
Related: Create programmatically a product using CRUD methods in Woocommerce 3
2ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJoaXJtZG6Cc4GOnKmemaSaeq%2Bx1manq6eUqrC1ecCtq6uhkqrBpnnPq6agqpGiuqLAyJyYpaSpYravedaoppynnaKys6%2FE