Skip to content

Allt om WordPress, webbutveckling — och mer därtill

🛠 Exklusiva taxonomier i WordPress: hur du ersätter kryssrutor med radioknappar

🛠 Exklusiva taxonomier i WordPress: hur du ersätter kryssrutor med radioknappar

Som standard låter WordPress dig tilldela hur många termer som helst från en enskild taxonomi till ett inlägg. Kryssrutor i sidofältet, och du är klar. Men vad händer om kunden behöver att redaktören väljer exakt ett alternativ? Till exempel "Projekttyp": case study, landningssida eller webbutik. Tre alternativ, och att ha två av dem samtidigt är meningslöst.

Det finns ingen inbyggd växel för "gör taxonomi exklusiv" i WordPress. En ticket i Trac har legat sedan 2010 utan framsteg. Men uppgiften kan lösas med kod, utan tillägg eller extra beroenden.

När du har läst klart den här artikeln kommer du att förvandla den vanliga metaboxen med kryssrutor till en panel med radioknappar: exakt en term per inlägg, färre redaktörsmisstag.

💡 Snabb översikt:

  • Registrera en taxonomi med parametern meta_box_cb så att den vanliga metaboxen inte visas.
  • Skapa ditt eget block med radioknappar på hooken add_meta_boxes.
  • Använd save_post för att skriva den valda termen till databasen.
  • Den fullständiga koden kan kopieras in i barntemats functions.php och fungerar direkt.

Vad taxonomier är och varför exklusivitet spelar roll

En taxonomi i WordPress är en mekanism för att gruppera inlägg. Standardfunktionerna "Kategorier" och "Etiketter" är också taxonomier. En anpassad taxonomi skapas för en specifik uppgift: "Projekttyp" för en portfölj, "Region" för en kontorskatalog, "Tjänstetyp" för en prislista.

Inbyggda kategorier fungerar som en exklusiv taxonomi: ett inlägg tillhör exakt en kategori, om du inte använder tilläggsplugins. Hierarkin "förälder → barn" antyder urvalslogiken för redaktören.

Alla anpassade taxonomier som registreras via register_taxonomy() är dock icke-exklusiva som standard. Gränssnittet består av kryssrutor eller ett fält med autocomplete. För etiketter och produktattribut är detta korrekt. Men när varje inlägg måste ha exakt en term blir kryssrutor en felkälla.

Lösningen: dölj den vanliga metaboxen och rendera din egen, med radioknappar och strikt kontroll. Detta är ingen workaround utan ett dokumenterat WordPress API, bara utspritt över flera steg.

Steg 1: registrera en anpassad taxonomi

Grunden är funktionen register_taxonomy(). Koden läggs till i barntemats functions.php eller via tillägget Code Snippets. Låt oss skapa en taxonomi project_type för vanliga inlägg:

1function sd_register_project_type_taxonomy() {
2 register_taxonomy(
3 'project_type',
4 'post',
5 array(
6 'label' => __( 'Project Type', 'textdomain' ),
7 'public' => true,
8 'show_in_rest' => true,
9 'hierarchical' => true,
10 'show_in_quick_edit' => false,
11 'meta_box_cb' => false,
12 )
13 );
14}
15add_action( 'init', 'sd_register_project_type_taxonomy' );

Viktiga parametrar:

  • hierarchical => true möjliggör en trädstruktur, som kategorier. Termer organiseras hierarkiskt: "Design → Landningssida", "Utveckling → Webbutik".
  • show_in_rest => true gör taxonomin tillgänglig i REST API och blockredigeraren. Utan detta kommer Gutenberg inte att se metaboxen.
  • meta_box_cb => false och show_in_quick_edit => false tar helt bort det vanliga gränssnittet för termval.

Efter att ha sparat koden dök taxonomin project_type upp i menyn "Inlägg". Termer läggs till via "Inlägg → Projekttyp" med ett standardgränssnitt, som för kategorier.

Steg 2: dölj den vanliga metaboxen

Detta steg har faktiskt redan gjorts med parametrarna meta_box_cb och show_in_quick_edit i steg 1. För att sammanfatta:

  • meta_box_cb => false tar bort metaboxen från inläggets redigeringssida.
  • show_in_quick_edit => false döljer taxonomin från panelerna för snabbredigering och massredigering.

Utan dem lägger WordPress till ett standardgränssnitt: för hierarkiska taxonomier, kategorikryssrutor; för icke-hierarkiska, ett etikettfält med autocomplete.

meta_box_cb och show_in_quick_edit-parametrar i register_taxonomy

Termer fylls i via en separat hanteringssida:

Hanteringssida för anpassade taxonomitermer i WordPress admin

Steg 3: skapa en anpassad metabox med radioknappar

Registrera din egen metabox via hooken add_meta_boxes. Lägg till i functions.php:

