Como obter o nome da categoria sem link no WordPress (get_the_category)

Como obter o nome da categoria sem link no WordPress (get_the_category)

Última verificação: 21 de setembro de 2026
13 min de leitura
Tutorial
500+ projetos WP
Desenvolvedor full-stack

the_category() imprime âncoras HTML. Se o cartão do arquivo, o slider ou a badge do tema precisam de texto puro, essa função está no caminho errado. A alternativa correta é get_the_category() (ou get_the_terms() para taxonomias genéricas): devolve objetos PHP, e decide se o nome transforma-se em <span>, classe CSS ou string para um atributo aria-label.

Este tutorial cobre o contrato de saída de the_category(), a forma do array de get_the_category(), escape com esc_html(), listas com implode(), o antipadrão strip_tags( the_category() ), get_the_terms(), categoria primária (Yoast / Rank Math), Full Site Editing e o papel da object cache.

No Codex e no Developer Reference, the_category() é uma template tag de saída: escreve HTML no buffer. O separador entre categorias é um argumento de string, mas cada nome continua dentro de <a href="...">. Não existe parâmetro oficial para «só o nome».

<?php
// No Loop: imprime HTML com links para os arquivos de categoria.
the_category( ', ' );
?>

Exemplo típico de markup gerado (simplificado):

<a href="https://exemplo.pt/categoria/noticias/" rel="category tag">Notícias</a>,
<a href="https://exemplo.pt/categoria/eventos/" rel="category tag">Eventos</a>

Para um badge visual no content-card.php, esse markup traz problemas concretos:

  • o clique na badge compete com o clique no título do post;
  • estilos de a do tema (underline, cor de foco) herdam-se para a label;
  • leitores de ecrã anunciam «link» quando a intenção era só um rótulo;
  • em JSON-LD ou meta tags, o HTML fica exposto se alguém copiar a saída sem sanitizar.

Quando o desenho pede texto, leia dados. Quando o desenho pede navegação para o arquivo, aí sim the_category() ou um <a> construído à mão com get_category_link() fazem sentido.

#O que devolve get_the_category no WordPress

get_the_category( $post_id = false ) devolve um array de objetos WP_Term (historicamente documentados como objetos de categoria). Sem argumentos, usa o post global do Loop. Com ID, funciona fora do Loop, por exemplo num shortcode ou num callback REST.

Propriedades usadas na prática do tema:

PropriedadeUso típico
nameTexto visível da badge
slugClasse CSS (badge-noticias)
term_idChaves de cache, comparações
term_taxonomy_idIdentidade na tabela term_taxonomy
descriptionTooltips raros; costuma ser HTML
countContagem de posts na categoria
parentHierarquia; 0 = raiz
cat_IDAlias legado de term_id

Snippet mínimo para a primeira categoria:

<?php
$categories = get_the_category();

if ( ! empty( $categories ) ) {
	echo esc_html( $categories[0]->name );
}
?>

O índice [0] é a primeira categoria na ordem em que o WordPress as devolve para aquele post. Essa ordem não é «categoria primária SEO». Se o editor atribuiu três categorias e Yoast marcou outra como primary, $categories[0] pode ser a errada para o breadcrumb comercial. A secção sobre categoria primária cobre esse caso.

Posts sem categorias (ou tipos de conteúdo onde a taxonomia category não está registada) devolvem array vazio. O ! empty() evita avisos de índice indefinido em PHP 8+.

#Como escapar o nome da categoria com esc_html

Nomes de categoria são conteúdo editorial. Um editor com capacidade manage_categories pode meter <script> ou aspas no nome. Em HTML de texto, use esc_html(). Em atributos (class, data-*, aria-label), use esc_attr().

<?php
$categories = get_the_category();
$first      = ! empty( $categories ) ? $categories[0] : null;

if ( $first ) :
	?>
	<span
		class="badge badge-<?php echo esc_attr( $first->slug ); ?>"
		aria-label="<?php echo esc_attr( sprintf( 'Categoria: %s', $first->name ) ); ?>"
	>
		<?php echo esc_html( $first->name ); ?>
	</span>
	<?php
endif;

