Skip to content

Alles für WordPress, Webentwicklung — und mehr

🛠 Exklusive Taxonomien in WordPress: wie man Checkboxen durch Radio-Buttons ersetzt

🛠 Exklusive Taxonomien in WordPress: wie man Checkboxen durch Radio-Buttons ersetzt

Standardmäßig erlaubt Ihnen WordPress, einem Beitrag beliebig viele Begriffe aus einer einzigen Taxonomie zuzuweisen. Checkboxen in der Seitenleiste, und fertig. Doch was, wenn der Kunde möchte, dass der Redakteur genau eine Option auswählt? Zum Beispiel „Projekttyp": Case Study, Landingpage oder Onlineshop. Drei Optionen, und zwei davon gleichzeitig ergeben keinen Sinn.

Einen eingebauten Schalter „Taxonomie exklusiv machen" gibt es in WordPress nicht. Ein Ticket im Trac liegt seit 2010 ohne Fortschritt. Aber die Aufgabe lässt sich mit Code lösen, ohne Plugins oder zusätzliche Abhängigkeiten.

Am Ende dieses Artikels verwandeln Sie die Standard-Metabox mit Checkboxen in ein Panel mit Radio-Buttons: genau ein Begriff pro Beitrag, weniger Fehler durch die Redaktion.

💡 Kurzüberblick:

  • Registrieren Sie eine Taxonomie mit dem Parameter meta_box_cb, damit die Standard-Metabox nicht erscheint.
  • Erstellen Sie über den Hook add_meta_boxes einen eigenen Block mit Radio-Buttons.
  • Nutzen Sie save_post, um den gewählten Begriff in die Datenbank zu schreiben.
  • Der vollständige Code kann in die functions.php des Child-Themes kopiert werden und funktioniert sofort.

Was Taxonomien sind und warum Exklusivität wichtig ist

Eine Taxonomie in WordPress ist ein Mechanismus zur Gruppierung von Beiträgen. Die Standard-„Kategorien" und „Schlagwörter" sind ebenfalls Taxonomien. Eine benutzerdefinierte Taxonomie wird für eine spezifische Aufgabe erstellt: „Projekttyp" für ein Portfolio, „Region" für ein Filialverzeichnis, „Leistungsart" für eine Preisliste.

Die eingebauten Kategorien funktionieren als exklusive Taxonomie: Ein Beitrag gehört zu genau einer Kategorie, sofern Sie keine Erweiterungs-Plugins verwenden. Die Hierarchie „Übergeordnet → Untergeordnet" legt dem Redakteur die Auswahllogik nahe.

Jede benutzerdefinierte Taxonomie, die über register_taxonomy() registriert wird, ist jedoch standardmäßig nicht exklusiv. Die Oberfläche besteht aus Checkboxen oder einem Feld mit Autovervollständigung. Für Schlagwörter und Produktattribute ist das korrekt. Wenn aber jeder Beitrag genau einen Begriff haben muss, werden Checkboxen zur Fehlerquelle.

Die Lösung: Blenden Sie die Standard-Metabox aus und rendern Sie Ihre eigene, mit Radio-Buttons und strikter Kontrolle. Das ist kein Workaround, sondern eine dokumentierte WordPress-API, nur auf mehrere Schritte verteilt.

Schritt 1: Eine benutzerdefinierte Taxonomie registrieren

Die Grundlage ist die Funktion register_taxonomy(). Der Code wird in die functions.php des Child-Themes oder über das Plugin Code Snippets eingefügt. Erstellen wir eine Taxonomie project_type für Standardbeiträge:

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' );

Wichtige Parameter:

  • hierarchical => true aktiviert eine Baumstruktur, wie bei Kategorien. Begriffe werden hierarchisch organisiert: „Design → Landingpage", „Entwicklung → Onlineshop".
  • show_in_rest => true macht die Taxonomie in der REST-API und im Block-Editor verfügbar. Ohne dies sieht Gutenberg die Metabox nicht.
  • meta_box_cb => false und show_in_quick_edit => false entfernen die Standardoberfläche zur Begriffsauswahl vollständig.

