
⚙️ WordPress: So legst du ein Standard-Template für einen benutzerdefinierten Beitragstyp fest
Sie haben dem Kunden eine Website auf WordPress mit einem Portfolio übergeben, und am nächsten Tag ruft er an: „Ich lege einen neuen Eintrag an, aber die Vorlage springt immer wieder auf die Standardvorlage mit Seitenleiste zurück. Wie kann ich sie fest zuweisen?" Die Situation ist schmerzlich vertraut: Sie klicken bei einem benutzerdefinierten Beitragstyp auf „Neu hinzufügen", und statt des von Ihnen gebauten Layouts über die volle Breite erscheint eine Blog-Spalte mit Seitenleiste. Die Vorlage bei jedem Beitrag manuell auszuwählen ist sinnlose Fleißarbeit, die sowohl Sie als auch den Kunden frustriert. Vor allem dann, wenn „Volle Breite" ohne Seitenleiste fast immer das ist, was Sie benötigen.
Standardmäßig verwendet WordPress für benutzerdefinierte Beitragstypen (Custom Post Types, CPTs) die single.php des Themes. Und single.php ist üblicherweise auf einen Blog zugeschnitten: Titel, Inhalt, Seitenleiste mit Widgets. Für Portfolios, Case Studies, Referenzen oder Produkte passt dieses Layout schlecht. Die gute Nachricht: WordPress bietet vier Wege, um einem CPT eine Vorlage zuzuweisen, vom einfachsten (eine Datei im Theme, ganz ohne Code) bis hin zur vollständig programmatischen Lösung über Hooks und Block-Themes. Jede Methode erledigt die Aufgabe zuverlässig; der einzige Unterschied liegt im Maß an Kontrolle und Wartungsfreundlichkeit.
💡 Kurzüberblick:
- Legen Sie eine Datei
single-{post_type}.phpim Theme-Stammverzeichnis an, und WordPress greift automatisch über die Template-Hierarchie darauf zu - Hängen Sie sich in den Filter
template_includein derfunctions.phpein, um eine Vorlage programmatisch zuzuweisen, ohne eine physische Datei im Theme zu platzieren - Erstellen Sie für Block-Themes
single-{post_type}.htmlim Ordnertemplates/; die Datei kann ohne Code über den Website-Editor bearbeitet werden - Leeren Sie nach jeder Änderung die Permalinks: „Einstellungen → Permalinks → Änderungen speichern", sonst erkennt WordPress die neue Vorlage nicht
Methode 1: Vorlagendatei über die WordPress-Hierarchie
Die zuverlässigste und direkteste Methode. Seit Version 3.0 unterstützt WordPress benutzerdefinierte Vorlagen für CPTs über die standardmäßige Template-Hierarchie. So funktioniert es: Wenn ein Besucher einen Eintrag des Typs portfolio öffnet, sucht WordPress in einer festgelegten Reihenfolge von oben nach unten nach einer Vorlage und verwendet die erste gefundene Datei:
single-portfolio.php → single.php → singular.php → index.php
Sie müssen eine Datei mit dem Namen single-{post_type}.php anlegen, wobei {post_type} der Slug Ihres benutzerdefinierten Typs ist. Platzieren Sie sie im Stammverzeichnis des aktiven Themes:
1 /* File: /wp-content/themes/your-theme/single-portfolio.php */ 2 3 <?php get_header(); ?> 4 5 <div class="full-width-content"> 6 <?php while ( have_posts() ) : the_post(); ?> 7 <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>> 8 <h1><?php the_title(); ?></h1> 9 <div class="entry-content"> 10 <?php the_content(); ?> 11 </div> 12 </article> 13 <?php endwhile; ?> 14 </div> 15 16 <?php get_footer(); ?> 17
Der schnellste Einstieg: Kopieren Sie den Inhalt von page.php oder template-fullwidth.php aus Ihrem Theme und passen Sie das Layout für den spezifischen CPT an. Existiert keine single-{post_type}.php-Datei, greift WordPress stillschweigend auf single.php zurück, und der Kunde erhält eine Seitenleiste.
Der Vorteil dieser Methode: kein Code in der functions.php; die Datei liegt einfach im Theme und funktioniert. Der Nachteil: Die Vorlage ist eng an das Theme gekoppelt. Wechseln Sie das Theme, bleibt die Datei im alten Ordner und funktioniert nicht mehr.
Methode 2: Programmatisch über den template_include-Filter
Die dateibasierte Methode funktioniert, solange Sie die Kontrolle über das Theme haben. Wenn Sie jedoch ein Plugin oder ein Child-Theme entwickeln, das nicht davon abhängen soll, dass eine Datei im Stammverzeichnis vorhanden ist, benötigen Sie den Hook template_include.
Der Filter wird ausgelöst, bevor die Vorlage geladen wird, und erlaubt es Ihnen, auf eine PHP-Datei von einem beliebigen Ort aus zu verweisen:
1 /* File: functions.php (theme) or main plugin file */ 2 3 add_filter( 'template_include', 'sd_cpt_default_template', 99 ); 4 5 function sd_cpt_default_template( $template ) { 6 if ( is_singular( 'portfolio' ) ) { 7 $custom_template = plugin_dir_path( __FILE__ ) . 'templates/single-portfolio.php'; 8 if ( file_exists( $custom_template ) ) { 9 return $custom_template; 10 } 11 } 12 return $template; 13 }
Was hier passiert:
is_singular('portfolio')prüft, ob wir uns auf einer Einzelansicht-Seite des Typsportfoliobefinden- Ist die Bedingung wahr, lädt WordPress die Vorlage aus dem Plugin-Ordner und umgeht damit die Theme-Hierarchie
- Die Priorität 99 stellt sicher, dass der Filter zuletzt ausgelöst und nicht vom Theme überschrieben wird
Dieser Ansatz ist praktisch, wenn die Vorlage innerhalb eines Plugins leben und Theme-Wechsel überdauern soll. Die Datei templates/single-portfolio.php innerhalb des Plugins kann get_header() und get_footer() des aktiven Themes verwenden, sodass optisch alles mit dem Design der Website konsistent bleibt.
Methode 3: Der {$type}_template-Filter
WordPress stellt einen dynamischen Hook {$type}_template bereit, wobei $type für single, archive oder page steht. Für einen CPT nimmt er die Form single-portfolio_template an und erlaubt es Ihnen, die Vorlage präzise zu überschreiben, ohne zusätzliche Prüfungen innerhalb der Callback-Funktion:
1 add_filter( 'single_template', 'sd_cpt_template_by_type' ); 2 3 function sd_cpt_template_by_type( $single_template ) { 4 global $post; 5 6 if ( 'portfolio' === $post->post_type ) { 7 $custom_template = get_stylesheet_directory() . '/single-portfolio.php'; 8 if ( file_exists( $custom_template ) ) { 9 return $custom_template; 10 } 11 } 12 return $single_template; 13 }
Der Unterschied zu Methode 2 ist semantischer Natur: Sie sagen explizit „ändere die Vorlage für Einzeleinträge", anstatt „fange alle Vorlagen ab". Der Code ist etwas aufgeräumter, aber funktional lösen beide Hooks das Problem auf die gleiche Weise.
Methode 4: Vorlage in einem Block-Theme (Full Site Editing)
Mit WordPress 5.9 und dem Wechsel zu Block-Themes ändert sich der Ansatz. In FSE-Themes sind Vorlagen HTML-Dateien im Ordner templates/, nicht PHP. Für einen benutzerdefinierten Beitragstyp erstellen Sie:
1 /wp-content/themes/your-fse-theme/templates/single-portfolio.html
Im Inneren verwenden Sie eine blockbasierte Struktur. Ein minimales Beispiel:
1 <!-- wp:template-part {"slug":"header","theme":"your-fse-theme"} /--> 2 3 <!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} --> 4 <main class="wp-block-group"> 5 <!-- wp:post-title {"level":1} /--> 6 <!-- wp:post-featured-image /--> 7 <!-- wp:post-content {"layout":{"type":"constrained"}} /--> 8 </main> 9 <!-- /wp:group --> 10 11 <!-- wp:template-part {"slug":"footer","theme":"your-fse-theme"} /-->
Sie können diese Vorlage direkt im Website-Editor (Design → Editor) bearbeiten, ohne Code anzufassen. Wechseln Sie das Block-Theme, bleibt die Datei im alten Ordner, dieselbe Schwachstelle wie bei Methode 1.
Welche Methode soll man wählen
Eine kurze Entscheidungsmatrix für Ihr Szenario:
Szenario | Methode |
|---|---|
Ein Theme, ein CPT, keine Plugins | Methode 1: |
Plugin mit eigener Vorlage | Methode 2: |
Child-Theme, Überschreiben der Eltern-Vorlage nötig | Methode 1 oder 3 |
FSE / Block-Theme (Twenty Twenty-Four und neuer) | Methode 4: |
Nach der Implementierung einer der Methoden gehen Sie unbedingt zu „Einstellungen → Permalinks" und klicken auf „Änderungen speichern". Das leert den Cache der Rewrite-Regeln, und WordPress erkennt die neue Vorlage.
⁉️🤔 Häufig gestellte Fragen
Die Vorlage wird nicht erkannt. Was soll ich tun?
Leeren Sie zuerst die Permalinks („Einstellungen → Permalinks → Speichern"). Prüfen Sie zweitens, ob der CPT-Slug im Dateinamen mit dem Slug aus
register_post_type()übereinstimmt. Leeren Sie drittens den Cache, falls ein Caching-Plugin aktiv ist. In der Praxis liegt das Problem meistens am Leeren der Rewrite-Regeln nach der Registrierung des CPT, nicht am Vorlagencode selbst.
Kann ich eine Vorlage mehreren CPTs gleichzeitig zuweisen?
Ja. Verwenden Sie bei Methode 2 ein Array in
is_singular():is_singular( array( 'portfolio', 'testimonials', 'team' ) ). Oder prüfen Siein_array( $post->post_type, array('portfolio', 'team') )innerhalb der Callback-Funktion. Die Vorlagendatei ist eine, und das Layout wird über alle aufgeführten Typen hinweg geteilt.
Die Vorlage funktioniert, aber das Layout ist fehlerhaft (fehlende Seitenleisten-/Header-Stile).
Sie haben die Vorlage von
page.phpübernommen, aber die Stile des Themes hängen von CSS-Klassen ambodyab. Fügen Sie einenbody_class-Filter in derfunctions.phphinzu, damit WordPress dem<body>einepost-type-{slug}-Klasse zuweist, und die Stile greifen:
1 add_filter( 'body_class', function( $classes ) { 2 if ( is_singular( 'portfolio' ) ) { 3 $classes[] = 'single-portfolio'; 4 } 5 return $classes; 6 } );
Was passiert beim Theme-Wechsel? Die Vorlage verschwindet.
Ja, die Datei
single-portfolio.phpverbleibt im Ordner des alten Themes. Ihre Optionen: Verschieben Sie die Datei manuell in das neue Theme, verwenden Sie ein Child-Theme (die Datei überdauert Updates des Eltern-Themes) oder verlagern Sie die Vorlage über Methode 2 in ein Plugin, das nicht vom aktiven Theme abhängt.
Was, wenn ALLE CPTs standardmäßig ohne Seitenleiste geöffnet werden sollen?
Verwenden Sie einen universellen Filter mit
is_singular(), ohne einen bestimmten post_type anzugeben, schließen Sie aber die Standardtypenpostundpageaus:
1 add_filter( 'template_include', function( $template ) { 2 if ( is_singular() && ! is_singular( array( 'post', 'page' ) ) ) { 3 $fullwidth = get_stylesheet_directory() . '/template-fullwidth.php'; 4 if ( file_exists( $fullwidth ) ) { 5 return $fullwidth; 6 } 7 } 8 return $template; 9 }, 99 );
Diese Lösung wendet eine einzige Vorlage mit voller Breite auf alle benutzerdefinierten Beitragstypen gleichzeitig an: Portfolios, Referenzen, Teammitglieder, Case Studies. Standardbeiträge und -seiten sind nicht betroffen.
Lohnt sich der Aufwand mit template_include, wenn man einfach eine Datei anlegen kann?
Wenn Sie eine Website, ein Theme und einen CPT haben, erstellen Sie single-{post_type}.php und vergessen Sie die Sache. Das ist eine Lösung, die jahrelang hält: Sie geht bei WordPress-Updates nicht kaputt, hängt nicht von der PHP-Version ab und ist für jeden Entwickler, der den Theme-Ordner öffnet, sofort verständlich. Die Wartung beschränkt sich auf eine einzige Datei, die Sie im Handumdrehen korrigieren können.
Programmatische Methoden über Hooks sind in zwei Fällen gerechtfertigt. Erstens: Die Vorlage ist Teil eines verteilten Plugins, und Sie möchten Nutzern nicht zumuten, Dateien ins Theme zu kopieren. Zweitens: CPTs werden dynamisch über ACF, Toolset oder ein ähnliches Plugin registriert, und ein Dutzend single-*.php-Dateien im Theme anzuhäufen ist unpraktisch. Für alles andere ist die WordPress-Template-Hierarchie der einfachste und zuverlässigste Weg, über Jahre bewährt.



