I’m using WooCommerce as a headless CMS with Angular. Currently, I’m working on implementing a product filter sidebar. The goal is to collect the attributes and their options (terms) for the products in the current category, and display them in the filter sidebar.
I’m calling the WooCommerce API with this endpoint:
/wp-json/wc/v3/products?category=62,4239&per_page=20&page=1&attribute=pa_brand&attribute_term=19
However, the response I’m getting for each product looks like this:
"attributes": [
{
"id": 3,
"name": "Brand",
"slug": "pa_brand",
"position": 1,
"visible": true,
"variation": false,
"options": [
"Barebones"
]
}
]
The issue is that the "options" (e.g., "Barebones") are returned as strings, but I need the term IDs for filtering purposes (i.e., attribute_term=19)
. So, I’m thinking of getting the term IDs separately, but when I do this, it significantly impacts the performance because I have to fetch the whole list of attributes and terms and then search for the corresponding term IDs.
Is there a better solution for gathering all attributes and their term IDs efficiently for the filter sidebar?
I tried to call the whole attributes and terms in a pagination, and compare the product's options and terms with this call, but the performance were too bad.
I’m using WooCommerce as a headless CMS with Angular. Currently, I’m working on implementing a product filter sidebar. The goal is to collect the attributes and their options (terms) for the products in the current category, and display them in the filter sidebar.
I’m calling the WooCommerce API with this endpoint:
/wp-json/wc/v3/products?category=62,4239&per_page=20&page=1&attribute=pa_brand&attribute_term=19
However, the response I’m getting for each product looks like this:
"attributes": [
{
"id": 3,
"name": "Brand",
"slug": "pa_brand",
"position": 1,
"visible": true,
"variation": false,
"options": [
"Barebones"
]
}
]
The issue is that the "options" (e.g., "Barebones") are returned as strings, but I need the term IDs for filtering purposes (i.e., attribute_term=19)
. So, I’m thinking of getting the term IDs separately, but when I do this, it significantly impacts the performance because I have to fetch the whole list of attributes and terms and then search for the corresponding term IDs.
Is there a better solution for gathering all attributes and their term IDs efficiently for the filter sidebar?
I tried to call the whole attributes and terms in a pagination, and compare the product's options and terms with this call, but the performance were too bad.
Share Improve this question edited Mar 12 at 23:04 VLAZ 29.1k9 gold badges63 silver badges84 bronze badges asked Mar 12 at 16:56 Mohamed SabryMohamed Sabry 311 silver badge3 bronze badges 2- You can create a custom endpoint, and fetch all attributes and their term IDs for the products with a single request instead of multiple fetches. This SO questions should provide some valuable insight: WooCommerce API v3 custom endpoint. – Richard Commented Mar 13 at 15:37
- @Richard this is really worked ! – Mohamed Sabry Commented Mar 13 at 21:14
1 Answer
Reset to default 1Thanks to @Rishard! I tried to customize the endpoint by adding this code in the WP snippet:
add_filter('woocommerce_rest_prepare_product_object', function ($response, $product, $request) {
if (!empty($response->data['attributes'])) {
foreach ($response->data['attributes'] as &$attribute) {
if (!empty($attribute['options'])) {
$options_with_ids = [];
foreach ($attribute['options'] as $option) {
$term = get_term_by('name', $option, $attribute['slug']);
if ($term) {
$options_with_ids[] = [
'id' => $term->term_id,
'name' => $term->name
];
} else {
$options_with_ids[] = [
'id' => null,
'name' => $option
];
}
}
$attribute['options'] = $options_with_ids;
}
}
}
return $response;
}, 10, 3);
Now the response is
{
"id": 7,
"name": "Size",
"slug": "pa_size",
"position": 4,
"visible": true,
"variation": true,
"options": [
{
"id": 123,
"name": "L"
},
{
"id": 138,
"name": "XL"
}
]
}