Cómo obtener el nombre de categoría sin enlace en WordPress (get_the_category)

Cómo obtener el nombre de categoría sin enlace en WordPress (get_the_category)

Última verificación: 14 de octubre de 2026
16 min de lectura
Tutorial
500+ proyectos WP
Desarrollador full-stack

La función estándar de WordPress the_category() es genial, pero tiene un defecto: siempre genera enlaces HTML (<a href="...">...</a>) a la página de archivo. ¿Qué pasa si estás construyendo un diseño personalizado (como una tarjeta de portfolio o un slider) donde la categoría debe ser texto plano, no un elemento clicable?

Descubre más sobre desarrollo profesional WordPress en WPPoland. La solución es usar get_the_category(), que devuelve un array de objetos en lugar de HTML listo.

#Obtener la categoría de una entrada sin enlace en PHP

Aquí tienes un fragmento listo para usar que puedes pegar en tu single.php o content.php:

<?php
// Obtener todas las categorías asignadas a la entrada actual
$categories = get_the_category();

if ( ! empty( $categories ) ) {
    // Mostrar el nombre de la primera categoría encontrada
    echo esc_html( $categories[0]->name );
}
?>

#Cómo mostrar varias categorías separadas por comas

Si tu entrada tiene múltiples categorías y quieres listarlas como texto separado por comas:

<?php
$categories = get_the_category();
$output     = array();

if ( ! empty( $categories ) ) {
    foreach ( $categories as $category ) {
        // Añadir nombre al array
        $output[] = esc_html( $category->name );
    }
    // Unir el array en una cadena con separador
    echo implode( ', ', $output );
}
?>

#Funciones de WordPress para obtener el nombre de categoría

WordPress trae varias funciones que devuelven el nombre de una categoría sin envolverlo en un enlace. Cada una encaja en un contexto distinto:

  • get_the_category(): dentro del loop, devuelve un array de objetos WP_Term de la entrada actual. $categories[0]->name es el acceso más directo al primer nombre.
  • get_cat_name( $cat_id ): recibe un ID y devuelve solo el nombre como cadena. Útil cuando ya conoces el ID, por ejemplo guardado en un campo de opciones del tema.
  • single_cat_title( '', false ): en páginas de archivo de categoría devuelve el título del archivo actual. El segundo parámetro en false hace que la función devuelva el valor en lugar de imprimirlo.
  • get_the_terms() frente a get_the_term_list(): la segunda genera HTML con enlaces ya montados, la primera devuelve objetos crudos. Para texto plano y control total del marcado quieres get_the_terms().
<?php
// 1. Dentro del loop: primera categoría de la entrada actual
$categories = get_the_category();
if ( ! empty( $categories ) ) {
    echo esc_html( $categories[0]->name );
}

// 2. Con un ID conocido, dentro o fuera del loop
echo esc_html( get_cat_name( 12 ) );

// 3. En category.php o archive.php: título del archivo actual
if ( is_category() ) {
    echo esc_html( single_cat_title( '', false ) );
}

// 4. get_the_terms(): objetos crudos, sin HTML generado
$terms = get_the_terms( get_the_ID(), 'category' );
if ( $terms && ! is_wp_error( $terms ) ) {
    echo esc_html( $terms[0]->name );
}
?>

La regla práctica: si la función termina en _list o empieza por the_, imprime o devuelve HTML listo. Si empieza por get_the_ y devuelve objetos, tienes el control.

#Obtener los nombres de categoría como array con wp_get_post_terms

wp_get_post_terms() pasa su tercer argumento a wp_get_object_terms(), así que acepta las opciones de WP_Term_Query que get_the_terms() no admite. Con 'fields' => 'names' devuelve un array de cadenas y el bucle desaparece:

<?php
// Solo los nombres, primero las categorías más usadas
$nombres = wp_get_post_terms(
    get_the_ID(),
    'category',
    array(
        'fields'  => 'names',
        'orderby' => 'count',
        'order'   => 'DESC',
    )
);

