Verifică dacă un post se află în orice subcategorie a unei categorii părinte
Într-un site pe care îl dezvolt, am următoarea structură de categorii:
* filme (părinte)
* thriller (copil)
* comedie (copil)
* dramă (copil)
Postul curent se află în categoria comedie. Funcția has_term cu următorii parametri returnează true:
has_term( 'comedie', 'category' )
Dar, aceeași funcție cu următorii parametri returnează false:
has_term( 'filme', 'category' )
Întrebarea mea este: există o funcție de bază pentru a verifica dacă postul curent se află în orice subcategorie a unei categorii părinte specifice? Dacă nu, cum pot face această verificare?
Mulțumesc anticipat
Adăugați următoarele în functions.php al temei dumneavoastră:
/**
* Testează dacă oricare dintre categoriile alocate unui post sunt descendente ale categoriilor țintă
*
* @param int|array $cats Categoriile țintă. ID-ul ca întreg sau un array de ID-uri întregi
* @param int|object $_post Postul. Omiteți pentru a testa postul curent din Loop sau interogarea principală
* @return bool True dacă cel puțin 1 dintre categoriile postului este descendentă a oricăreia dintre categoriile țintă
* @see get_term_by() Puteți obține o categorie după nume sau slug, apoi trimiteți ID-ul către această funcție
* @uses get_term_children() Trimite $cats
* @uses in_category() Trimite $_post (poate fi gol)
* @version 2.7
* @link http://codex.wordpress.org/Function_Reference/in_category#Testing_if_a_post_is_in_a_descendant_category
*/
if ( ! function_exists( 'post_is_in_descendant_category' ) ) {
function post_is_in_descendant_category( $cats, $_post = null ) {
foreach ( (array) $cats as $cat ) {
// get_term_children() acceptă doar ID-uri întregi
$descendants = get_term_children( (int) $cat, 'category' );
if ( $descendants && in_category( $descendants, $_post ) )
return true;
}
return false;
}
}
Utilizați funcția pentru a verifica ID-ul categoriei părinte, nu numele sau slug-ul. De exemplu, dacă ID-ul categoriei 'movies' este 50:
if ( post_is_in_descendant_category( 50 ) ) {
// fă ceva
}
Dacă nu cunoașteți ID-ul categoriei 'movies', puteți obține ID-ul folosind get_term_by() și să-l trimiteți către post_is_in_descendant_category():
$category_to_check = get_term_by( 'name', 'movies', 'category' );
if ( post_is_in_descendant_category( $category_to_check->term_id ) ) {
// fă ceva
}

Dacă dorești orice adâncime de imbricare, folosește get_posts
.
/**
* Verifică dacă postarea se află într-una din categorii sau orice categorie copil.
*
* @param int|string|array $category_ids (ID-ul unei singure categorii) sau (șir de caractere separat prin virgule sau array de ID-uri de categorii).
* @param int $post_id ID-ul postării de verificat. Implicit este `get_the_ID()`.
* @return bool true, dacă postarea se află în orice categorie sau categorie copil.
*/
function is_post_in_category( $category_ids, $post_id = null ) {
$args = array(
'include' => $post_id ?? get_the_ID(),
'category' => $category_ids,
'fields' => 'ids',
);
return 0 < count( get_posts( $args ) );
}
Poți extinde această funcție în multe moduri. Poate să transmiți un array de ID-uri de postări și să filtrezi unele sau să permiți rafinarea interogării.

Actualizare pentru utilizarea taxonomiilor personalizate:
/**
* Testează dacă oricare dintre categoriile alocate unui articol sunt descendente ale categoriilor țintă
*
* @param int|array $cats Categoriile țintă. ID-ul ca întreg sau un array de ID-uri întregi
* @param int|object $_post Articolul. Lăsați necompletat pentru a testa articolul curent din Loop sau interogarea principală
* @param string $target_cat Numele taxonomiei pentru care se face interogarea. Lăsați necompletat pentru a utiliza taxonomia implicită 'category' utilizată pentru articole
* @return bool True dacă cel puțin 1 dintre categoriile articolului este un descendent al oricăreia dintre categoriile țintă
* @see get_term_by() Puteți obține o categorie după nume sau slug, apoi transmiteți ID-ul acestei funcții
* @uses get_term_children() Transmite $cats
* @uses in_category() Transmite $_post (poate fi gol)
* @version 2.7
* @link https://developer.wordpress.org/reference/functions/in_category/#comment-4999
*/
if(!function_exists('post_is_in_descendant_category')) {
function post_is_in_descendant_category($cats, $_post = null, $target_cat = 'category') {
foreach((array) $cats as $cat) {
// get_term_children() acceptă doar ID-uri întregi
$descendants = get_term_children((int) $cat, $target_cat);
if($descendants && has_term($descendants, $target_cat, $_post)) {
return true;
}
}
return false;
}
}
Context
in_category
utilizează has_category
care la rândul său apelează has_term( $category, 'category', $post )
cu 'category' setat hard-codat ca taxonomie.
Folosirea directă a has_term()
ne permite să verificăm o taxonomie personalizată precum product_cat (WooCommerce) sau orice altă taxonomie.
Funcția utilizează category ca valoare implicită, astfel încât aceasta poate fi utilizată ca înlocuitor direct.
Utilizare
Apelați funcția astfel:
if(post_is_in_descendant_category($category_to_check->term_id, $post, 'product_cat')) {
// fă ceva
}
