La lógica es el cerebro de tu tema. En 2026, con Full Site Editing (FSE) y Block Themes complejos, podrias pensar que la lógica PHP es obsoleta. No lo es. La lógica del backend determina que renderizar antes de que el Editor de Bloques siquiera se cargue.
Descubre más sobre desarrollo profesional WordPress en WPPoland.
Un error comun que cometen los desarrolladores es confundir in_category() (para la taxonomía nativa ‘category’) con has_term() (para taxonomías personalizadas).
Esta guía establece los Procedimientos Operativos Estándar para la lógica condicional en el desarrollo moderno de WordPress.
Parte 1: Los fundamentos - Comprobando categorías
1. in_category()
Usa esto ESTRICTAMENTE para la taxonomía integrada “Category”.
if ( in_category( 'news' ) ) {
// Esta es una entrada de Noticias.
}
Advertencia: Comprueba el slug o ID. NO comprueba taxonomías personalizadas (como ‘product_cat’ en WooCommerce).
2. has_term() (la herramienta universal)
En 2026, casí siempre deberias preferir has_term(). Funciona para todo: Categorías, Etiquetas y Taxonomías Personalizadas.
// Comprobar si la entrada actual esta en el termino 'jeans' de la taxonomia 'product_cat'
if ( has_term( 'jeans', 'product_cat' ) ) {
// Es un par de vaqueros.
}
Parte 2: La complejidad de la jerarquía (hijos y padres)
Las funciones nativas de WordPress comprueban coincidencias exactas.
Si compruebas in_category('fruta'), pero la entrada solo esta en la categoría hija manzana, la comprobacion devuelve FALSE.
Esta es la fuente #1 de errores logicos.
La solución: post_is_in_descendant_category()
WordPress todavia no tiene una función de comprobacion recursiva integrada en el nucleo (ni siquiera en 2026). Debes implementar una función auxiliar.
/**
* Comprueba si una entrada pertenece a una categoria o a cualquiera de sus descendientes.
* Optimizado para rendimiento usando cache de get_term_children.
*
* @param int|string $field Clase/Slug/ID de la categoria
* @param int $post_id Opcional. ID de la entrada.
* @return bool
*/
function wppoland_post_is_in_descendant_category( $cats, $_post = null ) {
$_post = get_post( $_post );
if ( ! $_post ) return false;
$term_id = is_numeric($cats) ? $cats : get_cat_ID($cats);
if (! $term_id) return false;
$descendants = get_term_children( $term_id, 'category' );
$descendants[] = $term_id; // Incluir el padre mismo
return in_category( $descendants, $_post );
}
Parte 3: Etiquetas condicionales en 2026
La lógica moderna de WordPress a menudo se maneja en theme.json o plugins de Block Logic, pero las condiciones PHP codificadas siguen siendo vitales para:
- Cargar assets: “Solo cargar el JavaScript pesado del Mapa en entradas de la categoría ‘Ubicaciones’.”
- Filtrar contenido: “Anadir automáticamente un aviso legal a todas las entradas en ‘Consejos Medicos’.”
Ejemplo: Carga inteligente de assets
add_action( 'wp_enqueue_scripts', function() {
if ( has_term( 'marketing', 'category' ) || is_page_template( 'landing.php' ) ) {
wp_enqueue_script( 'conversión-tracking' );
}
} );
Parte 4: Operadores logicos y rendimiento
is_object_in_term
Si ejecutas lógica fuera del loop (p. ej., en un trabajo en segundo plano o endpoint REST API), usa is_object_in_term(). Evita configurar el objeto post global.
Impacto en la base de datos
Cada llamada a has_term desencadena una búsqueda en cache. Es rápida (O(1)), porque los terminos se almacenan en memoria (Object Cache).
Sin embargo, get_term_children puede ser costoso en taxonomías masivas (10,000+ terminos) si no se cachea correctamente via Redis/Memcached.
Parte 5: Especificidades de WooCommerce
WooCommerce tiene sus propios condicionales logicos.
is_product()is_shop()is_product_category()
Error comun: Intentar usar is_product_category() dentro de un Loop estándar.
Si estas iterando sobre productos en una consulta de Entradas del Blog, is_product_category() devolvera false (porque la página no es un archivo de categoría). Debes usar has_term( $term, 'product_cat', $post_id ).
Parte 6: Patrones avanzados para temas Block en 2026
Condicionales en bloques personalizados
Con la llegada de los bloques personalizados y Full Site Editing, la lógica condicional se ha movido parcialmente al editor. Sin embargo, la lógica del servidor sigue siendo fundamental para:
- Pre-renderizado de bloques: Determinar que variacion de bloque mostrar basandose en la taxonomía
- Personalización de consultas: Modificar WP_Query basandose en relaciones taxonomicas
- API REST personalizada: Filtrar respuestas según terminos asignados
// Ejemplo: Filtrar bloques dinamicos según la categoria del post
add_filter( 'render_block', function( $block_content, $block ) {
if ( $block['blockName'] === 'core/group' ) {
if ( has_term( 'premium', 'membership_level' ) ) {
return $block_content;
}
return ''; // Ocultar para usuarios no premium
}
return $block_content;
}, 10, 2 );
Taxonomías jerarquicas vs planas
Es importante distinguir entre taxonomías jerarquicas (como categorías) y planas (como etiquetas):
// Taxonomia jerarquica - necesita comprobacion recursiva
$taxonomy = get_taxonomy( 'product_cat' );
if ( $taxonomy->hierarchical ) {
// Usar función auxiliar con get_term_children()
$result = wppoland_in_term_tree( 'electronics', 'product_cat' );
} else {
// Comprobacion directa es suficiente
$result = has_term( 'electronics', 'product_tag' );
}
Optimización con Object Cache
Para sitios de alto tráfico, almacena en cache los resultados de las comprobaciones de taxonomía:
function wppoland_cached_term_check( $term, $taxonomy, $post_id = null ) {
$post_id = $post_id ?: get_the_ID();
$cache_key = "term_check_{$term}_{$taxonomy}_{$post_id}";
$result = wp_cache_get( $cache_key, 'term_checks' );
if ( false === $result ) {
$result = has_term( $term, $taxonomy, $post_id ) ? 1 : 0;
wp_cache_set( $cache_key, $result, 'term_checks', HOUR_IN_SECONDS );
}
return (bool) $result;
}
Parte 7: Depuracion de condicionales
Usando Query Monitor
El plugin Query Monitor es invaluable para depurar lógica condicional:
// Registrar comprobaciones de terminos en el log
if ( defined( 'QM_LOG' ) ) {
do_action( 'qm/debug', sprintf(
'Post %d: has_term(%s, %s) = %s',
get_the_ID(),
'news',
'category',
has_term( 'news', 'category' ) ? 'true' : 'false'
));
}
Errores comunes y soluciones
| Error | Causa | Solución |
|---|---|---|
in_category() devuelve false para subcategorias | No comprueba descendientes | Usar función auxiliar recursiva |
is_tax() devuelve false en single posts | Comprueba contexto de página, no del post | Usar has_term() |
has_term() lento en bucles grandes | Consultas repetidas | Implementar Object Cache |
| Taxonomía no reconocida | Registrada despues de la comprobacion | Mover registro a init con prioridad baja |
Resumen
- Usa
has_term()para robustez en todas las taxonomías. - Usa funciones auxiliares personalizadas para comprobaciones recursivas/jerarquicas.
- Optimiza el rendimiento confiando en Object Cache.
- Distingue entre Contexto de página (
is_category()) y Datos del post (in_category()).
La lógica es binaria. Asegurate de que la tuya sea TRUE.

