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.
Código (fragmento)
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 );
}
?>
Mostrar una lista separada 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 );
}
?>
Todas las formas de obtener el nombre como texto plano
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 objetosWP_Termde la entrada actual.$categories[0]->namees 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 enfalsehace que la función devuelva el valor en lugar de imprimirlo.get_the_terms()frente aget_the_term_list(): la segunda genera HTML con enlaces ya montados, la primera devuelve objetos crudos. Para texto plano y control total del marcado quieresget_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.
Ordenar y excluir categorías
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.
¿Por qué get_the_category()?
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)
Aplicación práctica
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.
Uso avanzado: categoría primaria con plugins SEO
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 ) : '';
}
Estilización de etiquetas de categoría
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;
}
Categorías en formatos de tarjeta de blog
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; ?>
Para taxonomías personalizadas
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 );
}
Función helper reutilizable
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"
Escapado e internacionalización
Los nombres de término pasan por sanitize_term_field() al guardarse, así que un nombre como “Diseño & UX” puede llegar a tu plantilla con la entidad & ya codificada. Si lo vuelves a escapar sin más, el visitante verá “&” en pantalla. La secuencia segura es decodificar las entidades almacenadas y escapar una sola vez en el momento de imprimir:
<?php
$categories = get_the_category();
if ( ! empty( $categories ) ) {
// El nombre almacenado puede contener entidades, p. ej. "Diseño & UX"
$raw = $categories[0]->name;
$clean = wp_specialchars_decode( $raw, ENT_QUOTES );
// Escapar una sola vez, justo al imprimir
echo esc_html( $clean );
}
?>
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.
Uso en el editor de bloques y shortcodes
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.
Errores comunes
Tres fallos que aparecen una y otra vez en temas heredados:
- 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 conob_start()y pasarla porstrip_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. - Olvidar
wp_reset_postdata()tras un loop personalizado.get_the_category()sin argumento lee la entrada global. Si acabas de recorrer unWP_Querysecundario 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
?>
- No comprobar
is_wp_error()conget_the_terms(). Si la taxonomía no está registrada (un plugin desactivado, un typo en el nombre), la función devuelve un objetoWP_Errory elforeachposterior lanza un aviso. La comprobación dobleif ( $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 evitarget_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