Diferença prática:

  • esc_html() converte <, >, &, aspas para entidades adequadas a nós de texto;
  • esc_attr() trata o contexto de atributo (aspas e caracteres que partem o markup);
  • sanitize_html_class( $first->slug ) é útil se o slug puder ter caracteres estranhos após migrações antigas.

Não escape duas vezes. esc_html( esc_html( $name ) ) não «segura mais»; só dificulta a leitura e pode alterar entidades em cenários edge.

Vários nomes sem âncoras: acumule strings escapadas e junte com implode().

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

if ( ! empty( $categories ) ) {
	foreach ( $categories as $category ) {
		$names[] = esc_html( $category->name );
	}

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

Vantagens face a concatenar à mão com $out .= $name . ', ':

  • o separador fica num sítio só;
  • não sobra vírgula final;
  • pode trocar ', ' por ' · ' ou por '</span><span class="sep">' sem reescrever o loop.

Se precisar de markup por item (cada nome num <span>), faça o escape dentro do fragmento e junte os fragmentos:

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

foreach ( (array) $categories as $category ) {
	$chips[] = sprintf(
		'<span class="chip chip-%1$s">%2$s</span>',
		esc_attr( $category->slug ),
		esc_html( $category->name )
	);
}

echo implode( ' ', $chips );
?>

Aqui implode junta HTML já escapado por peça. Não passe o HTML completo por esc_html() no fim - isso tornaria as tags visíveis como texto.

#Porque não usar strip_tags em the_category?

Ainda aparece em temas antigos e em respostas de fóruns:

<?php
// Antipadrão: não faças isto.
echo strip_tags( get_the_category_list( ', ' ) );
// ou:
ob_start();
the_category( ', ' );
echo strip_tags( ob_get_clean() );
?>

Problemas:

  1. Custo desnecessário. Constrói HTML completo (links, rel, URLs) para deitar fora as tags.
  2. Separadores frágeis. Se o tema ou um filtro em the_category injeta wrappers, strip_tags pode colar nomes sem espaço (NotíciasEventos).
  3. Escape errado. Depois de strip_tags, ainda precisa de esc_html(); muita gente esquece e imprime texto cru.
  4. Filtros laterais. Plugins que alteram o HTML de the_category passam a afetar «texto puro» sem o programador perceber.
  5. Testes. Unit tests sobre strings HTML são mais ruidosos do que asserts sobre $term->name.

O caminho curto e estável é get_the_category() + propriedade name. Reserve strip_tags para conteúdo rico onde realmente recebeu HTML de origem desconhecida - não para remover âncoras que o próprio pediu à API.

#Como obter termos de taxonomia personalizada com get_the_terms

get_the_category() é um atalho para a taxonomia category em posts. Em custom post types com taxonomias próprias (setor, tipo_projeto, mercado), use get_the_terms( $post, $taxonomy ).

<?php
$terms = get_the_terms( get_the_ID(), 'setor' );

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

$names = array();
foreach ( $terms as $term ) {
	$names[] = esc_html( $term->name );
}

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

Notas de contrato:

  • retorno pode ser false, array de WP_Term, ou WP_Error se a taxonomia não existir;
  • verifique sempre is_wp_error() antes de iterar;
  • a forma do objeto é a mesma família (name, slug, term_id);
  • para um único termo «como categoria principal do CPT», a mesma lógica de primary (meta do SEO plugin) aplica-se se o plugin a suportar nessa taxonomia.

wp_get_post_terms() é irmão próximo com argumentos de WP_Term_Query. Para «nomes no template», get_the_terms() costuma bastar e beneficia da cache de termos do post.

#Obter a categoria primária do Yoast e Rank Math

Em arquivos e cartões de blog corporativo, o negócio quer uma label: a categoria comercial, não a primeira da lista alfabética ou a ordem de atribuição no editor.

Yoast SEO grava o ID em post meta _yoast_wpseo_primary_category. Rank Math usa rank_math_primary_category. Sem plugin, defina a sua própria meta ou assuma $categories[0] de forma documentada no README do tema.

<?php
/**
 * Devolve o WP_Term da categoria primária, ou o primeiro de get_the_category().
 */
function wppoland_get_primary_category( $post_id = 0 ) {
	$post_id = $post_id ? (int) $post_id : get_the_ID();

	$primary_id = (int) get_post_meta( $post_id, '_yoast_wpseo_primary_category', true );
	if ( ! $primary_id ) {
		$primary_id = (int) get_post_meta( $post_id, 'rank_math_primary_category', true );
	}

	if ( $primary_id ) {
		$term = get_term( $primary_id, 'category' );
		if ( $term && ! is_wp_error( $term ) ) {
			return $term;
		}
	}

	$categories = get_the_category( $post_id );
	return ! empty( $categories ) ? $categories[0] : null;
}

$primary = wppoland_get_primary_category();
if ( $primary ) {
	echo esc_html( $primary->name );
}
?>

Regras de robustez:

  • se o termo primary foi apagado mas a meta ficou, faça fallback para get_the_category();
  • não faça cache do nome em transient sem invalidar quando o post ou o termo mudam;
  • no breadcrumb, a primary é a que deve alimentar o item intermédio entre Home e o post.

#Nome da categoria sem link no bloco Post Terms

Em temas de blocos (FSE), o bloco Post Categories / Post Terms renderiza links por omissão, alinhado com the_category(). Para texto puro no editor de site dispõe de três vias honestas:

  1. CSS only (limitado). pointer-events: none e text-decoration: none no bloco de categorias do cartão. Remove o gesto de clique visualmente, mas o markup continua a ser <a> - mau para acessibilidade e para «copiar como texto».
  2. Bloco personalizado ou variação. Um bloco dinâmico PHP que chama get_the_category() e imprime <span>. Registe com block.json e render_callback.
  3. Filtro no HTML do bloco. render_block pode reescrever o HTML do core, mas é frágil entre versões do WordPress. Prefira um bloco seu se o cartão for peça central do design system.

Exemplo mínimo de render_callback para um bloco de tema:

<?php
function wppoland_render_category_label_block( $attributes, $content, $block ) {
	$post_id = isset( $block->context['postId'] )
		? (int) $block->context['postId']
		: get_the_ID();

	$categories = get_the_category( $post_id );
	if ( empty( $categories ) ) {
		return '';
	}

	$term = $categories[0];
	return sprintf(
		'<span class="wp-block-wppoland-category-label">%s</span>',
		esc_html( $term->name )
	);
}
?>

No Query Loop, o contexto postId do bloco é o que garante a categoria do item certo - não dependa só do Loop global se o callback correr em contextos aninhados.

#Como fazer cache do nome da categoria no WordPress

get_the_category() e get_the_terms() leem a relação post-termo e os objetos WP_Term. Com object cache persistente (Redis, Memcached via drop-in), termos e meta entram em cache de forma transparente. Na prática:

  • Não reinvente um transient por cartão só para o nome da categoria no Loop principal do arquivo. O custo de get_the_category() no Loop é baixo face ao resto do template.
  • Caches de fragmento HTML (cartões inteiros em transient ou em edge) devem incluir o nome da categoria dentro do HTML cacheado, e invalidar quando o post é guardado (save_post) ou quando o termo é editado (edited_term).
  • Se guarda só o term_id no seu índice custom (Elasticsearch, tabela própria), resolva o name na renderização com get_term() - assim renomear a categoria atualiza o arquivo sem rebuild do índice de IDs.

Exemplo de invalidação ao guardar o post, se mantém um fragmento por ID:

<?php
add_action(
	'save_post_post',
	function ( $post_id ) {
		delete_transient( 'wppoland_card_html_' . (int) $post_id );
	}
);
?>

Evite cachear a string já passada por esc_html() durante horas se editores alteram nomes com frequência em sites de notícias - ou aceite um TTL curto (5-15 minutos) e documente o compromisso.

Antes de fechar o PR do partial template-parts/card-category.php:

  1. Confirmou que o design quer texto, não navegação para o arquivo.
  2. Usa get_the_category() ou get_the_terms(), nunca strip_tags em cima de the_category().
  3. Todo o name visível passa por esc_html(); slugs em classes por esc_attr() ou sanitize_html_class().
  4. Decidiu explicitamente entre «primeira do array» e «categoria primária SEO».
  5. No FSE, o cartão não depende de pointer-events: none como solução permanente.
  6. Fragmentos HTML cacheados invalidam em save_post / edição de termo.
<?php
/**
 * template-parts/card-category-label.php
 *
 * @package WPPoland_Theme
 */

defined( 'ABSPATH' ) || exit;

$post_id  = get_the_ID();
$primary  = function_exists( 'wppoland_get_primary_category' )
	? wppoland_get_primary_category( $post_id )
	: null;

if ( ! $primary ) {
	$categories = get_the_category( $post_id );
	$primary    = ! empty( $categories ) ? $categories[0] : null;
}

if ( ! $primary ) {
	return;
}
?>
<span class="card__category card__category--<?php echo esc_attr( $primary->slug ); ?>">
	<?php echo esc_html( $primary->name ); ?>
</span>

Este partial separa dados de apresentação: o CSS pinta a badge; o PHP não emite âncoras. Se mais tarde o produto pedir link, envolva o esc_html( $primary->name ) num <a href="<?php echo esc_url( get_category_link( $primary->term_id ) ); ?>"> - sem reintroduzir the_category().

Há ecrãs em que o HTML com links é o produto:

  • rodapé do single clássico «Publicado em Notícias, Eventos»;
  • widgets de «meta do post» onde cada categoria deve ser clicável;
  • temas minimalistas sem cartões, onde o arquivo por categoria é a navegação secundária.

Nesses casos chame the_category( ', ' ) (ou o bloco Post Terms) e não reinvente o markup. O erro é misturar os dois modos no mesmo componente sem regra: badge do cartão com texto, meta do single com links - documente a regra no tema para o próximo programador não «unificar» tudo com strip_tags.

#Funções WordPress para obter categorias

FunçãoPapelSaída
the_category()Template tag de impressãoHTML com <a>
get_the_category()Dados da taxonomia categoryWP_Term[]
get_the_category_list()Lista HTML configurávelstring HTML
get_the_terms()Qualquer taxonomiaWP_Term[]|false|WP_Error
get_category_link()URL do arquivostring URL

Documentação oficial (Developer Reference):

#Erros comuns ao mostrar categorias no tema

Em code review, procure estes sinais de regressão:

  • echo $category->name sem escape;
  • the_category() dentro de atributos HTML (title="");
  • dependência da ordem do array quando o negócio fala em «categoria principal»;
  • testes E2E que assertam href na badge do cartão (o teste fica a vermelho quando passa a texto puro - atualize o seletor para .card__category sem a).

Em sites multilingues (WPML, Polylang), o name já vem na língua do termo traduzido se o post estiver na língua certa. Não concatene nomes de outro idioma a partir de IDs sem passar pela API do plugin de tradução.

Se precisar de quem implemente estes partials e a regra de primary no seu tema, fale com a equipa de desenvolvimento WordPress.

Última verificação editorial deste guia: 21 de setembro de 2026. As funções citadas mantêm o mesmo contrato público no Developer Handbook; valide sempre contra a versão do WordPress do projeto antes de copiar snippets para produção.

Próximo passo

Transforme o artigo numa implementação real

Este bloco reforça a ligação interna e conduz o leitor para o passo seguinte mais útil dentro da arquitetura do site.

Quer implementar isto no seu site?

Se quer transformar o artigo em melhorias concretas, redesign ou num plano de implementação, posso fechar o escopo e executar.

Cluster relacionado

Explorar outros serviços WordPress e base de conhecimento

Reforce o seu negócio com suporte técnico profissional em áreas-chave do ecossistema WordPress.

FAQ do artigo

Perguntas frequentes

Respostas práticas para aplicar o tema na execução real.

SEO-readyGEO-readyAEO-ready3 Q&A
Porque não usar the_category() se quero apenas texto?#
Porque the_category() gera links HTML prontos. Se precisa apenas do nome da categoria para uma badge ou layout personalizado, get_the_category() dá-lhe acesso direto ao objeto.
Como mostrar apenas a primeira categoria do post?#
Use get_the_category(), confirme que o array não está vazio e depois imprima o name da primeira categoria com esc_html().
Como listar várias categorias sem links?#
Percorra o array de categorias com foreach, guarde os nomes num array e una tudo com implode() para controlar o separador.

Precisa de FAQ adaptado ao setor e mercado? Criamos uma versão alinhada com os seus objetivos de negócio.

Fale connosco

Artigos Relacionados