1add_action( 'add_meta_boxes', 'sd_add_project_type_meta_box' );
2
3function sd_add_project_type_meta_box() {
4 add_meta_box(
5 'project_type_box',
6 __( 'Project Type', 'textdomain' ),
7 'sd_render_project_type_meta_box',
8 'post',
9 'side',
10 'default'
11 );
12}

Parametrar för add_meta_box():

  • project_type_box: internt ID (godtyckligt men unikt).
  • 'Project Type': titel i adminpanelen.
  • sd_render_project_type_meta_box: renderingsfunktion.
  • 'post': inläggstyp; kan vara en array för flera CPT:er.
  • 'side': sidofält. Alternativ: 'normal', 'advanced'.

Funktionen som renderar radioknapparna:

1function sd_render_project_type_meta_box( $post ) {
2 $terms = get_terms( array(
3 'taxonomy' => 'project_type',
4 'hide_empty' => false,
5 ) );
6
7 if ( empty( $terms ) || is_wp_error( $terms ) ) {
8 echo '<p>First, add terms on the “Project Type” page.</p>';
9 return;
10 }
11
12 $current_terms = get_the_terms( $post->ID, 'project_type' );
13 $current_id = ( ! empty( $current_terms ) && ! is_wp_error( $current_terms ) )
14 ? $current_terms[0]->term_id
15 : 0;
16
17 foreach ( $terms as $term ) : ?>
18 <label style="display:block;margin-bottom:4px;">
19 <input type="radio"
20 name="project_type_term"
21 value="<?php echo esc_attr( $term->term_id ); ?>"
22 <?php checked( $current_id, $term->term_id ); ?>>
23 <?php echo esc_html( $term->name ); ?>
24 </label>
25 <?php endforeach;
26}

Vad som är viktigt här:

  • get_terms() med hide_empty => false returnerar alla termer, inklusive oanvända.
  • get_the_terms() returnerar en array; vi tar det första elementet [0] eftersom logiken garanterar högst en term.
  • checked() är en inbyggd WordPress-funktion som matar ut checked="checked" när det finns en träff.
  • esc_attr() och esc_html() är obligatorisk escaping.

Resultatet är ett rent block med radioknappar:

Anpassad metaruta med radioknappar för att välja en enskild taxonomiterm

Inga kryssrutor, inget sätt att välja två alternativ.

Steg 4: spara termen när inlägget sparas

Utan detta steg är metaboxen rent dekorativ. Vi använder hooken save_post:

1add_action( 'save_post', 'sd_save_project_type_term' );
2
3function sd_save_project_type_term( $post_id ) {
4 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
5 return;
6 }
7
8 if ( ! current_user_can( 'edit_post', $post_id ) ) {
9 return;
10 }
11
12 if ( isset( $_POST['project_type_term'] ) ) {
13 $term_id = absint( $_POST['project_type_term'] );
14 wp_set_object_terms( $post_id, $term_id, 'project_type' );
15 }
16}

Detaljer:

  • DOING_AUTOSAVE: vi hoppar över autosparningar. Utan denna kontroll skrivs termen över i bakgrunden var 60:e sekund.
  • current_user_can( 'edit_post', $post_id ): grundläggande behörighetskontroll.
  • absint() konverterar värdet till ett positivt heltal, säkrare än (int) sanitize_text_field().
  • wp_set_object_terms() med ett enskilt ID (inte en array) skriver exakt en term och tar bort tidigare kopplingar.

Klart. Spara inlägget, så låses radioknappsvalet. När du öppnar det igen är den valda termen markerad.

Fullständig kod för kopiering

Alla fyra steg i ett snippet. Lägg till i ditt barntemas functions.php eller via Code Snippets:

1/**
2 * Exclusive taxonomy "Project Type" — one term per post.
3 * Add to child theme's functions.php.
4 */
5function sd_register_project_type_taxonomy() {
6 register_taxonomy(
7 'project_type',
8 'post',
9 array(
10 'label' => __( 'Project Type', 'textdomain' ),
11 'public' => true,
12 'show_in_rest' => true,
13 'hierarchical' => true,
14 'show_in_quick_edit' => false,
15 'meta_box_cb' => false,
16 )
17 );
18}
19add_action( 'init', 'sd_register_project_type_taxonomy' );
20
21add_action( 'add_meta_boxes', 'sd_add_project_type_meta_box' );
22
23function sd_add_project_type_meta_box() {
24 add_meta_box(
25 'project_type_box',
26 __( 'Project Type', 'textdomain' ),
27 'sd_render_project_type_meta_box',
28 'post',
29 'side',
30 'default'
31 );
32}
33
34function sd_render_project_type_meta_box( $post ) {
35 $terms = get_terms( array(
36 'taxonomy' => 'project_type',
37 'hide_empty' => false,
38 ) );
39
40 if ( empty( $terms ) || is_wp_error( $terms ) ) {
41 echo '<p>First, add terms on the “Project Type” page.</p>';
42 return;
43 }
44
45 $current_terms = get_the_terms( $post->ID, 'project_type' );
46 $current_id = ( ! empty( $current_terms ) && ! is_wp_error( $current_terms ) )
47 ? $current_terms[0]->term_id
48 : 0;
49
50 foreach ( $terms as $term ) : ?>
51 <label style="display:block;margin-bottom:4px;">
52 <input type="radio"
53 name="project_type_term"
54 value="<?php echo esc_attr( $term->term_id ); ?>"
55 <?php checked( $current_id, $term->term_id ); ?>>
56 <?php echo esc_html( $term->name ); ?>
57 </label>
58 <?php endforeach;
59}
60
61add_action( 'save_post', 'sd_save_project_type_term' );
62
63function sd_save_project_type_term( $post_id ) {
64 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
65 return;
66 }
67
68 if ( ! current_user_can( 'edit_post', $post_id ) ) {
69 return;
70 }
71
72 if ( isset( $_POST['project_type_term'] ) ) {
73 $term_id = absint( $_POST['project_type_term'] );
74 wp_set_object_terms( $post_id, $term_id, 'project_type' );
75 }
76}

