Hi there!
Yes, this is possible for any hierarchical taxonomy, they are often called “categories”.
In the category selection box, you can tick the radio button on the right:

Regarding the permalink structure: The primary term selection will affect the %category% part in your permalink structure.
“Dynamic” is a big word; so, if I got your question wrong, feel free to rephrase it 🙂
P.S. This doesn’t work yet with Gutenberg.
Thread Starter
Joe G.
(@webgmclassics)
Hi Sybre, thank you for the response.
I understand how to do the above using the admin. But, I need to do this for thousands of existing products (using woocommerce).
Is there a TSF hook I could use to do this, or do I just need to write a custom script to set the WP metadata?
Hi Joe,
I recommend using a script to set the metadata, this way you ensure future compatibility.
The meta key is: _primary_term_{$taxonomy}
So, if it’s a default category, then it’ll be _primary_term_category
The meta value will be an integer, this will be the term ID.
For the loop, I recommend checking each post for having the term ID.
Alternatively, you can set up a query that grabs all posts that have the term ID set.
It’ll look a bit like the snippet below. It’ll probably abruptly stop due to memory exhaustion. When that happens, you might wish to turn this into a paginated query containing X posts, where you’ll iterate through the “pages” updating X posts at a time.
Warning: This has not been tested! Make a backup first and/or test it on a disposable site.
// Increase memory limit
wp_raise_memory_limit( 'set-metadata' );
// Set values....
$post_type = 'product';
$taxonomy = 'product_cat';
$term_id = 1;
// Get product IDs. This is a slow query!
$products = get_posts( [
'post_type' => $post_type,
'numberposts' => -1,
'fields' => 'ids',
'tax_query' => [
[
'taxonomy' => $taxonomy,
'field' => 'id',
'terms' => $term_id,
'include_children' => false,
],
],
] );
// Set metadata here
foreach ( $products as $product_id ) {
update_post_meta( $product_id, "_primary_term_{$taxonomy}", $term_id );
}
I hope this helps 🙂