Hvordan hente kategorinavn uten lenke i WordPress (get_the_category)

Hvordan hente kategorinavn uten lenke i WordPress (get_the_category)

Sist verifisert: 14. oktober 2026
15 min lesetid
Veiledning
500+ WP-prosjekter
Full-stack-utvikler

Standard WordPress-funksjonen the_category() er praktisk i klassiske temaer, men den har en hard grense: den skriver alltid ut HTML-ankere (<a href="...">...</a>) til kategoriarkivet. Det funker på en enkeltinnleggsside der leseren skal kunne klikke videre. Det funker dårlig på et porteføljekort, en slider, en meta-rad i et headless-oppsett eller en badge der kategorien bare skal være etikett.

Løsningen er get_the_category(), som returnerer en array av term-objekter i stedet for ferdig markup. Offisiell referanse: get_the_category(), the_category() og get_the_terms().

På WordUp Oslo og WordCamp Norge dukker dette opp ofte når noen bygger et kortbasert arkiv for norske medlemsbedrifter eller et konferanseprogram: de vil ha «Nyheter», «Case» eller «Arrangører» som tekst, ikke som klikkbare arkivlenker inne i kortet. Samme krav dukker opp i medlemsportaler der kortet allerede er hele lenkemålet - en ekstra anker inne i badge-en skaper nestede <a>-tagger, som er ugyldig HTML og rotete for tastaturnavigasjon.

Målet med denne veiledningen er praktisk: velg riktig API, escape i riktig kontekst, håndter flere termer, egne taksonomier, SEO-primary og FSE, og unngå snarveier som ser smarte ut i et gist men feiler i produksjon.

#Hvorfor the_category() alltid skriver ut anker

the_category() er en template tag i WordPress-forstand: den er laget for å vise noe, ikke for å returnere data du kan forme videre. Under panseret bygger den på get_the_category_list(), som setter sammen en liste med lenker, separator og valgfri overordnet kontekst.

Parametere styrer separator, foreldre og post-ID. De styrer ikke en «kun tekst»-modus. Hvis du trenger navnet uten markup, er feil verktøy valgt. Bytt API, ikke lim på strip_tags() etterpå.

Et konkret scenario: du har en forsiderad med åtte arrangementskort etter WordCamp Norge. Hvert kort linker allerede til single. Hvis badge-en også er en kategoriarkiv-lenke, får mobilbrukere to treffområder oppå hverandre, og analytics blander «kortklikk» med «kategoriklikk». Ren tekst i badge-en gjør målingen ærlig.

<?php
// Dette skriver alltid ut <a>-tagger.
the_category( ', ' );
?>

#Hva returnerer get_the_category() i WordPress

<?php
$categories = get_the_category();
// Array av WP_Term-objekter for taksonomien «category».
?>

get_the_category( $post_id = false ) uten argument bruker gjeldende post fra den globale $post (inne i loopen). Returverdien er en array av term-objekter. Feltene du bruker mest:

  • name - synlig etikett («Nyheter»)
  • slug - URL- og CSS-vennlig streng (nyheter)
  • term_id - stabil ID for spørringer og meta
  • description - kategoriens beskrivelsesfelt
  • count - antall innlegg i kategorien
  • parent - overordnet term-ID (0 hvis toppnivå)

Tom array er lovlig: et innlegg uten kategorier (eller et custom post type uten category) gir array(). Sjekk alltid ! empty( $categories ) før du leser indeks 0. Ellers får du notices i WP_DEBUG og blanke badges i produksjon når redaksjonen glemmer å tilordne kategori på et hastig publisert innlegg.

Rekkefølgen i arrayen er ikke en kontrakt du bør bygge forretningslogikk på. Den følger hvordan termene er tilordnet og sortert internt, ikke nødvendigvis den redaksjonelle «hovedkategorien». Trenger du den, les plugin-meta for primary (se egen seksjon under).

Utenfor hovedloopen (widget, REST-callback, cron) send eksplisitt post-ID:

<?php
$categories = get_the_category( $post_id );
?>

#Hva get_the_category gjør inne i WordPress-kjernen

I kildekoden til wordpress-develop er get_the_category() et tynt skall. Den kaller get_the_terms( $post_id, 'category' ), gjør et false- eller WP_Error-resultat om til en tom array, nummererer den på nytt med array_values(), sender hver term gjennom den private funksjonen _make_cat_compat() og returnerer resultatet gjennom filteret get_the_categories. Disse få linjene gir tre praktiske konsekvenser.

De gamle egenskapene finnes bare i utdata fra denne funksjonen. _make_cat_compat() kopierer de moderne feltene til gamle navn: cat_ID, cat_name, category_nicename, category_count, category_description og category_parent. Objekter fra get_the_terms() får dem ikke. En mal som leser $cat->cat_name fungerer i dag og viser ingenting den dagen noen bytter kallet til get_the_terms() for å støtte en egen taksonomi. Les name, slug og term_id, som begge funksjonene deler.

Rekkefølgen er alfabetisk, ikke redaksjonell. get_the_terms() sjekker først innleggets relasjonscache og kaller ellers wp_get_object_terms(), som kjører en WP_Term_Query med standard orderby satt til name. $categories[0] er altså den alfabetisk første kategorien, så lenge ingen filter sorterer arrayen om.

Utvidelser kan skrive om arrayen. Enhver callback på get_the_categories (med argumentet $post_id siden WordPress 4.4) eller på get_the_terms kan legge til, fjerne eller sortere termer før malen ser dem. Viser en badge en kategori ingen har tilordnet, sjekk callbackene på disse to hookene før du feilsøker malen.

#Hvordan escape kategorinavn med esc_html og esc_attr

Kategorinavn kommer fra databasen og kan i teorien inneholde tegn som ødelegger markup. Bruk kontekst riktig:

  • Tekstinnhold i HTML: esc_html( $category->name )
  • Attributter (class, data-*, title): esc_attr( $category->slug )
  • URL-er (hvis du velger å lenke selv): esc_url( get_category_link( $category->term_id ) )
<?php
$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; ?>

Da får «Nyheter» klassen .badge-nyheter uten at du mister kontroll over markup. the_category() gir deg ikke den friheten.

#Hvorfor kategorinavn viser & utenfor HTML

Før en term lagres, sender default-filters.php navnet gjennom sanitize_text_field(), wp_filter_kses() og, med prioritet 30, _wp_specialchars() på hooken pre_term_name. HTML-tagger fjernes allerede ved lagring, og en kategori som heter «Tips & triks» ligger i databasen som Tips &amp; triks.

I HTML gjør det ingenting. esc_html() kaller _wp_specialchars() med dobbel koding slått av, så en eksisterende &amp; forblir &amp;, og nettleseren viser en vanlig «&». Den bokstavelige &amp; dukker opp utenfor HTML: i JSON-LD bygget med wp_json_encode(), i et REST-felt som JavaScript skriver med textContent, i emnet på en ren tekst-e-post eller i en CSV-eksport. Et direkte kall til PHPs htmlspecialchars(), som dobbelkoder som standard, gir den synlige &amp;amp;. I disse kontekstene dekoder du først og bruker deretter escapingen til målformatet:

<?php
$categories = get_the_category();