Nach dem Speichern des Codes erschien die Taxonomie project_type im Menü „Beiträge". Begriffe werden über „Beiträge → Projekttyp" mit einer Standardoberfläche hinzugefügt, wie bei Kategorien.

Schritt 2: Die Standard-Metabox ausblenden

Dieser Schritt wurde tatsächlich bereits mit den Parametern meta_box_cb und show_in_quick_edit in Schritt 1 erledigt. Zur Zusammenfassung:

  • meta_box_cb => false entfernt die Metabox von der Beitragsbearbeitungsseite.
  • show_in_quick_edit => false blendet die Taxonomie in der Schnell- und Massenbearbeitung aus.

Ohne diese fügt WordPress eine Standardoberfläche hinzu: für hierarchische Taxonomien Kategorie-Checkboxen, für nicht-hierarchische ein Schlagwortfeld mit Autovervollständigung.

meta_box_cb und show_in_quick_edit Parameter in register_taxonomy

Die Begriffe werden über eine separate Verwaltungsseite befüllt:

Verwaltungsseite für benutzerdefinierte Taxonomiebegriffe im WordPress-Admin

Schritt 3: Eine benutzerdefinierte Metabox mit Radio-Buttons erstellen

Registrieren Sie Ihre eigene Metabox über den Hook add_meta_boxes. Ergänzen Sie in der 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}

Parameter von add_meta_box():

  • project_type_box: interne ID (beliebig, aber eindeutig).
  • 'Project Type': Titel im Admin-Panel.
  • sd_render_project_type_meta_box: Rendering-Funktion.
  • 'post': Beitragstyp; kann ein Array für mehrere CPTs sein.
  • 'side': Seitenleiste. Alternativen: 'normal', 'advanced'.

Die Funktion, die die Radio-Buttons rendert:

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}

Wichtig hierbei:

  • get_terms() mit hide_empty => false gibt alle Begriffe zurück, auch ungenutzte.
  • get_the_terms() gibt ein Array zurück; wir nehmen das erste Element [0], da die Logik garantiert, dass es nicht mehr als einen Begriff gibt.
  • checked() ist eine eingebaute WordPress-Funktion, die checked="checked" ausgibt, wenn eine Übereinstimmung vorliegt.
  • esc_attr() und esc_html() sind obligatorisches Escaping.

Das Ergebnis ist ein sauberer Block mit Radio-Buttons:

Benutzerdefinierte Meta-Box mit Radio-Buttons zur Auswahl eines einzelnen Taxonomiebegriffs

Keine Checkboxen, keine Möglichkeit, zwei Optionen auszuwählen.

Schritt 4: Den Begriff beim Speichern des Beitrags sichern

Ohne diesen Schritt ist die Metabox rein dekorativ. Wir nutzen den Hook 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}

Details:

  • DOING_AUTOSAVE: Wir überspringen automatische Speicherungen. Ohne diese Prüfung wird der Begriff alle 60 Sekunden im Hintergrund überschrieben.
  • current_user_can( 'edit_post', $post_id ): grundlegende Berechtigungskontrolle.
  • absint() konvertiert den Wert in eine positive Ganzzahl, sicherer als (int) sanitize_text_field().
  • wp_set_object_terms() mit einer einzelnen ID (nicht als Array) schreibt genau einen Begriff und entfernt vorherige Zuordnungen.

Fertig. Speichern Sie den Beitrag, und die Auswahl des Radio-Buttons wird festgeschrieben. Wenn Sie ihn erneut öffnen, ist der gewählte Begriff hervorgehoben.

Vollständiger Code zum Kopieren

Alle vier Schritte in einem Snippet. Fügen Sie es in die functions.php Ihres Child-Themes oder über Code Snippets ein:

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}

⚠️ Erstellen Sie ein vollständiges Backup der Website, bevor Sie den Code einfügen. Der Code wurde mit der aktuellen WordPress-Version und dem klassischen Editor getestet. In Gutenberg wird die benutzerdefinierte Metabox unverändert in der Seitenleiste angezeigt.

In der Praxis haben wir dieses Snippet in drei Projekten eingesetzt, und es funktionierte überall ohne Anpassungen. Wenn Sie einen hierarchischen Beitragstyp oder mehrere Redakteursrollen haben, ersetzen Sie 'post' durch Ihren Slug und überprüfen Sie die Berechtigungen in save_post.