if ( ! is_wp_error( $nombres ) && ! empty( $nombres ) ) {
    echo esc_html( implode( ', ', $nombres ) );
}
?>

El precio es la caché. get_the_terms() lee primero la caché de relaciones de cada entrada, y el WP_Query principal la rellena para todas las entradas de la página porque update_post_term_cache vale true por defecto. wp_get_post_terms() se salta esa caché y siempre llama a wp_get_object_terms(), de modo que en un archivo con veinte tarjetas lanza veinte consultas de términos para datos que WordPress ya tenía cargados. Dentro del loop, wp_list_pluck( get_the_category(), 'name' ) da el mismo array de nombres desde la caché. Reserva wp_get_post_terms() para los sitios donde necesitas sus argumentos, como ordenar por count en una barra lateral o un callback REST que trabaja con una sola entrada.

#Cómo ordenar y excluir categorías de una entrada

Cuando una entrada tiene varias categorías, WordPress las devuelve ordenadas por nombre de forma predeterminada, pero a menudo quieres otro orden o necesitas ocultar una categoría interna (por ejemplo una que solo usas para marcar entradas destacadas). Como get_the_category() devuelve un array normal de PHP, puedes filtrarlo y reordenarlo con las funciones estándar:

<?php
$categories = get_the_category();

if ( ! empty( $categories ) ) {
    // Excluir la categoría "destacados" por slug
    $categories = array_filter( $categories, function( $cat ) {
        return 'destacados' !== $cat->slug;
    } );

    // Ordenar por número de entradas, de mayor a menor
    usort( $categories, function( $a, $b ) {
        return $b->count - $a->count;
    } );

    $names = array_map( function( $cat ) {
        return esc_html( $cat->name );
    }, $categories );

    echo implode( ', ', $names );
}
?>

El mismo patrón sirve para excluir por term_id, limitar la lista con array_slice( $categories, 0, 2 ) o poner una categoría concreta siempre en primer lugar.

#Qué devuelve get_the_category() además del nombre

Esta función te da acceso al objeto completo de categoría. Además del nombre (->name), puedes extraer:

  • ->slug (útil para clases CSS, p. ej., <span class="cat-<?php echo $cat->slug; ?>">)
  • ->term_id (ID de la categoría)
  • ->description (descripción de la categoría)
  • ->count (número de entradas en esta categoría)

#Qué hace get_the_category dentro del núcleo de WordPress

En el código fuente de wordpress-develop, get_the_category() es un envoltorio fino. Llama a get_the_terms( $post_id, 'category' ), convierte un resultado false o WP_Error en un array vacío, lo reindexa con array_values(), pasa cada término por la función privada _make_cat_compat() y devuelve el resultado a través del filtro get_the_categories. De esas pocas líneas salen tres consecuencias prácticas.

Las propiedades heredadas solo existen en la salida de esta función. _make_cat_compat() copia los campos modernos a nombres antiguos: cat_ID, cat_name, category_nicename, category_count, category_description y category_parent. Los objetos de get_the_terms() no las reciben. Una plantilla que lee $cat->cat_name funciona hoy y deja de mostrar nada el día que alguien cambia la llamada por get_the_terms() para admitir una taxonomía personalizada. Lee name, slug y term_id, que comparten ambas funciones.

El orden es alfabético, no editorial. get_the_terms() consulta primero la caché de relaciones de términos de la entrada y, si no hay datos, llama a wp_get_object_terms(), que ejecuta un WP_Term_Query cuyo orderby predeterminado es name. Por eso $categories[0] es la primera categoría por orden alfabético, salvo que un filtro reordene el array. Nunca es la categoría principal elegida en un plugin SEO.