if ( ! empty( $categories ) ) {
	// Gjør lagret "&amp;" om til "&" for en kontekst som ikke er HTML.
	$navn = wp_specialchars_decode( $categories[0]->name, ENT_QUOTES );

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

#Hvordan vise flere kategorier uten lenke med implode

Mange innlegg har mer enn én kategori. Samle navnene først, slå dem sammen etterpå. Da styrer du separator, mellomrom og rekkefølge uten å røre anker-HTML.

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

if ( ! empty( $categories ) ) {
	foreach ( $categories as $category ) {
		$output[] = esc_html( $category->name );
	}
	echo implode( ', ', $output );
}
?>

Tips fra praksis på norske nettredaksjoner: bruk en midterprikk (·) eller skråstrek når komma konkurrerer med tusenskiller i talltunge case-studier. implode() bryr seg ikke - du velger strengen.

Hvis du trenger både navn og slug i samme pass (for eksempel JSON-LD articleSection pluss CSS), bygg to arrays eller ett assosiativt kart i loopen, ikke kall get_the_category() to ganger i samme request uten grunn.

#Hvordan sortere og utelate kategorier på et innlegg

implode-løkken over dekker grunntilfellet. I ekte maler trenger du som regel to ting til: kontroll over rekkefølgen og en måte å hoppe over kategorier du aldri vil skrive ut (det klassiske eksemplet er “Ukategorisert” som lekker inn i et kortdesign).

For rekkefølgen korter wp_list_pluck() løkken ned til én linje, og en vanlig sort() gir alfabetisk utskrift. WordPress returnerer kategorier sortert etter navn som standard, men tillegg kan filtrere det, så eksplisitt sortering koster ingenting og fjerner en overraskelse:

<?php
$categories = get_the_category();

if ( ! empty( $categories ) ) {
    // Hent bare navnene ut av term-objektene
    $names = wp_list_pluck( $categories, 'name' );

    // Eksplisitt alfabetisk rekkefølge, uavhengig av filtre
    sort( $names );

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

For å utelate bestemte kategorier sammenligner du med slug, ikke navn. Slugs er stabile, mens navn blir endret av kunder uten forvarsel:

<?php
$categories = get_the_category();
$skip       = array( 'uncategorized', 'featured' );
$names      = array();

foreach ( $categories as $category ) {
    if ( in_array( $category->slug, $skip, true ) ) {
        continue;
    }
    $names[] = $category->name;
}

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

Escaping skjer én gang, på den ferdig sammenslåtte strengen. Å escape hvert navn og så slå dem sammen fungerer også, men én esc_html() der utskriften skjer gjør det tydelig i kodegjennomgang at ingenting forlater malen uescapet.

#Hvorfor strip_tags på kategorilisten er feil

Dette dukker fortsatt opp i gamle child themes og i «raske» snippets fra forum:

<?php
// Unngå dette.
echo strip_tags( get_the_category_list( ', ' ) );
?>

Hvorfor det er dårlig:

  1. Du ber WordPress bygge full HTML bare for å kaste den.
  2. strip_tags() erstatter ikke esc_html(). Den fjerner tagger, men escaper ikke teksten for konteksten den havner i.
  3. Du mister tilgang til slug, term_id og parent.
  4. Filtre på the_category / get_the_category_list kan fortsatt kjøre og endre output før strip.

Riktig retning: hent data med get_the_category() eller get_the_terms(), escape ved utskrift. Bygg markup selv hvis du trenger den.

#Hente termnavn fra egen taksonomi med get_the_terms

get_the_category() er spesialisert for innebygd category. Har du produktlinje, fagfelt eller wordcamp-spor, bruk get_the_terms():

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

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

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

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

Merk forskjellen: get_the_terms() kan returnere false eller WP_Error. get_the_category() returnerer vanligvis en (muligens tom) array. Kode som kopieres mellom kategori og custom taxonomy må håndtere begge returformer.

#Hente kategorinavn som array med wp_get_post_terms

wp_get_post_terms() sender det tredje argumentet videre til wp_get_object_terms() og godtar dermed WP_Term_Query-valgene som get_the_terms() ikke har. Med 'fields' => 'names' får du en array av strenger tilbake, og løkken forsvinner:

<?php
// Bare navn, mest brukte kategori først.
$navn = wp_get_post_terms(
	get_the_ID(),
	'category',
	array(
		'fields'  => 'names',
		'orderby' => 'count',
		'order'   => 'DESC',
	)
);

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

Prisen er cachen. get_the_terms() leser først innleggets relasjonscache, og hoved-WP_Query fyller den for alle innlegg på siden fordi update_post_term_cache er true som standard. wp_get_post_terms() hopper over denne cachen og kaller alltid wp_get_object_terms(). På et arkiv med tjue kort blir det tjue term-spørringer etter data WordPress allerede har lastet. Inne i loopen gir wp_list_pluck( get_the_category(), 'name' ) samme navnearray fra cachen. Bruk wp_get_post_terms() der du trenger argumentene, for eksempel sortering etter count i et sidefelt eller en REST-callback som behandler ett innlegg om gangen.

Til WordCamp Norge-programmet er det vanlig å ha både category (innholdstype) og en egen taksonomi for spor (utvikling, innhold, business). Da trenger du to kall, ikke én «superliste».

#Hente primærkategori fra Yoast og Rank Math

Yoast, Rank Math og flere lagrer en «primary category». get_the_category()[0] er ikke garantert den samme. Rekkefølgen fra get_the_category() følger term-rekkefølge / tilordning, ikke nødvendigvis SEO-pluginens valg.

Typisk mønster (Yoast-meta som eksempel - sjekk alltid nøkkelen for din plugin-versjon):

<?php
$post_id   = get_the_ID();
$primary   = (int) get_post_meta( $post_id, '_yoast_wpseo_primary_category', true );
$categories = get_the_category( $post_id );
$chosen     = null;

if ( $primary && ! empty( $categories ) ) {
	foreach ( $categories as $category ) {
		if ( (int) $category->term_id === $primary ) {
			$chosen = $category;
			break;
		}
	}
}

if ( ! $chosen && ! empty( $categories ) ) {
	$chosen = $categories[0];
}

if ( $chosen ) {
	echo esc_html( $chosen->name );
}
?>

Fallback til første element er viktig: eldre innlegg mangler ofte primary-meta. På et medlemsmagasin etter WordUp Bergen så vi badges som hoppet mellom «Medlemsnytt» og «Arrangement» fra side til side fordi noen kort leste [0] og andre leste Yoast-primary uten fallback.

#Kategorinavn uten lenke i blokktema og FSE

I Full Site Editing får du Query Loop og Post Terms-blokker. De er fine når du vil ha standard term-lenker i et arkiv. Post Terms kan ikke slå av lenkene: blokkens block.json definerer bare attributtene term, separator, prefix og suffix, og PHP-renderen bygger utdata med get_the_term_list(). De er svake når:

  • badge-markup må matche et designsystem med faste BEM-klasser
  • du trenger bare én term (primær) uten lenke
  • headless / App Router-frontends leser REST og forventer rene strenger
  • du mapper term-slug til Tailwind- eller token-klasser i PHP-delen av et hybridtema

Da beholder du en liten template-part eller et blokkvariasjonsmønster med PHP, eller du eksponerer feltene via REST (register_rest_field) basert på samme get_the_category() / get_the_terms()-logikk. Poenget er det samme: les term-objektet, ikke strip ferdig HTML.

Et hybridtema vi så etter WordUp Trondheim brukte FSE til layout og en render_callback på en egen «Post badge»-blokk. Callback-en kalte get_the_category( $block->context['postId'] ), escapet name/slug, og returnerte span-markup. Redaktørene flyttet blokken i Site Editor; utviklerne beholdt kontroll på klassenavn. Det er et bedre kompromiss enn å låse hele arkivet til klassisk PHP, eller å tvinge Post Terms til å late som den er et designsystem.

#Kategorinavn i kategoriarkivet med single_cat_title

I category.php hører kategorien ikke til et innlegg, den er det spurte objektet for hele siden. Der returnerer get_the_category() kategoriene til det første innlegget i loopen, ikke arkivets kategori. Riktig funksjon er single_cat_title(); med false som andre argument returnerer den verdien i stedet for å skrive den ut:

<?php
if ( is_category() ) {
	$navn = single_cat_title( '', false );
	echo esc_html( $navn );
}
?>

I general-template.php delegerer single_cat_title() til single_term_title(). Den leser get_queried_object(), bruker filteret single_cat_title på kategoriarkiver og returnerer null utenfor kategori-, stikkord- og taksonomiarkiver. default-filters.php kobler wptexturize og strip_tags til dette filteret; ingen av dem erstatter escaping, så esc_html() blir stående ved utskrift. Trenger du også slug eller term_id til en CSS-klasse, les objektet direkte med get_queried_object() og sjekk at det er en instans av WP_Term.

#Når du bør bruke the_category() med lenke

Noen ganger er ankeret riktig: brødsmuler, term-sky, enkeltinnlegg der meta-raden skal lede til arkivet. Da er the_category() eller en bevisst bygget <a href="<?php echo esc_url( get_category_link( $id ) ); ?>"> greit. Poenget er ikke «aldri lenke». Poenget er å ikke la template-taggen bestemme markup når UI-et ditt allerede har bestemt noe annet.

#Hvordan cache kategorinavn i innleggskort og meta

På forsider med 24 kort er 24 kall til get_the_category() billige sammenlignet med remote HTTP, men de summerer seg under objektcache-miss og tung term-meta. Noen mønstre som holder i produksjon:

  1. Les inne i loopen, skriv én gang. Ikke kall funksjonen i header, i kortet og i schema for samme post uten å cache lokalt i en variabel.
  2. Transient per post bare når du aggregérer tungt. For eksempel en «topp kategorier denne uken»-widget. Ikke transient for enkeltnavn på single - det er overkill.
  3. Object cache / Redis: WordPress cacher allerede mange term-oppslag. Unngå å invalidere hele term-cachen unødig etter hver lagring i admin.
  4. Fragment cache for HTML-kort: hvis kortet er dyrt (bilde + ACF + term), cache hele kort-HTML med post-ID som nøkkel og tøm ved save_post.
<?php
function wppoland_post_category_label( $post_id = 0 ) {
	$post_id = $post_id ? (int) $post_id : get_the_ID();
	$cats    = get_the_category( $post_id );

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

	return esc_html( $cats[0]->name );
}
?>

En liten helper hindrer at fem template-filer hver finner opp sin egen variant med eller uten escaping.

#Kategorinavn uten lenke i single.php og innleggskort

Minimal utgave til single eller content.php:

<?php
$categories = get_the_category();

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

Liste uten lenker:

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

if ( ! empty( $categories ) ) {
	foreach ( $categories as $category ) {
		$output[] = esc_html( $category->name );
	}
	echo implode( ', ', $output );
}
?>

Trenger du samme kontroll gjennom hele temaet, er det typisk slik vi strukturerer merkelapper i skreddersydd WordPress-utvikling.

#Hvorfor get_the_category returnerer tomme eller feil kategorier

Glemt wp_reset_postdata() i egne løkker. get_the_category() leser den globale $post. I en egen WP_Query-løkke som kaller the_post(), peker den globale variabelen fortsatt på siste element i løkken hvis du ikke tilbakestiller den, så alle kategorikall etter løkken rapporterer kategoriene til feil innlegg:

<?php
$related = new WP_Query( array( 'posts_per_page' => 3 ) );

while ( $related->have_posts() ) {
    $related->the_post();
    $cats = get_the_category();
    // ... utskrift ...
}

// Uten denne linjen gjelder get_the_category() nedenfor det siste relaterte innlegget
wp_reset_postdata();
?>

Å anta at et innlegg alltid har en kategori. Vanlige innlegg får “Ukategorisert” som standard, men egne innleggstyper med kategoristøtte kan faktisk mangle kategori, og kode som blindt leser $categories[0] gir da en notice om udefinert indeks. Sjekken ! empty( $categories ) i eksemplene i denne artikkelen står der med vilje: behold den, selv om “alle innlegg har en kategori” virker garantert i dag.

#Sjekkliste for kategorinavn uten lenke i temaet

  • Bytt the_category() der du faktisk ikke vil ha anker.
  • Bruk get_the_category() for category, get_the_terms() for resten.
  • Escape med esc_html / esc_attr etter kontekst.
  • Bygg lister med foreach + implode, ikke strip_tags( get_the_category_list() ).
  • Avklar om «første kategori» eller SEO-primary er kravet.
  • Test et innlegg uten kategori (tom array) og et CPT uten category.
  • I FSE: beholde PHP bare der blokken ikke kan levere etiketten din.

#Oppsummering

the_category() printer lenker. get_the_category() gir deg term-objekter. Derfra bygger du tekst, badges, schema og REST-felt uten å strippe HTML i etterkant. Samme idé gjelder egne taksonomier via get_the_terms(). Primærkategori er plugin-meta, ikke magisk indeks null.

Ta med dette videre i code review:

  1. Ingen strip_tags rundt kategorilister.
  2. Escape ved utskrift, ikke «senere».
  3. Tom array og WP_Error er testet.
  4. Primary vs [0] er avklart med redaksjonen.
  5. FSE-blokker får PHP der designet krever det.

På WordCamp Norge- og WordUp-oppsett er det forskjellen mellom et kort som ser ut som designet og et kort som lekker arkivlenker inn i UI-et. Hold API-valget eksplisitt, så slipper neste utvikler å gjette hvorfor badge-en plutselig ble klikkbar igjen etter en theme-oppdatering.

Neste steg

Gjør artikkelen om til faktisk implementering

Denne blokken styrker intern lenking og sender leseren videre til de mest relevante tjenestene og innholdet.

Vil du få dette implementert på nettstedet ditt?

Hvis du vil gjøre kunnskapen i artikkelen om til konkrete forbedringer, redesign eller en tydelig leveranseplan, kan jeg ta det videre.

Utforsk andre WordPress-tjenester og kunnskapsbase

Styrk virksomheten din med profesjonell teknisk støtte innen kjerneområdene i WordPress-økosystemet.

Ofte stilte spørsmål

Praktiske svar for å bruke temaet i faktisk arbeid.

Hvorfor ikke bruke the_category() når jeg bare vil ha tekst?#
Fordi the_category() genererer ferdige HTML-lenker. Trenger du bare kategorinavnet til en merkelapp eller et eget oppsett, gir get_the_category() deg direkte tilgang til objektet.
Hvordan viser jeg bare den første kategorien til innlegget?#
Bruk get_the_category(), sjekk at arrayet ikke er tomt, og skriv deretter ut name på den første kategorien med esc_html().
Hvordan lister jeg flere kategorier uten lenker?#
Gå gjennom kategori-arrayet med foreach, samle navnene i et array og slå dem sammen med implode() for å styre skilletegnet.
Hvordan henter jeg navnet fra en egen taksonomi?#
Bruk get_the_terms( $post_id, 'din_taksonomi' ). Den returnerer et array med WP_Term-objekter, false eller WP_Error. Håndter feil og tomt array hver for seg, og les deretter ->name som for kategorier.
Hvilken funksjon returnerer kategorinavnet på en arkivside?#
På et kategoriarkiv bruker du single_cat_title() med false som andre argument, fordi den gjeldende kategorien hører til det spurte objektet, ikke til ett enkelt innlegg.
Hvordan viser jeg kategorinavnet i blokkredigereren?#
Registrer en kortkode som returnerer navnet med get_the_category() og esc_html(), og sett den inn med Shortcode-blokken i malen eller mønsteret.
Er strip_tags(get_the_category_list()) en god snarvei?#
Nei. Du genererer først HTML med lenker og skjærer det bort etterpå. Du mister kontrollen over escaping, attributter og rekkefølge. Les term-objektene og bygg strengen selv med esc_html().
Hva med primærkategorien i Yoast SEO eller Rank Math?#
Tilleggene lagrer den valgte term-ID-en i innleggets metadata. Les metaverdien, hent termen med get_term() og skriv deretter ut navnet. Indeks [0] fra get_the_category() er ikke nødvendigvis kategorien som er merket som primær.

Trenger du FAQ tilpasset bransje og marked? Jeg lager en versjon som støtter dine forretningsmål.

Ta kontakt

Relaterte artikler