WordPress Trac hat das Ticket #14877 seit 2010 für native Unterstützung exklusiver Taxonomien offen. Sobald ein Parameter 'exclusive' => true im Core erscheint, schrumpft dieses gesamte Konstrukt auf eine einzige Zeile. Bis das Ticket Bewegung zeigt, bleibt der Radio-Button-Ansatz die primäre Lösung.

Und unten ein kurzes Video zum Thema, damit Sie den Prozess in Aktion sehen können:

⁉️🤔 Häufig gestellte Fragen

Funktioniert das in Gutenberg?

Ja. Der Parameter show_in_rest => true bei der Registrierung der Taxonomie ermöglicht die Kompatibilität mit dem Block-Editor. Die benutzerdefinierte Metabox erscheint in der Dokumenten-Seitenleiste, und Radio-Buttons werden korrekt angezeigt und gespeichert.

Kann dieser Ansatz auf benutzerdefinierte Beitragstypen angewendet werden?

Ja. Ersetzen Sie 'post' in register_taxonomy() und add_meta_box() durch Ihren CPT-Slug. Der restliche Code (Taxonomiename, Label, Parameter) bleibt gleich. Der Ansatz funktioniert mit jedem registrierten Beitragstyp, einschließlich solcher, die über ACF oder Custom Post Type UI erstellt wurden.

Was passiert, wenn der Redakteur keinen Begriff auswählt?

Der Beitrag wird ohne zugewiesenen Begriff gespeichert; save_post ruft wp_set_object_terms() einfach nicht auf. Wenn eine Pflichtauswahl entscheidend ist, fügen Sie eine JavaScript-Validierung im Admin hinzu oder eine Prüfung über den Hook pre_post_update.

Warum nicht das Plugin Radio Buttons for Taxonomies verwenden?

Das können Sie. Das Plugin löst die Aufgabe ohne Code und hat über 100.000 aktive Installationen. Der Nachteil ist eine weitere Abhängigkeit. Für ein oder zwei Websites ist das Plugin gerechtfertigt. Für Agenturen und Multisites bietet Code im Theme volle Kontrolle ohne zusätzliche Updates und Konflikte.

Wie füge ich eine hierarchische Auswahl hinzu (übergeordnet → untergeordnet)?

Hierarchische Taxonomien (hierarchical => true) erhalten automatisch eine Eltern-Kind-Struktur. Um die Hierarchie in der benutzerdefinierten Metabox anzuzeigen, ersetzen Sie get_terms() durch wp_dropdown_categories() mit dem Parameter 'taxonomy' => 'project_type'; die Funktion gibt ein Select mit Einrückungen aus.

Das Fazit: Wann sich der Aufwand für Code lohnt

Eine exklusive Taxonomie wird nicht für jedes Projekt benötigt. Wenn Redakteure die Logik der Website verstehen und bei der Auswahl keine Fehler machen, genügen Standard-Checkboxen. Aber wenn die Kosten für Fehler hoch sind (eine Landingpage im Portfolio, die versehentlich sowohl als „Onlineshop" als auch als „Case Study" markiert ist), zahlt sich eine halbe Stunde Programmierung durch saubere Inhalte aus.

  • Wenn Sie eine Website und keinen Entwickler haben, installieren Sie Radio Buttons for Taxonomies. Es funktioniert ohne Code.
  • Wenn Sie eine Agentur sind oder ein Multisite betreiben, kopieren Sie den obigen Code in Ihr Basis-Theme. Weniger Plugins, weniger Fehlerquellen bei Updates.
  • Wenn Ihre Website auf reinem Gutenberg läuft, überlegen Sie, ob Sie überhaupt eine Taxonomie benötigen. Vielleicht genügt ein ACF-Feld mit Radio-Buttons: weniger Entitäten, schnellerer Admin.

Beginnen Sie mit einer Testseite. Registrieren Sie die Taxonomie, fügen Sie drei Begriffe hinzu und erstellen Sie einen Beitrag; die Oberfläche funktioniert sofort. Schreiben Sie in die Kommentare, für welche Aufgabe Sie eine exklusive Taxonomie verwendet haben.