A
A
Alexey selftrips.ru2017-10-29 19:35:27
metadata
Alexey selftrips.ru, 2017-10-29 19:35:27

Where to rest (official docs) about displaying entries from 2 categories /category/slug1+slug2 (AND)?

Wordpress can display posts from 2 categories /category/slug1+slug2
Where can I read about this in the wordpress documentation?
ps
Can't do this when using the no category base plugin, which removes /category/ from the URL? I want to know if there is a way to solve this problem.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
Igor Vorotnev, 2017-10-30
@HeadOnFire

It's best to see what's going on under the hood. Using the Query Monitor plugin, you can see the resulting query and analyze it. I specifically created several categories and posts, and for debugging one post I assigned 3 categories, one of which is a child category of another (only hardcore!):

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts 
LEFT JOIN wp_term_relationships
ON (wp_posts.ID = wp_term_relationships.object_id) 
LEFT JOIN wp_term_relationships AS tt1
ON (wp_posts.ID = tt1.object_id) 
LEFT JOIN wp_term_relationships AS tt2
ON (wp_posts.ID = tt2.object_id)
WHERE 1=1 
AND ( wp_term_relationships.term_taxonomy_id IN (2,3,4) 
AND tt1.term_taxonomy_id IN (1) 
AND tt2.term_taxonomy_id IN (3) )
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'acf-disabled'
OR wp_posts.post_status = 'private')
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10

The most interesting here (removed unnecessary for clarity):
WHERE ( 
wp_term_relationships.term_taxonomy_id IN (2,3,4) 
AND 
tt1.term_taxonomy_id IN (1) 
AND 
tt2.term_taxonomy_id IN (3) 
)

What conclusions can be drawn?
1. Under each new term, there is an additional LEFT JOIN of the same wp_term_relationships table
2. WHERE uses the AND operator, that is, records that have all 3 terms will be selected
3. An important nuance is that in the first condition IN (2,3,4) are requested and the parent category (2), and all its children (3, 4) - this is an interesting point of main query on the pages of term archives
Total:
- The first term in the URL is the basis of the query
- All subsequent ones are thrown into the query via LEFT JOIN using the AND operator in WHERE
So everything works exactly as you need. Except for the important nuance number 3 (see above). But this is the standard behavior of WP, it can be changed:
https://wordpress.stackexchange.com/questions/5525...
https://gist.github.com/CodeProKid/1d21fb763514149...
The question remains "how to generate such a link". It's easy - just glue the site address, category base, and category slugs through +. We write a simple function:
/**
 * Generate a link for multiple categories
 * 
 * @param $categories array An array of category slugs
 *
 * @return string
 */
function my_categories_link( $categories ) {
    
    $category_base = get_option( 'category_base' ) ? get_option( 'category_base' ) : 'category';
    $categories_str = implode( '+', $categories );
  
    return sprintf( "%s/%s/%s/",
        home_url(),
        $category_base,
        $categories_str
    );
}

In the template, where the link should be made: Where one and two are the slugs of the required categories. You can finish the function so that it accepts a choice - IDs, slugs or category objects. But these are subtleties :)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question