Add size as a product attribute
Add a product's size as a taxonomy attribute making it possible to filter a product list based on its size.
Heads-up!
This tutorial is still valid but a simpler version exists here.
In this article

Add size attribute
Before you begin, the Size attribute must exist. To add it, go here WordPress Admin Area > Products > Attributes and add Size in the "Name" field and size in the "Slug" field.

Use a single field for attribute
In this example, we will choose one field from the product's list of fields and store that field as the size attribute.
- 1
-
Identify the field
We can view all fields by clicking a product's name on the add/edit Product Sets pages in your WordPress Admin Area. We see that this product does have a "size" field so we will use that.
Example of a product's size field - 2
-
Create a custom plugin
If you haven't done so already, create a custom plugin.
- 3
-
Add custom code
Add the following code to your custom plugin file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters<?php /** * Add the product's size as a size attribute for this product. * * The attribute "Size" with a slug of "size" must already exist here: * WordPress Admin Area > Products > Attributes. * * @param array|string $value The current value of the $attribute for this $post. * @param string $attribute The slug of the attribute. Examples: pa_size or pa_shoe-size * @param array $post An array of post data including ID, post_title, post_status, etc... * @param array $product An array of product data returned from the Datafeedr API. * @param array $set A post array for this Product Set with an array key of postmeta containing all post meta data. * @param string $action The action the Product Set is performing. Value are either "insert" or "update". * * @return array|string The updated attribute's value. */ add_filter( 'dfrpswc_filter_attribute_value', function ( $value, $attribute, $post, $product, $set, $action ) { if ( $attribute !== 'pa_size' ) { return $value; } if ( isset( $product['size'] ) ) { return $product['size']; } return $value; }, 20, 6 ); - 4
-
Add/Update product sets
These changes will only take effect after any new Product Sets are created or after existing Product Sets are updated.
- 5
-
Expose filter as widget
Go here WordPress Admin Area > Appearance > Widgets and add a WooCommerce Layered Nav widget to your sidebar and configure it to display the size attribute like this:
Add size widget
Use multiple fields for attribute
Sometimes merchants store product information in different fields than other merchants. For example, some merchants will store the product's size in the "size" field while others will use a different field. In this example, we will use multiple fields to get the product's size.
- 1
-
Identify the fields
We can view all fields by clicking a product's name on the add/edit Product Sets pages in your WordPress Admin Area. We see that this product does not have a "size" field however it does have a field named "custom1" which contains the product's size. So we will use that field if the "size" field does not exist.
Product without a size field - 2
-
Create a custom plugin
If you haven't done so already, create a custom plugin.
- 3
-
Add custom code
Add the following code to your custom plugin file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters<?php /** * Add the product's size as a size attribute for this product. * * The attribute "Size" with a slug of "size" * must already exist here: * WordPress Admin Area > Products > Attributes. * * @param array|string $value The current value of the $attribute for this $post. * @param string $attribute The slug of the attribute. Examples: pa_size or pa_shoe-size * @param array $post An array of post data including ID, post_title, post_status, etc... * @param array $product An array of product data returned from the Datafeedr API. * @param array $set A post array for this Product Set with an array key of postmeta containing all post meta data. * @param string $action The action the Product Set is performing. Value are either "insert" or "update". * * @return array|string The updated attribute's value. */ add_filter( 'dfrpswc_filter_attribute_value', function ( $value, $attribute, $post, $product, $set, $action ) { if ( $attribute !== 'pa_size' ) { return $value; } if ( isset( $product['size'] ) ) { return $product['size']; } if ( isset( $product['custom1'] ) ) { return $product['custom1']; } return $value; }, 20, 6 ); - 4
-
Add/Update product sets
These changes will only take effect after any new Product Sets are created or after existing Product Sets are updated.
- 5
-
Expose filter as widget
Go here WordPress Admin Area > Appearance > Widgets and add a WooCommerce Layered Nav widget to your sidebar and configure it to display the size attribute like this:
Add size widget
Use controlled vocabulary with one field
In the above examples, we rely on the names the merchants have provided for their product sizes. But this can sometimes lead to unexpected results like this:

In this example, we will provide a controlled vocabulary to ensure we have an organized size attribute filter.

- 1
-
Identify the field
We can view all fields by clicking a product's name on the add/edit Product Sets pages in your WordPress Admin Area. We see that this product does have a "size" field so we will use that.
Example of a product's size field - 2
-
Create a custom plugin
If you haven't done so already, create a custom plugin.
- 3
-
Add custom code
Add the following code to your custom plugin file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters<?php /** * Add the product's size as a size attribute for this product. * * The attribute "Size" with a slug of "size" * must already exist here: * WordPress Admin Area > Products > Attributes. * * @param array|string $value The current value of the $attribute for this $post. * @param string $attribute The slug of the attribute. Examples: pa_size or pa_shoe-size * @param array $post An array of post data including ID, post_title, post_status, etc... * @param array $product An array of product data returned from the Datafeedr API. * @param array $set A post array for this Product Set with an array key of postmeta containing all post meta data. * @param string $action The action the Product Set is performing. Value are either "insert" or "update". * * @return array|string The updated attribute's value. */ add_filter( 'dfrpswc_filter_attribute_value', function ( $value, $attribute, $post, $product, $set, $action ) { if ( $attribute !== 'pa_size' ) { return $value; } if ( isset( $product['size'] ) ) { return mycode_get_size( $product['size'], $product['size'] ); } return $value; }, 20, 6 ); /** * A function to normalize gender attribute names. * * This returns a normalized value of a term based on a supplied * array of mappings of a key (desired word) mapped to an array of * keywords (undesired words). * * @param string $field The value to normalize. * @param string $default Optional. What to return if the $field value doesn't have a "normalized" value. Default: '' * * @return string Normalized attribute value. */ function mycode_get_size( $field, $default = '' ) { $map = []; // ++++++++++ Begin Editing Here ++++++++++ // Small, Medium, Large Sizes $map['XXXS'] = [ 'xxx small' ]; $map['XXS'] = [ 'xx small' ]; $map['XS'] = [ 'x small' ]; $map['Small'] = [ 'sm', 's' ]; $map['Medium'] = [ 'md', 'med', 'm' ]; $map['Large'] = [ 'lg', 'l' ]; $map['XL'] = [ 'extra large', 'x large' ]; $map['XXL'] = [ 'xx large' ]; $map['XXXL'] = [ 'xxx large' ]; // European Shoe Sizes $map['34'] = [ '34', 'UK 2' ]; $map['34.5'] = [ '34.5', 'UK 2' ]; $map['35'] = [ '35', 'UK 2.5' ]; $map['35.5'] = [ '35.5', 'UK 3' ]; $map['36'] = [ '36', 'UK 3.5' ]; $map['36.5'] = [ '36.5', 'UK 3.5' ]; $map['37'] = [ '37', 'UK 4' ]; $map['37.5'] = [ '37.5', 'UK 4.5' ]; $map['38'] = [ '38', 'UK 5' ]; $map['38.5'] = [ '38.5', 'UK 5.5' ]; $map['39'] = [ '39', 'UK 6' ]; $map['39.5'] = [ '39.5', 'UK 6.5' ]; $map['40'] = [ '40', 'UK 7' ]; $map['40.5'] = [ '40.5', 'UK 7' ]; $map['41'] = [ '41', 'UK 7.5' ]; $map['41.5'] = [ '41.5', 'UK 7.5' ]; $map['42'] = [ '42', 'UK 8' ]; $map['42.5'] = [ '42.5', 'UK 8.5' ]; $map['43'] = [ '43', 'UK 9' ]; $map['43.5'] = [ '43.5', 'UK 9' ]; $map['44'] = [ '44', 'UK 9.5' ]; $map['44.5'] = [ '44.5', 'UK 10' ]; $map['45'] = [ '45', 'UK 10.5' ]; $map['45.5'] = [ '45.5', 'UK 10.5' ]; $map['46'] = [ '46', 'UK 11' ]; $map['46.5'] = [ '46.5', 'UK 11.5' ]; $map['47'] = [ '47', 'UK 12' ]; // ++++++++++ Stop Editing Here ++++++++++ $terms = []; foreach ( $map as $key => $keywords ) { if ( preg_match( '/\b' . preg_quote( $key, '/' ) . '\b/iu', $field ) ) { $terms[] = $key; } foreach ( $keywords as $keyword ) { if ( preg_match( '/\b' . preg_quote( $keyword, '/' ) . '\b/iu', $field ) ) { $terms[] = $key; } } } if ( ! empty( $terms ) ) { return implode( WC_DELIMITER, array_unique( $terms ) ); } return $default; } - 4
-
Add/Update product sets
These changes will only take effect after any new Product Sets are created or after existing Product Sets are updated.
- 5
-
Expose filter as widget
Go here WordPress Admin Area > Appearance > Widgets and add a WooCommerce Layered Nav widget to your sidebar and configure it to display the size attribute like this:
Add size widget
Use controlled vocabulary with multiple fields
This is useful when a merchant provides the product's size in a field other than "size" or if a merchant only provides the size in the product's name. Using a controlled vocabulary on a variety of fields, we can extract the data we need!
- 1
-
Identify the fields
In this example, we will use 3 fields: size, custom1 and name in that order.
- 2
-
Create a custom plugin
If you haven't done so already, create a custom plugin.
- 3
-
Add custom code
Add the following code to your custom plugin file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters<?php /** * Add the product's size as a size attribute for this product. * * The attribute "Size" with a slug of "size" * must already exist here: * WordPress Admin Area > Products > Attributes. * * @param array|string $value The current value of the $attribute for this $post. * @param string $attribute The slug of the attribute. Examples: pa_color or pa_shoe-size * @param array $post An array of post data including ID, post_title, post_status, etc... * @param array $product An array of product data returned from the Datafeedr API. * @param array $set A post array for this Product Set with an array key of postmeta containing all post meta data. * @param string $action The action the Product Set is performing. Value are either "insert" or "update". * * @return array|string The updated attribute's value. */ add_filter( 'dfrpswc_filter_attribute_value', function ( $value, $attribute, $post, $product, $set, $action ) { if ( $attribute !== 'pa_size' ) { return $value; } if ( isset( $product['size'] ) ) { return mycode_get_size( $product['size'] ); } if ( isset( $product['custom1'] ) ) { return mycode_get_size( $product['custom1'] ); } if ( isset( $product['name'] ) ) { return mycode_get_size( $product['name'] ); } return $value; }, 20, 6 ); /** * A function to normalize size attribute names. * * This returns a normalized value of a term based on a supplied * array of mappings of a key (desired word) mapped to an array of * keywords (undesired words). * * @param string $field The value to normalize. * @param string $default Optional. What to return if the $field value doesn't have a "normalized" value. Default: '' * * @return string Normalized attribute value. */ function mycode_get_size( $field, $default = '' ) { $map = []; // ++++++++++ Begin Editing Here ++++++++++ // Small, Medium, Large Sizes $map['XXXS'] = [ 'xxx small' ]; $map['XXS'] = [ 'xx small' ]; $map['XS'] = [ 'x small' ]; $map['Small'] = [ 'sm', 's' ]; $map['Medium'] = [ 'md', 'med', 'm' ]; $map['Large'] = [ 'lg', 'l' ]; $map['XL'] = [ 'extra large', 'x large' ]; $map['XXL'] = [ 'xx large' ]; $map['XXXL'] = [ 'xxx large' ]; // European Shoe Sizes $map['34'] = [ '34', 'UK 2' ]; $map['34.5'] = [ '34.5', 'UK 2' ]; $map['35'] = [ '35', 'UK 2.5' ]; $map['35.5'] = [ '35.5', 'UK 3' ]; $map['36'] = [ '36', 'UK 3.5' ]; $map['36.5'] = [ '36.5', 'UK 3.5' ]; $map['37'] = [ '37', 'UK 4' ]; $map['37.5'] = [ '37.5', 'UK 4.5' ]; $map['38'] = [ '38', 'UK 5' ]; $map['38.5'] = [ '38.5', 'UK 5.5' ]; $map['39'] = [ '39', 'UK 6' ]; $map['39.5'] = [ '39.5', 'UK 6.5' ]; $map['40'] = [ '40', 'UK 7' ]; $map['40.5'] = [ '40.5', 'UK 7' ]; $map['41'] = [ '41', 'UK 7.5' ]; $map['41.5'] = [ '41.5', 'UK 7.5' ]; $map['42'] = [ '42', 'UK 8' ]; $map['42.5'] = [ '42.5', 'UK 8.5' ]; $map['43'] = [ '43', 'UK 9' ]; $map['43.5'] = [ '43.5', 'UK 9' ]; $map['44'] = [ '44', 'UK 9.5' ]; $map['44.5'] = [ '44.5', 'UK 10' ]; $map['45'] = [ '45', 'UK 10.5' ]; $map['45.5'] = [ '45.5', 'UK 10.5' ]; $map['46'] = [ '46', 'UK 11' ]; $map['46.5'] = [ '46.5', 'UK 11.5' ]; $map['47'] = [ '47', 'UK 12' ]; // ++++++++++ Stop Editing Here ++++++++++ $terms = []; foreach ( $map as $key => $keywords ) { if ( preg_match( '/\b' . preg_quote( $key, '/' ) . '\b/iu', $field ) ) { $terms[] = $key; } foreach ( $keywords as $keyword ) { if ( preg_match( '/\b' . preg_quote( $keyword, '/' ) . '\b/iu', $field ) ) { $terms[] = $key; } } } if ( ! empty( $terms ) ) { return implode( WC_DELIMITER, array_unique( $terms ) ); } return $default; } - 4
-
Add/Update product sets
These changes will only take effect after any new Product Sets are created or after existing Product Sets are updated.
- 5
-
Expose filter as widget
Go here WordPress Admin Area > Appearance > Widgets and add a WooCommerce Layered Nav widget to your sidebar and configure it to display the size attribute like this:
Add size widget
Provide default attribute value
When using the controlled vocabulary mentioned in the previous 2 examples you will see that if the size field doesn't contain a size in the controlled vocabulary you have configured, it will be ignored.
For example, if the product's size is XXXX Large, it will be ignored because we have not configured any controlled vocabulary for that term.
In these cases, we need to configure our code to either use the provided term (ie. XXXX Large) or we can provide a default value. in this example, we will force the script to use the value provided in the "size" or "custom1" fields if they exist, otherwise not use any value.
- 1
-
Identify the fields
In this example, we will use 3 fields: size, custom1 and name in that order.
- 2
-
Create a custom plugin
If you haven't done so already, create a custom plugin.
- 3
-
Add custom code
Add the following code to your custom plugin file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters<?php /** * Add the product's size as a size attribute for this product. * * The attribute "Size" with a slug of "size" * must already exist here: * WordPress Admin Area > Products > Attributes. * * @param array|string $value The current value of the $attribute for this $post. * @param string $attribute The slug of the attribute. Examples: pa_color or pa_shoe-size * @param array $post An array of post data including ID, post_title, post_status, etc... * @param array $product An array of product data returned from the Datafeedr API. * @param array $set A post array for this Product Set with an array key of postmeta containing all post meta data. * @param string $action The action the Product Set is performing. Value are either "insert" or "update". * * @return array|string The updated attribute's value. */ add_filter( 'dfrpswc_filter_attribute_value', function ( $value, $attribute, $post, $product, $set, $action ) { if ( $attribute !== 'pa_size' ) { return $value; } if ( isset( $product['size'] ) ) { return mycode_get_size( $product['size'], $product['size'] ); } if ( isset( $product['custom1'] ) ) { return mycode_get_size( $product['custom1'], $product['custom1'] ); } if ( isset( $product['name'] ) ) { return mycode_get_size( $product['name'] ); } return $value; }, 20, 6 ); /** * A function to normalize size attribute names. * * This returns a normalized value of a term based on a supplied * array of mappings of a key (desired word) mapped to an array of * keywords (undesired words). * * @param string $field The value to normalize. * @param string $default Optional. What to return if the $field value doesn't have a "normalized" value. Default: '' * * @return string Normalized attribute value. */ function mycode_get_size( $field, $default = '' ) { $map = []; // ++++++++++ Begin Editing Here ++++++++++ // Small, Medium, Large Sizes $map['XXXS'] = [ 'xxx small' ]; $map['XXS'] = [ 'xx small' ]; $map['XS'] = [ 'x small' ]; $map['Small'] = [ 'sm', 's' ]; $map['Medium'] = [ 'md', 'med', 'm' ]; $map['Large'] = [ 'lg', 'l' ]; $map['XL'] = [ 'extra large', 'x large' ]; $map['XXL'] = [ 'xx large' ]; $map['XXXL'] = [ 'xxx large' ]; // European Shoe Sizes $map['34'] = [ '34', 'UK 2' ]; $map['34.5'] = [ '34.5', 'UK 2' ]; $map['35'] = [ '35', 'UK 2.5' ]; $map['35.5'] = [ '35.5', 'UK 3' ]; $map['36'] = [ '36', 'UK 3.5' ]; $map['36.5'] = [ '36.5', 'UK 3.5' ]; $map['37'] = [ '37', 'UK 4' ]; $map['37.5'] = [ '37.5', 'UK 4.5' ]; $map['38'] = [ '38', 'UK 5' ]; $map['38.5'] = [ '38.5', 'UK 5.5' ]; $map['39'] = [ '39', 'UK 6' ]; $map['39.5'] = [ '39.5', 'UK 6.5' ]; $map['40'] = [ '40', 'UK 7' ]; $map['40.5'] = [ '40.5', 'UK 7' ]; $map['41'] = [ '41', 'UK 7.5' ]; $map['41.5'] = [ '41.5', 'UK 7.5' ]; $map['42'] = [ '42', 'UK 8' ]; $map['42.5'] = [ '42.5', 'UK 8.5' ]; $map['43'] = [ '43', 'UK 9' ]; $map['43.5'] = [ '43.5', 'UK 9' ]; $map['44'] = [ '44', 'UK 9.5' ]; $map['44.5'] = [ '44.5', 'UK 10' ]; $map['45'] = [ '45', 'UK 10.5' ]; $map['45.5'] = [ '45.5', 'UK 10.5' ]; $map['46'] = [ '46', 'UK 11' ]; $map['46.5'] = [ '46.5', 'UK 11.5' ]; $map['47'] = [ '47', 'UK 12' ]; // ++++++++++ Stop Editing Here ++++++++++ $terms = []; foreach ( $map as $key => $keywords ) { if ( preg_match( '/\b' . preg_quote( $key, '/' ) . '\b/iu', $field ) ) { $terms[] = $key; } foreach ( $keywords as $keyword ) { if ( preg_match( '/\b' . preg_quote( $keyword, '/' ) . '\b/iu', $field ) ) { $terms[] = $key; } } } if ( ! empty( $terms ) ) { return implode( WC_DELIMITER, array_unique( $terms ) ); } return $default; } - 4
-
Add/Update product sets
These changes will only take effect after any new Product Sets are created or after existing Product Sets are updated.
- 5
-
Expose filter as widget
Go here WordPress Admin Area > Appearance > Widgets and add a WooCommerce Layered Nav widget to your sidebar and configure it to display the size attribute like this:
Add size widget