Los plugins pueden reescribir el array. Cualquier función enganchada a get_the_categories (con el argumento $post_id desde WordPress 4.4) o a get_the_terms puede añadir, quitar o reordenar términos antes de que tu plantilla los vea. Si una etiqueta muestra una categoría que el editor nunca asignó, revisa las funciones enganchadas a esos dos hooks antes de depurar la plantilla.

#Cómo mostrar la categoría como etiqueta con clase CSS

Un caso de uso común es estilizar etiquetas en tarjetas de blog.

// Dentro del loop de WordPress
$cats = get_the_category();
$first_cat = !empty($cats) ? $cats[0] : null;

if ($first_cat) : ?>
    <span class="badge badge-<?php echo esc_attr($first_cat->slug); ?>">
        <?php echo esc_html($first_cat->name); ?>
    </span>
<?php endif; ?>

De esta forma, si tienes una categoría “Noticias”, obtendrás la clase .badge-noticias, que puedes colorear fácilmente en CSS. Este nivel de control es algo que the_category() simplemente no ofrece.

#Obtener la categoría principal de Yoast o Rank Math

Cuando una entrada tiene múltiples categorías, es común querer mostrar solo la “principal”:

function wppoland_get_primary_category_name() {
    $post_id = get_the_ID();

    // Intentar obtener categoría primaria de Yoast
    if ( class_exists( 'WPSEO_Primary_Term' ) ) {
        $primary = new WPSEO_Primary_Term( 'category', $post_id );
        $term_id = $primary->get_primary_term();
        if ( $term_id ) {
            $term = get_term( $term_id );
            if ( ! is_wp_error( $term ) ) {
                return esc_html( $term->name );
            }
        }
    }

    // Intentar obtener de RankMath
    $rankmath_primary = get_post_meta( $post_id, 'rank_math_primary_category', true );
    if ( $rankmath_primary ) {
        $term = get_term( $rankmath_primary );
        if ( ! is_wp_error( $term ) ) {
            return esc_html( $term->name );
        }
    }

    // Fallback: primera categoría
    $cats = get_the_category( $post_id );
    return ! empty( $cats ) ? esc_html( $cats[0]->name ) : '';
}

#CSS para etiquetas de categoría en WordPress

CSS para badges de categoría elegantes:

.badge {
    display: inline-block;
    padding: 0.25rem 0.75rem;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    border-radius: 9999px;
    background: #e5e7eb;
    color: #374151;
}

/* Colores por categoría */
.badge-noticias {
    background: #dbeafe;
    color: #1e40af;
}

.badge-tutorial {
    background: #d1fae5;
    color: #065f46;
}

.badge-opinion {
    background: #fef3c7;
    color: #92400e;
}

/* Hover sutil */
.badge:hover {
    filter: brightness(0.95);
    cursor: default;
}

#Plantilla de tarjeta de blog con la categoría como insignia

Un ejemplo completo de tarjeta de blog con categoría como insignia:

<?php while ( have_posts() ) : the_post(); ?>
    <article class="blog-card">
        <?php if ( has_post_thumbnail() ) : ?>
            <div class="card-image">
                <?php the_post_thumbnail( 'medium_large' ); ?>

                <?php
                $cats = get_the_category();
                if ( ! empty( $cats ) ) :
                    $primary_cat = $cats[0];
                ?>
                    <span class="card-badge badge-<?php echo esc_attr( $primary_cat->slug ); ?>">
                        <?php echo esc_html( $primary_cat->name ); ?>
                    </span>
                <?php endif; ?>
            </div>
        <?php endif; ?>

        <div class="card-content">
            <h2 class="card-title">
                <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
            </h2>

            <div class="card-meta">
                <time datetime="<?php echo get_the_date('c'); ?>">
                    <?php echo get_the_date(); ?>
                </time>

                <?php
                // Mostrar todas las categorías como texto
                $all_cats = get_the_category();
                $cat_names = array_map( function( $cat ) {
                    return esc_html( $cat->name );
                }, $all_cats );
                echo '<span class="categories">' . implode( ' / ', $cat_names ) . '</span>';
                ?>
            </div>

            <p class="card-excerpt"><?php echo wp_trim_words( get_the_excerpt(), 20 ); ?></p>
        </div>
    </article>
