selftrips
@selftrips

Где почить (официальные доки) про вывод записей из 2 категорий /category/slug1+slug2 (AND)?

Wordpress умеет выводить записи из 2 категорий /category/slug1+slug2
Где про это почить в документации wordpress?
ps
Не получается так сделать при использовании плагина no category base, который удаляет из URL /category/? хочу понять можно ли как то решить это проблему.
  • Вопрос задан
  • 195 просмотров
Пригласить эксперта
Ответы на вопрос 1
HeadOnFire
@HeadOnFire
PHP, Laravel & WordPress Evangelist
Лучше всего посмотреть, что происходит под капотом. С помощью плагина Query Monitor можно увидеть результирующий запрос и проанализировать его. Я специально создал несколько категорий и постов, и для отладки одному посту назначил 3 категории, одна из которых является дочерней категорией другой (только хардкор!):

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


Самое интересное тут (убрал лишнее для наглядности):

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) 
)


Какие выводы можно сделать?

1. Под каждый новый термин идет дополнительный LEFT JOIN все той же таблицы wp_term_relationships
2. WHERE использует оператор AND, то есть будут выбраны записи у которых есть все 3 термина
3. Важный нюанс - в первом условии IN (2,3,4) запрошены и родительская категори (2), так и все ее дочерние (3, 4) - это интересный момент main query на страницах архивов терминов

Итого:

- Первый термин в URL идет основой запроса
- Все последующие докидываются в запрос через LEFT JOIN с использованием оператора AND в WHERE

Значит, работает все именно так, как вам надо. За исключением важного нюанса номер 3 (см. выше). Но это стандартное поведение WP, его можно поменять:

https://wordpress.stackexchange.com/questions/5525...
https://gist.github.com/CodeProKid/1d21fb763514149...

Остается вопрос "как сгенерировать такую ссылку". Это несложно - достаточно склеить адрес сайта, category base, и слаги категорий через +. Пишем простую функцию:

/**
 * 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
    );
}


В темплейте, там где ссылку надо сделать:

echo my_categories_link( [ 'one', 'two' ] );

Где one и two - слаги нужных категорий.

Можно допилить функцию, чтобы она принимала на выбор - ID, слаги или объекты категорий. Но это уже тонкости :)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы