in_category vs has_term? Como comprobar relaciones padre/hijo? Una guía completa de ingenieria para la lógica de taxonomías en WordPress.
ES

Lógica condicional de WordPress para taxonomías

5.00 /5 - (23 votes )
Última verificación: 1 de mayo de 2026
6min de lectura
Guía
Desarrollador full-stack

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:

  1. Cargar assets: “Solo cargar el JavaScript pesado del Mapa en entradas de la categoría ‘Ubicaciones’.”
  2. 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

ErrorCausaSolución
in_category() devuelve false para subcategoriasNo comprueba descendientesUsar función auxiliar recursiva
is_tax() devuelve false en single postsComprueba contexto de página, no del postUsar has_term()
has_term() lento en bucles grandesConsultas repetidasImplementar Object Cache
Taxonomía no reconocidaRegistrada despues de la comprobacionMover registro a init con prioridad baja

#Resumen

  1. Usa has_term() para robustez en todas las taxonomías.
  2. Usa funciones auxiliares personalizadas para comprobaciones recursivas/jerarquicas.
  3. Optimiza el rendimiento confiando en Object Cache.
  4. 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.

Siguiente paso

Transforma el artículo en una implementación real

Este bloque refuerza el enlazado interno y lleva al lector al siguiente paso más útil dentro de la arquitectura del sitio.

¿Quieres implementar esto en tu sitio?

Si quieres transformar el artículo en mejoras concretas, rediseño o un plan de implementación, puedo cerrar el alcance y ejecutar.

Cluster relacionado

Explora otros servicios WordPress y base de conocimiento

Refuerza tu negocio con soporte técnico profesional en áreas clave del ecosistema WordPress.

FAQ del artículo

Preguntas Frecuentes

Respuestas prácticas para aplicar el tema en la ejecución real.

SEO-ready GEO-ready AEO-ready 3 Q&A
Cuando debo usar has_term() en lugar de in_category()?
Usa has_term() siempre que trabajes con taxonomías personalizadas o quieras un enfoque más flexible. in_category() esta limitado a la taxonomía de categorías integrada.
Como compruebo correctamente las categorías hijas en WordPress?
Para lógica padre-hijo generalmente necesitas un helper que expanda los descendientes con get_term_children() y luego compruebe la pertenencia contra esa lista.
Pueden los condicionales de taxonomía afectar el rendimiento?
Las comprobaciones simples de terminos suelen ser baratas, pero las búsquedas recursivas y las llamadas repetidas dentro de bucles grandes pueden anadir sobrecarga. Los proyectos con mucho cache deben mantener esa lógica ligera.

¿Necesitas un FAQ adaptado a tu sector y mercado? Preparamos una versión alineada con tus objetivos de negocio.

Hablemos

Artículos Relacionados

RSS no esta muerto. Aprende como personalizar los feeds de WordPress, agregar imágenes destacadas, soportar Podcasting e implementar JSON Feed para aplicaciones headless.
development

Dominando los feeds RSS de WordPress en 2026: Guia del desarrollador

RSS no esta muerto. Aprende como personalizar los feeds de WordPress, agregar imágenes destacadas, soportar Podcasting e implementar JSON Feed para aplicaciones headless.

has_term() e is_tax() se confunden a menudo. Consulta la guía completa sobre lógica condicional para categorías, etiquetas y taxonomías personalizadas.
development

Comprobar si una entrada pertenece a un termino de taxonomía

has_term() e is_tax() se confunden a menudo. Consulta la guía completa sobre lógica condicional para categorías, etiquetas y taxonomías personalizadas.

Notas prácticas sobre WP_Query: cuándo get_posts gana a new WP_Query, por qué meta_query sobre claves no indexadas colapsa a escala, y cómo paginar loops personalizados sin caer en 404.
development

Una guía práctica de WP_Query y el Loop (edición de rendimiento 2026)

Notas prácticas sobre WP_Query: cuándo get_posts gana a new WP_Query, por qué meta_query sobre claves no indexadas colapsa a escala, y cómo paginar loops personalizados sin caer en 404.