⚠️ Gör en fullständig säkerhetskopia av webbplatsen innan du klistrar in. Koden har testats på den aktuella versionen av WordPress med den klassiska redigeraren. I Gutenberg visas den anpassade metaboxen i sidofältet utan ändringar.

I praktiken distribuerade vi detta snippet på tre projekt, och det fungerade överallt utan modifieringar. Om du har en hierarkisk inläggstyp eller flera redaktörsroller, ersätt 'post' med din slug och verifiera behörigheter i save_post.


WordPress Trac har haft ticket #14877 öppen sedan 2010 för inbyggt stöd för exklusiv taxonomi. När en parameter 'exclusive' => true dyker upp i core, kommer hela denna konstruktion att krympa till en enda rad. Tills ticketen får rörelse förblir radioknappsmetoden den primära lösningen.

Och nedan, en kort video om ämnet så att du kan se processen i aktion:

⁉️🤔 Vanliga frågor

Fungerar detta i Gutenberg?

Ja. Parametern show_in_rest => true vid registrering av taxonomin möjliggör kompatibilitet med blockredigeraren. Den anpassade metaboxen visas i dokumentets sidofält, och radioknappar visas och sparas korrekt.

Kan denna metod tillämpas på anpassade inläggstyper?

Ja. Ersätt 'post' i register_taxonomy() och add_meta_box() med din CPT-slug. Resten av koden (taxonominamn, etikett, parametrar) förblir densamma. Metoden fungerar med alla registrerade inläggstyper, inklusive de som skapats via ACF eller Custom Post Type UI.

Vad händer om redaktören inte väljer någon term?

Inlägget sparas utan tilldelad term; save_post anropar helt enkelt inte wp_set_object_terms(). Om obligatoriskt val är kritiskt, lägg till JavaScript-validering i admin eller en kontroll via hooken pre_post_update.

Varför inte använda tillägget Radio Buttons for Taxonomies?

Du kan. Tillägget löser uppgiften utan kod och har 100 000+ aktiva installationer. Nackdelen är ytterligare ett beroende. För en eller två webbplatser är tillägget motiverat. För byråer och multisites ger kod i temat full kontroll utan extra uppdateringar och konflikter.

Hur lägger jag till hierarkiskt urval (förälder → barn)?

Hierarkiska taxonomier (hierarchical => true) får en förälder-barn-struktur automatiskt. För att visa hierarkin i den anpassade metaboxen, ersätt get_terms() med wp_dropdown_categories() med parametern 'taxonomy' => 'project_type'; funktionen kommer att mata ut en select med indrag.

Sammanfattning: när det är värt ansträngningen att skriva kod

En exklusiv taxonomi behövs inte för varje projekt. Om redaktörer förstår webbplatsens logik och inte gör misstag vid val, räcker vanliga kryssrutor. Men när kostnaden för fel är hög (en landningssida i portföljen felaktigt markerad som både "webbutik" och "case study"), betalar en halvtimmes kodning sig i innehållets renhet.

  • Om du har en webbplats och ingen utvecklare, installera Radio Buttons for Taxonomies. Det fungerar utan kod.
  • Om du är en byrå eller driver en multisite, kopiera koden ovan till ditt bastema. Färre tillägg, färre felpunkter vid uppdateringar.
  • Om din webbplats körs på ren Gutenberg, överväg om du ens behöver en taxonomi. Kanske räcker ett ACF-fält med radioknappar: färre entiteter, snabbare admin.

Börja med en testsajt. Registrera taxonomin, lägg till tre termer och skapa ett inlägg; gränssnittet fungerar omedelbart. Skriv i kommentarerna vilken uppgift du använde en exklusiv taxonomi för.