<?php endwhile; ?>

#Nombre de un término de taxonomía personalizada sin enlace

El mismo principio se aplica a taxonomías personalizadas con get_the_terms():

$genres = get_the_terms( get_the_ID(), 'genre' );

if ( ! empty( $genres ) && ! is_wp_error( $genres ) ) {
    $genre_names = array();
    foreach ( $genres as $genre ) {
        $genre_names[] = esc_html( $genre->name );
    }
    echo implode( ', ', $genre_names );
}

#Cómo obtener términos de cualquier taxonomía como texto

Crea una función helper que funcione con cualquier taxonomía:

/**
 * Obtener nombres de términos como texto plano
 *
 * @param string $taxonomy Nombre de la taxonomía
 * @param string $separator Separador entre nombres
 * @param int|null $post_id ID de la entrada
 * @return string Lista de nombres separados
 */
function wppoland_get_term_names( $taxonomy = 'category', $separator = ', ', $post_id = null ) {
    $post_id = $post_id ?: get_the_ID();

    if ( $taxonomy === 'category' ) {
        $terms = get_the_category( $post_id );
    } else {
        $terms = get_the_terms( $post_id, $taxonomy );
    }

    if ( empty( $terms ) || is_wp_error( $terms ) ) {
        return '';
    }

    $names = array_map( function( $term ) {
        return esc_html( $term->name );
    }, $terms );

    return implode( $separator, $names );
}

// Uso:
echo wppoland_get_term_names( 'category' );           // "Noticias, WordPress"
echo wppoland_get_term_names( 'post_tag', ' | ' );    // "PHP | CSS | HTML"
echo wppoland_get_term_names( 'genre', ' / ', 123 );  // "Acción / Drama"

#Cómo escapar el nombre de categoría con WPML o Polylang

Antes de guardar un término, default-filters.php pasa el nombre por sanitize_text_field(), wp_filter_kses() y, con prioridad 30, por _wp_specialchars() en el hook pre_term_name. Las etiquetas HTML se eliminan al guardar, y un nombre como “Diseño & UX” queda en la base de datos como Diseño &amp; UX.

Dentro de HTML eso no causa problemas. esc_html() llama a _wp_specialchars() con la doble codificación desactivada, así que un &amp; existente se queda como &amp; y el navegador muestra un ”&” normal. El &amp; literal aparece fuera de HTML: en un JSON-LD construido con wp_json_encode(), en un campo REST que JavaScript escribe con textContent, en el asunto de un correo en texto plano o en una exportación CSV. Una llamada a htmlspecialchars() de PHP, que codifica dos veces por defecto, produce el &amp;amp; visible. En esos contextos decodifica primero y aplica después el escape del formato de destino:

<?php
$categories = get_the_category();

if ( ! empty( $categories ) ) {
    // Convertir el "&amp;" almacenado en "&" para un contexto que no es HTML
    $nombre = wp_specialchars_decode( $categories[0]->name, ENT_QUOTES );

    $schema = array( 'articleSection' => $nombre );
    echo wp_json_encode( $schema );
}
?>

Sobre la internacionalización: los nombres de categoría son contenido, no cadenas de código, así que no pasan por __() ni por los archivos .po del tema. Si el sitio es multilingüe con WPML o Polylang, get_the_category() ya devuelve el término traducido del idioma activo, no tienes que hacer nada extra. Lo que sí conviene traducir con esc_html__() son las etiquetas fijas alrededor, como el texto “Publicado en:” que precede a la lista.

#Cómo mostrar la categoría en el editor de bloques con un shortcode

En temas de bloques y patrones no puedes soltar PHP directamente en la plantilla. Un shortcode mínimo hace de puente: registra una función que devuelva (no imprima) el nombre plano y podrás usarla en el bloque Shortcode, dentro de patrones o en widgets clásicos:

<?php
// functions.php del tema hijo o un plugin propio
add_shortcode( 'categoria_texto', function() {
    $categories = get_the_category();

    if ( empty( $categories ) ) {
        return '';
    }

    // return, nunca echo: un shortcode debe devolver su salida
    return esc_html( $categories[0]->name );
} );
?>

Después basta con insertar [categoria_texto] donde lo necesites. Como el shortcode lee la entrada global, funciona en plantillas de entrada individual y dentro del loop de un bloque Query Loop.

El bloque Términos de la entrada (Post Terms) del núcleo no sirve como alternativa. Su block.json define solo los atributos term, separator, prefix y suffix, y su callback de renderizado en PHP construye la salida con get_the_term_list(), así que cada término que imprime es un enlace. No existe ningún ajuste que quite los enlaces. Un CSS como pointer-events: none solo oculta el clic: el marcado sigue siendo un ancla y los lectores de pantalla siguen anunciando un enlace.

#Por qué no usar strip_tags sobre the_category

Este atajo sigue apareciendo en temas antiguos y en respuestas de foros:

<?php
// Antipatrón: no lo hagas.
echo strip_tags( get_the_category_list( ', ' ) );
?>

Problemas concretos:

  1. Trabajo inútil. WordPress construye el HTML completo con enlaces, rel y URL para que tú tires las etiquetas.
  2. Separadores frágiles. Si el tema o un filtro sobre the_category añade envoltorios, strip_tags() puede pegar nombres sin espacio.
  3. No escapa. Después de strip_tags() sigues necesitando esc_html(), y mucha gente lo olvida.
  4. Pierdes los datos. Sin el objeto no tienes slug ni term_id para clases CSS o schema, así que acabas volviendo a get_the_category().

Reserva strip_tags() para contenido rico de origen desconocido, no para quitar anclas que tú mismo has pedido a la API.

#Cómo cachear el nombre de categoría en WordPress

get_the_category() y get_the_terms() leen la relación entre entrada y términos y los objetos WP_Term. Con una caché de objetos persistente (Redis o Memcached mediante drop-in), términos y relaciones entran en caché sin código adicional. En la práctica:

  • No crees un transient por tarjeta solo para el nombre de la categoría en el loop principal: el coste de get_the_category() es bajo frente al resto de la plantilla.
  • Si cacheas fragmentos HTML completos (tarjetas en transient o en el edge), el nombre va dentro del fragmento, y el fragmento se invalida al guardar la entrada (save_post) o al editar el término (edited_term).
  • Si tu índice propio (Elasticsearch, una tabla personalizada) guarda solo el term_id, resuelve el name al renderizar con get_term(). Así, renombrar una categoría actualiza el archivo sin reconstruir el índice.
<?php
add_action(
    'save_post_post',
    function ( $post_id ) {
        delete_transient( 'wppoland_card_html_' . (int) $post_id );
    }
);
?>

#Cuándo usar the_category con enlaces

Hay pantallas en las que el marcado con enlaces es justo lo que se busca: la línea clásica “Publicado en Noticias, Eventos” bajo una entrada individual, un widget de metadatos donde cada categoría debe ser clicable o un tema minimalista sin tarjetas en el que los archivos de categoría son la navegación secundaria. Ahí llama a the_category( ', ' ) o usa el bloque Post Terms y no reconstruyas el marcado a mano. Si más adelante el diseño pide un enlace alrededor de una sola etiqueta, envuelve el nombre escapado en <a href="<?php echo esc_url( get_category_link( $term->term_id ) ); ?>"> en lugar de volver a the_category(). El error es mezclar los dos modos en un mismo componente sin una regla, así que deja la regla escrita en el tema: las etiquetas de tarjeta son texto, las líneas de metadatos son enlaces.

#Por qué get_the_category() devuelve categorías equivocadas

