- Custom Post Types (CPT) schaffen einen eigenen Inhaltstyp mit eigenem Archiv, eigenen URLs und eigenen Feldern. Für Portfolio, Referenzen, Veranstaltungen oder Rezepte ist das die saubere Lösung.
- Registrieren Sie CPTs mit
register_post_type()iminit-Hook, am besten in einem kleinen mu-plugin. So bleiben sie beim Theme-Wechsel erhalten. - Plugin-Lösungen wie CPT UI sind für Nicht-Entwickler sinnvoll. Eigener Code ist schlanker, versionierbar und ohne Abhängigkeit.
- Wichtige Argumente:
public,has_archive,rewrite,supports,show_in_rest(Pflicht für Gutenberg) undmenu_icon.
Neue Projekte, neue Events, neue Rezepte: irgendwann reicht der Standard-Beitragstyp von WordPress nicht mehr aus. Dann brauchen Sie einen eigenen Inhaltstyp mit eigenem Archiv, eigenem URL-Schema und eigenen Feldern. Custom Post Types sind die saubere Lösung, und Sie brauchen dafür kein Plugin. Wie das geht, warum ein mu-plugin die bessere Ablage ist als functions.php und wann CPT UI trotzdem die ehrlichere Empfehlung ist, steht hier.
Was Custom Post Types sind und wozu sie dienen
WordPress bringt von Haus aus fünf eingebaute Post-Typen mit: Beiträge (post), Seiten (page), Anhänge (attachment), Navigationsmenüs und Revisionen. Wer Referenzprojekte oder Kursangebote verwalten will, könnte alles als Beitrag anlegen. Das klappt kurzfristig, erzeugt aber schnell Durcheinander: keine saubere Trennung im Backend, keine eigenen Archive, keine strukturierten Felder und schlechte URLs.
Ein Custom Post Type löst das. Er funktioniert intern genauso wie ein Beitrag, taucht aber im Backend als eigener Menüpunkt auf, hat eine eigene Archivseite unter einer selbstgewählten URL und lässt sich mit eigenen Taxonomien und Feldern ausstatten. Ein Veranstaltungs-CPT mit dem Slug events erzeugt automatisch ein Archiv unter /events/, und jede einzelne Veranstaltung liegt unter /events/sommerfest-2026/. Das ist semantisch sauber und für Suchmaschinen wie für Redakteure viel leichter zu handhaben.
Wann ein CPT sinnvoll ist und wann nicht
| Situation | CPT sinnvoll? | Begründung |
|---|---|---|
| Portfolio mit 20+ Projekten, eigenen Feldern (Kunde, Leistung, Jahr) | Ja | Eigene Struktur, eigenes Archiv, strukturierte Daten |
| Referenzenseite mit drei Testimonials | Nein | Eine einfache Seite mit Blöcken oder einer Tabelle reicht |
| Veranstaltungskalender mit Datum, Ort und Kategorien | Ja | Eigene Felder (Datum, Ort), eigenes Archiv, eigene Taxonomie |
| Einzelne Landingpage für eine Aktion | Nein | Seite genügt; kein Archiv nötig |
| Rezepte mit Zutaten, Nährwerten und Kategorien | Ja | Strukturierte Felder, Recipe-Schema, Archiv nach Kategorie |
| Stellenanzeigen, die regelmäßig wechseln | Ja | Eigener Workflow, Archiv, einfaches Löschen nach Ablauf |
Die Faustregel: Sobald Sie sich fragen, ob ein Inhalt ein Beitrag oder eine Seite ist, und keine befriedigende Antwort finden, brauchen Sie wahrscheinlich einen eigenen Typ. Und sobald dieser Typ eigene Felder bekommt, die für alle Einträge gleich sind, ist ein CPT die sauberste Lösung.
Registrierung per Code: register_post_type()
Die Funktion register_post_type() gehört zum WordPress-Kern. Sie erwartet zwei Argumente: einen eindeutigen Schlüssel (maximal 20 Zeichen, nur Kleinbuchstaben, Ziffern, Bindestriche und Unterstriche) und ein Array mit Konfigurationsoptionen. Aufgerufen wird sie zwingend im init-Hook.
Hier ein vollständiges, kommentiertes Beispiel für einen Portfolio-CPT:
add_action( 'init', 'ihp_register_portfolio_cpt' );
function ihp_register_portfolio_cpt() {
$labels = array(
'name' => 'Projekte',
'singular_name' => 'Projekt',
'add_new_item' => 'Neues Projekt anlegen',
'edit_item' => 'Projekt bearbeiten',
'not_found' => 'Keine Projekte gefunden',
'menu_name' => 'Portfolio',
);
$args = array(
'labels' => $labels,
'public' => true, // im Frontend sichtbar
'has_archive' => true, // Archivseite unter /projekte/ aktivieren
'rewrite' => array(
'slug' => 'projekte', // URL-Präfix: /projekte/mein-projekt/
),
'supports' => array(
'title',
'editor',
'thumbnail', // Beitragsbild
'excerpt',
'custom-fields',
),
'show_in_rest' => true, // Pflicht für den Gutenberg-Editor
'menu_icon' => 'dashicons-portfolio',
'menu_position' => 5,
);
register_post_type( 'ihp_projekt', $args );
}
Ein paar Argumente, die häufig übersehen werden:
- show_in_rest: Ohne dieses Argument auf
trueöffnet der Gutenberg-Editor für diesen CPT nicht. Es steht standardmäßig auffalseund muss explizit gesetzt werden. - has_archive: Statt
truekönnen Sie hier auch einen String angeben, z. B.'portfolio'. Dann liegt das Archiv unter/portfolio/, während die Einzelbeiträge unter/projekte/liegen. Das ermöglicht flexiblere URL-Strukturen. - menu_icon: Dashicons-Klassen wie
dashicons-portfoliooderdashicons-calendar-altgeben dem Menüeintrag ein passendes Icon. Eine vollständige Übersicht finden Sie im Dashicons-Referenz auf developer.wordpress.org. - Namenskonvention: Nutzen Sie einen eigenen Präfix wie
ihp_odermein_, um Konflikte mit Plugins zu vermeiden. Das Plugin-Handbuch rät ausdrücklich davon ab,wp_als Präfix zu verwenden.
Nach der Registrierung müssen Sie einmalig die Permalinks neu generieren: im Backend unter Einstellungen > Permalinks einfach speichern, ohne etwas zu ändern. Ohne diesen Schritt liefert das Archiv eine 404-Seite.
Custom Taxonomies dazuregistrieren
Ein CPT ohne eigene Taxonomie ist oft unvollständig. Mit register_taxonomy() registrieren Sie eine eigene Kategorie oder ein eigenes Tag-System für Ihren Inhaltstyp. Auch das gehört in den init-Hook, und auch hier gilt: maximal 32 Zeichen, nur Kleinbuchstaben und Bindestriche.
add_action( 'init', 'ihp_register_projekt_taxonomie' );
function ihp_register_projekt_taxonomie() {
$args = array(
'hierarchical' => true, // true = Kategorien, false = Tags
'labels' => array(
'name' => 'Leistungsbereiche',
'singular_name' => 'Leistungsbereich',
'add_new_item' => 'Neuen Leistungsbereich anlegen',
),
'show_in_rest' => true, // Gutenberg-Kompatibilität
'rewrite' => array(
'slug' => 'leistung',
),
);
register_taxonomy( 'ihp_leistung', 'ihp_projekt', $args );
}
Das zweite Argument ('ihp_projekt') verknüpft die Taxonomie direkt mit Ihrem CPT. Sie können hier auch ein Array übergeben, wenn dieselbe Taxonomie für mehrere Typen gelten soll: array( 'ihp_projekt', 'post' ).
mu-plugin statt functions.php: warum das besser ist
Das Plugin-Handbuch von WordPress ist da eindeutig: Registrierungen von Custom Post Types gehören in ein Plugin, nicht in ein Theme. Der Grund ist einfach. Ein Theme steuert die Optik. Ein Custom Post Type ist Inhalt, und Inhalt darf nicht von der Optik abhängen. Wird das Theme gewechselt, wie es in der Praxis regelmäßig vorkommt, verliert man sonst alle Archivseiten und Einzelbeiträge im Frontend, auch wenn die Daten in der Datenbank bleiben.
Wie Child-Theme-Anpassungen Theme-Änderungen vom eigentlichen Code trennen, trennt ein mu-plugin Inhaltsstruktur von der Darstellung.
Ein sogenanntes Must-Use-Plugin (mu-plugin) liegt im Verzeichnis /wp-content/mu-plugins/ und wird von WordPress immer automatisch geladen, ohne Aktivierung und ohne Deaktivierungsmöglichkeit im Backend. Das ist für CPTs ideal.
Legen Sie eine Datei an, z. B. /wp-content/mu-plugins/ihp-post-types.php, mit diesem Kopf:
<?php
/**
* Plugin Name: IHP Custom Post Types
* Description: Registriert Portfolio-CPT und Taxonomien.
* Version: 1.0
*/
// CPT- und Taxonomie-Funktionen hier eintragen
add_action( 'init', 'ihp_register_portfolio_cpt' );
// ...
Diese Datei lädt WordPress automatisch bei jedem Request. Sie können sie in der Versionskontrolle Ihres Projekts führen, unabhängig vom Theme und ohne Plugin-Verwaltung. Das ist der entscheidende Vorteil gegenüber der functions.php: Theme-Wechsel oder -Updates löschen nichts.
Custom Fields: native Meta, ACF oder SCF
Ein CPT ohne strukturierte Felder ist oft nur halb fertig. Für ein Veranstaltungs-CPT brauchen Sie ein Datumsfeld. Für Projekte ein Feld für den Kunden, den Zeitraum und verwendete Technologien.
Drei Wege stehen zur Wahl:
- Native Custom Fields: WordPress hat seit jeher ein eingebautes Meta-System (
add_post_meta(),get_post_meta()). Sie können Felder mitregister_post_meta()registrieren und im Gutenberg-Editor über die REST-API verfügbar machen. Für einfache, technisch verwaltete Felder reicht das. Die Eingabemaske im Backend ist aber schlicht, und für Redakteure ohne Entwicklerhintergrund unpraktisch. - Advanced Custom Fields (ACF): Das am weitesten verbreitete Plugin für strukturierte Felder. Bietet eine komfortable Oberfläche für Entwickler und Redakteure, unterstützt alle gängigen Feldtypen (Datum, Bild, Beziehung, Wiederholer) und integriert sich gut mit dem Block-Editor. Für die meisten Projekte die sinnvollste Wahl.
- Secure Custom Fields (SCF): Ein Fork von ACF, entstanden im Streit zwischen Automattic und WP Engine: WP Engine war seit 2022 Eigentümer und Maintainer von ACF (Kauf von Delicious Brains). Im Konflikt 2024 hat Automattic das ACF-Plugin im offiziellen WordPress.org-Verzeichnis übernommen, geforkt und unter dem Namen Secure Custom Fields weitergeführt. Für Projekte, die keine Abhängigkeit von Automattic-eigenen Produkten wollen, eine valide Alternative mit weitgehend identischer API.
Unser Praxisrat: Native Meta für einfache, programmatisch verwaltete Felder. ACF oder SCF für alles, was Redakteure im Backend befüllen.
Code gegen Plugin: ein ehrlicher Vergleich
| Kriterium | register_post_type() im Code | CPT UI Plugin |
|---|---|---|
| Versionierbarkeit | Vollständig in Git verwaltbar | Konfiguration in der Datenbank, nicht im Repo |
| Wartungsaufwand | Kein Update nötig, keine Plugin-Abhängigkeit | Plugin-Updates erforderlich, aktuell über 1 Million Installationen |
| Lernkurve | PHP-Kenntnisse nötig | Klickbare Oberfläche, kein Code |
| Schlankheit | Nur was Sie brauchen | Zusätzliche Datenbankabfragen und Admin-Seiten |
| Team ohne Entwickler | Schwierig zu pflegen | Kunden können selbst Typen anlegen |
| Export/Import zwischen Umgebungen | Per Deployment automatisch | JSON-Export/Import nötig |
| Konfliktrisiko | Gering, kein Plugin-Overhead | Abhängig von Plugin-Qualität und Updates |
Unsere Empfehlung: Wenn ein Entwickler am Projekt sitzt, registrieren Sie CPTs per Code in einem mu-plugin. Das ist schlanker, versionierbar und ohne Abhängigkeit. Wenn der Kunde später selbst neue Inhaltstypen anlegen will oder kein Entwickler erreichbar ist, ist CPT UI die richtige Wahl. Beides ist legitim. Es kommt auf das Projekt an.
Wie die REST API im Hintergrund arbeitet und warum show_in_rest so wichtig ist, erklärt der Artikel zur WordPress REST API ausführlicher.
Praxisbeispiel: Referenzen-CPT für eine Agentur
In einem Projekt für eine Marketingagentur wurden alle Referenzen bisher als Seiten angelegt. Das führte zu einem unstrukturierten Seitenbaum, keiner Archivseite und keiner Möglichkeit, nach Branchen zu filtern. Die Lösung: ein Referenzen-CPT mit einer hierarchischen Taxonomie für Branchen.
Nach der Registrierung des CPTs (ihp_referenz) und der Taxonomie (ihp_branche) in einem mu-plugin hatte die Agentur eine saubere Übersichtsseite unter /referenzen/, filterbar nach Branche. Bestehende Seiten wurden als neue CPT-Einträge angelegt und die alten Seiten mit Weiterleitungen versehen. Das Backend wurde für die Redaktion deutlich übersichtlicher: statt verstreuter Unterseiten ein eigener Menüpunkt mit allen Referenzen auf einen Blick.
Wichtig: Die alten Seiten-URLs wurden per 301-Redirect auf die neuen CPT-URLs weitergeleitet, damit keine Rankings verloren gingen. Diesen Schritt vergessen viele bei der Umstrukturierung.
Vor der Registrierung prüfen
- Brauchen diese Inhalte ein eigenes Archiv und eigene URLs?
- Haben alle Einträge dieselbe Feldstruktur, die sich von Beiträgen/Seiten unterscheidet?
- Ist der CPT-Schlüssel unter 20 Zeichen und mit eigenem Präfix?
- Liegt der Code in einem mu-plugin, nicht in der functions.php des Themes?
- Ist show_in_rest auf true gesetzt, damit Gutenberg funktioniert?
- Wurde nach der Registrierung der Permalink-Cache einmalig neu generiert (Einstellungen > Permalinks > Speichern)?
- Sind Custom Taxonomies mit dem richtigen object_type verknüpft?
- Ist eine Weiterleitungsstrategie vorhanden, wenn bestehende Inhalte umgezogen werden?
- Custom Post Types sind die saubere Lösung für Inhalte mit eigener Struktur, eigenem Archiv und eigenen Feldern. Alles als Beitrag anzulegen kostet langfristig mehr Aufwand als eine einmalige CPT-Registrierung.
- Registrieren Sie CPTs im
init-Hook, immer in einem mu-plugin statt in der functions.php, damit Theme-Wechsel keine Inhalte unsichtbar machen. - Das Argument
show_in_restauftrueist keine Option, sondern Pflicht, wenn Sie den Gutenberg-Editor nutzen. - Code ist schlanker und versionierbar, CPT UI ist die ehrlichere Empfehlung, wenn Kunden selbst ohne Entwickler auskommen müssen.
Häufige Fragen
Was ist ein Custom Post Type in WordPress?
Ein Custom Post Type (CPT) ist ein eigener Inhaltstyp, den Sie in WordPress neben den eingebauten Typen Beiträge und Seiten registrieren. Er bekommt einen eigenen Menüpunkt im Backend, eine eigene Archivseite und lässt sich mit eigenen Feldern und Taxonomien ausstatten. Typische Beispiele sind Portfolio-Projekte, Veranstaltungen, Rezepte oder Stellenanzeigen.
Brauche ich ein Plugin, um Custom Post Types anzulegen?
Nein. WordPress stellt die Funktion register_post_type() im Kern bereit. Sie brauchen nur PHP-Grundkenntnisse und eine Datei in /wp-content/mu-plugins/. Ein Plugin wie CPT UI ist nützlich, wenn kein Entwickler am Projekt sitzt oder wenn Kunden selbst Inhaltstypen anlegen sollen.
Was ist der Unterschied zwischen einem Custom Post Type und einer Seite?
Seiten sind für statische, hierarchische Inhalte gedacht: Impressum, Über uns, Kontakt. Ein Custom Post Type ist für sich wiederholende Inhalte mit gleicher Struktur gedacht. Seiten haben kein Archiv und keine eigenen Kategorien. Ein CPT bekommt beides. Wenn Sie mehr als drei oder vier ähnliche Inhalte haben, lohnt sich die CPT-Registrierung.
Warum soll ich den CPT in einem mu-plugin registrieren statt in functions.php?
Ein mu-plugin liegt in /wp-content/mu-plugins/ und wird von WordPress immer geladen, unabhängig vom aktiven Theme. Wenn Sie die CPT-Registrierung in die functions.php schreiben und später das Theme wechseln, verschwinden alle Archivseiten und Einzelbeiträge im Frontend. Die Daten bleiben in der Datenbank, aber WordPress weiß nicht mehr, was für ein Typ das ist.
Was bedeutet das Argument show_in_rest?
show_in_rest: true macht den Post-Typ über die WordPress REST API zugänglich und aktiviert damit den Gutenberg-Block-Editor für diesen Typ. Ohne dieses Argument öffnet Gutenberg nicht, und Sie landen beim alten Classic-Editor. Das Argument hat nichts mit der öffentlichen Sichtbarkeit des CPTs zu tun.
Kann ich Custom Post Types auch rückwirkend zu bestehenden Inhalten hinzufügen?
Ja, aber mit Aufwand. Bestehende Seiten oder Beiträge werden dabei manuell oder per Skript als neue CPT-Einträge angelegt. Die alten URLs müssen dann per 301-Redirect auf die neuen weitergeleitet werden, damit Rankings und eingehende Links erhalten bleiben. Wer das vergisst, verliert Rankingpositionen.
Was ist der Unterschied zwischen einer Custom Taxonomie und einer Kategorie?
Kategorien und Tags sind eingebaute Taxonomien für den Beitragstyp post. Eine Custom Taxonomie funktioniert genauso, gehört aber zu Ihrem eigenen Inhaltstyp. Mit hierarchical: true verhält sie sich wie Kategorien mit Unterkategorien, mit false wie Tags. Sie können Custom Taxonomies auch mit mehreren Post-Typen gleichzeitig verknüpfen.
Ist es sinnvoll, für jeden Zweck einen eigenen CPT zu erstellen?
Nein. Ein CPT lohnt sich erst, wenn Sie mehrere Einträge desselben Typs verwalten und wenn diese eigene Felder oder ein eigenes Archiv brauchen. Für eine einzelne Team-Seite mit drei Mitgliedern ist ein CPT überdimensioniert. Eine einfache Seite mit Blöcken oder eine Tabelle reicht. Die Faustregel: Wenn Sie sich unsicher sind, brauchen Sie wahrscheinlich keinen CPT.
