Das Wichtigste in 30 Sekunden

  • 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() im init-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) und menu_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

Kurz gesagt: Ein Custom Post Type ist ein eigener Inhaltstyp in WordPress, der sich wie Beiträge oder Seiten verhält, aber ein eigenes Archiv, eigene URLs und eigene Felder bekommt. Typische Anwendungsfälle sind Portfolio-Projekte, Referenzen, Veranstaltungen, Rezepte, Stellenanzeigen oder Immobilienangebote.

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

Kurz gesagt: Einen eigenen Post-Typ brauchen Sie, wenn Inhalte eine eigene Struktur, ein eigenes Archiv oder eigene Felder brauchen. Eine einzelne Sonderseite oder drei Projekte, die man auch als Seiten anlegen kann, rechtfertigen keinen CPT.
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 auf false und muss explizit gesetzt werden.
  • has_archive: Statt true kö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-portfolio oder dashicons-calendar-alt geben 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_ oder mein_, 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

Kurz gesagt: Custom Post Types gehören nicht in die functions.php des Themes. Wenn das Theme wechselt, verschwinden die CPTs, und alle Einträge sind zwar noch in der Datenbank, aber nicht mehr erreichbar. Ein mu-plugin überlebt jeden Theme-Wechsel.

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 mit register_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.

Direkt umsetzbar: mu-plugin-Starter für CPT mit Taxonomie

Diese Datei in /wp-content/mu-plugins/mein-cpt.php ablegen. Präfix, Slug und Labels nach Bedarf anpassen, dann einmalig unter Einstellungen > Permalinks speichern.

<?php
/**
 * Plugin Name: Mein Custom Post Type
 * Description: Registriert einen eigenen Inhaltstyp mit Taxonomie.
 * Version:     1.0
 */

add_action( 'init', 'mein_register_cpt_und_taxonomie' );

function mein_register_cpt_und_taxonomie() {

    // --- Custom Post Type ---
    $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',
    );

    register_post_type( 'mein_projekt', array(
        'labels'        => $cpt_labels,
        'public'        => true,
        'has_archive'   => true,
        'rewrite'       => array( 'slug' => 'projekte' ),
        'supports'      => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
        'show_in_rest'  => true,  // Pflicht fuer Gutenberg
        'menu_icon'     => 'dashicons-portfolio',
        'menu_position' => 5,
    ) );

    // --- Custom Taxonomy ---
    $tax_labels = array(
        'name'          => 'Leistungsbereiche',
        'singular_name' => 'Leistungsbereich',
        'add_new_item'  => 'Neuen Leistungsbereich anlegen',
    );

    register_taxonomy( 'mein_leistung', 'mein_projekt', array(
        'labels'       => $tax_labels,
        'hierarchical' => true,   // true = Kategorien, false = Tags
        'show_in_rest' => true,
        'rewrite'      => array( 'slug' => 'leistung' ),
    ) );
}

Präfix mein_ durch Ihr eigenes Kürzel ersetzen, um Plugin-Konflikte zu vermeiden. Wer den Aufbau abnehmen oder auf ein bestehendes Projekt anwenden lassen möchte, findet weitere Infos unter unserer WordPress-Entwicklung.

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?
Das Wichtigste zum Mitnehmen

  • 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_rest auf true ist 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.