Tres fallos que aparecen una y otra vez en temas heredados:

  1. Intentar limpiar la salida de the_category(). Esta función imprime el marcado con enlaces directamente y no tiene modo de texto plano. Capturar su salida con ob_start() y pasarla por strip_tags() funciona, pero es frágil y lento. La solución correcta es no usarla: get_the_category() te da los datos crudos desde el principio.
  2. Olvidar wp_reset_postdata() tras un loop personalizado. get_the_category() sin argumento lee la entrada global. Si acabas de recorrer un WP_Query secundario y no restauras el estado, la siguiente llamada devuelve las categorías de la entrada equivocada:
<?php
$destacados = new WP_Query( array( 'posts_per_page' => 3 ) );

while ( $destacados->have_posts() ) {
    $destacados->the_post();
    $cats = get_the_category(); // correcto: lee la entrada del loop secundario
}

wp_reset_postdata(); // sin esta línea, get_the_category() posterior apunta mal
?>
  1. No comprobar is_wp_error() con get_the_terms(). Si la taxonomía no está registrada (un plugin desactivado, un typo en el nombre), la función devuelve un objeto WP_Error y el foreach posterior lanza un aviso. La comprobación doble if ( $terms && ! is_wp_error( $terms ) ) cubre los dos casos: sin términos y taxonomía inexistente.

#Resumen

get_the_category() es la herramienta correcta cuando necesitas nombres de categoría como texto plano sin enlaces. Los puntos clave son:

  • the_category() siempre genera enlaces HTML, no se puede evitar
  • get_the_category() devuelve objetos con acceso completo a metadatos
  • Siempre escapa la salida con esc_html() por seguridad
  • Usa implode() para listas separadas elegantemente
  • El mismo patrón funciona con taxonomías personalizadas vía get_the_terms()
  • Crea funciones helper reutilizables para mantener tu código DRY
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.

Explora otros servicios WordPress y base de conocimiento

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

Preguntas frecuentes

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

¿Por qué no usar the_category() si solo necesito texto?#
Porque the_category() imprime enlaces HTML listos. Si necesitas texto plano para una insignia, slider o diseño personalizado, get_the_category() te da acceso directo al objeto de categoría.
¿Cómo muestro solo el nombre de la primera categoría?#
Obtén el array de categorías con get_the_category(), comprueba que no está vacío, y luego imprime el nombre del primer elemento con el escapado adecuado.
¿Cómo puedo mostrar varios nombres de categoría sin enlaces?#
Recorre los objetos de categoría, recoge los nombres en un array y únelos con implode() para controlar el separador y evitar etiquetas anchor.
¿Funciona el mismo enfoque con taxonomías personalizadas?#
Sí. Usa get_the_terms() con el nombre de la taxonomía y comprueba is_wp_error() antes de leer los nombres, porque la función devuelve WP_Error si la taxonomía no está registrada.
¿Cómo muestro el nombre de categoría en el editor de bloques?#
Registra un shortcode que devuelva el nombre con get_the_category() y esc_html(), e insértalo con el bloque Shortcode dentro de la plantilla o el patrón.
¿Qué función devuelve el nombre de la categoría en una página de archivo?#
En un archivo de categoría usa single_cat_title() con false como segundo argumento, porque la categoría actual pertenece al objeto consultado, no a una entrada concreta.
¿Es strip_tags(get_the_category_list()) un buen atajo?#
No. Primero generas HTML con enlaces y después lo recortas. Pierdes el control sobre el escapado, los atributos y el orden. Lee los objetos de término y construye la cadena tú mismo con esc_html().
¿Qué pasa con la categoría principal de Yoast SEO o Rank Math?#
Estos plugins guardan el ID del término elegido en los metadatos de la entrada. Lee el meta, carga el término con get_term() y luego imprime el nombre. El índice [0] de get_the_category() no tiene por qué ser la categoría marcada como principal.

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

Hablemos

Artículos Relacionados