Kommentare 46

WordPress Custom Post Types (Teil2): Selbst individuelle Inhaltstypen und Taxonomies anlegen

Im ersten Teil des Custom Post Types-Artikels habe ich die praktische WordPress-Option, eigene Inhaltstypen anzulegen in der Theorie erklärt. Heute geht es dagegen in die Praxis und ich beschreibe dir, wie du dein WordPress-Theme selbst mit Custom Post Types und Custom Taxonomies ausstatten und somit WordPress zu einem starken Content Management System machen kannst.

1. Eigene Custom Post Types im Theme anlegen

Im ersten Artikel-Teil über die Custom Post Types in WordPress habe ich ja schon das hilfreiche Plugin Custom Post Type UI vorgestellt, um neue Custom Post Types und Taxonomies zu erstellen.

Natürlich kannst du auch auf ein Plugin verzichten und den benötigten Code selbst in deine Theme-Dateien einfügen.

1.1. Custom Post Types über die functions.php anlegen

Um z.B. den Custom Post Type “Projects” für ein individuelles Portfolio-Element in WordPress umzusetzen, öffnest du die functions.php Datei deines Themes und fügst folgenden Code ein:

function post_type_projects() {
	register_post_type(
                'projects',
                array(
                    'label' => __('Projects'),
                    'public' => true,
                    'show_ui' => true,
                    'supports' => array(
	            'title',
		    'editor',
                    'post-thumbnails',
                    'custom-fields',
                    'revisions')
                )
        );
}
add_action('init', 'post_type_projects');

Im Code wird die WordPress-Funktion register_post_type genutzt, um den neuen Inhaltstyp zu definieren. Unter Supports kannst du festlegen, welche Felder du für das Verfassen deiner individuellen Inhalte (in diesem Fall der Projekte) benötigst.

Eine genaue Beschreibung zu den möglichen Argumenten für register_post_type findest du im WordPress Codex. Auch auf dem Blog von Justin Tadlock im Artikel “Custom Post Types in WordPress” kannst du noch mehr über die Funktion und die zusätzlichen Optionen erfahren.

Der neue Bereich Projects ist jetzt in deinem Admin-Menü integriert. Um ein neues Projekt anzulegen, kannst du einfach auf Projects / Erstellen klicken.

WordPress Custom Post Types anlegen
Jetzt kannst du ein neues Projekt für dein Portfolio erstellen.

1. 2. Custom Taxonomies für den neuen Inhaltstyp erstellen

Um jetzt auch noch eigene Werte (genannt Taxonomies, diese sind mit den Schlagwörtern und Kategorien zu vergleichen) für deine Projekte im Admin-Bereich anlegen zu können, kannst du wieder über den Code in der funtions.php noch eigene Custom Taxonomies anlegen.

So kannst du z.B. auf deinen Projektseiten angeben, mit welchen Techniken (Skills) bei den Projekten gearbeitet wurden. Dazu legst du dir die Taxonomie “Skills” an, um dort Werte wie HTML, CSS, WordPress, Photoshop oder Illustration eingeben zu können.

WordPress Custom Post Types anlegen

Dazu erweiterst du deinen Code in der functions.php Datei um den Absatz register_taxonomy:

function post_type_projects() {
	register_post_type(
                'projects',
                array(
                    'label' => __('Projects'),
                    'public' => true,
                    'show_ui' => true,
                    'supports' => array(
					'title',
					'editor',
                    'post-thumbnails',
                    'custom-fields',
                    'revisions')
                )
        );
	
       register_taxonomy( 'skills', 'projects',
		array(
             'hierarchical' => false,
			 'label' => __('Skills'),
			 'query_var' => 'skills',
			 'rewrite' => array('slug' => 'skills' )
		)
	);
}
add_action('init', 'post_type_projects');

Neben dem Eintragen neuer Skills innerhalb der Meta-Box während des Schreibens, kannst du deine Custom Taxonomies “skills” jetzt auch über das Menü im Admin-Bereich Projects / Skills verwalten und anpassen.

WordPress Custom Post Types anlegen

Die Skills funktionieren also genauso, wie die Schlagwörter und Kategorien bei WordPress-Seiten und Artikeln.

Weitere Infos und eine genaue Erklärung zu den Custom Taxonomies findest du auch im Artikel “Introducing WordPress 3 Custom Taxonomies” auf dem Nettuts-Blog.

1.3. Ein individuelles Template für den neuen Inhaltstyp

Standardmäßig greift der Custom Post Type-Inhalt auf das Theme-Template single.php oder alternativ auf index.php zu. Um ein eigenes Seiten-Layout für deinen neuen Inhaltstyp, z.B. deine Projektseiten zu erstellen, kannst du eine neue Template-Datei names single-projects.php in deinem Theme-Ordner anlegen. Am besten du nimmst dir die single.php Datei als Vorlage, und veränderst die Inhalte entsprechend deiner Vorstellungen.

Z.B. kannst du die Sidebar (get_sidebar) entfernen, um deine Projekte über die gesamte Webseiten-Breite präsentieren zu können. Auch die Kommentar-Funktion (comments_template) benötigst du für deine Projekten höchstwahrscheinlich nicht.

1.4. Die Custom Taxonomies im Template ausgeben

Um deine neu angelegten Custom Taxonomies (hier im Beispiel also die Skills) in der single-projects.php Datei mit auszugeben, benötigst du die Funktion get_the_term_list.

Der Code, um die Skills für dein Projekt mit auszugeben, lautet:

<?php echo get_the_term_list( $post->ID, 'skills', 'Projektumsetzung mit: ', ', ', '' ); ?> 

Weitere Info über get_the_term_list findest du auch im WordPress Codex.

Weitere Layout-Anpassungen kannst du dann natürlich auch noch mit Hilfe von HTML und entsprechenden CSS-Styles umsetzen.

2. Custom Post Types und Taxonomies mit dem Custom Post Type UI-Plugin erstellen

Falls dir die beschriebene Methode doch etwas zu viele Codeschnipsel enthält, kannst du alternativ auch eines der hilfreichen Plugins für das Anlegen von Custom Post Types und Custom Taxonomies nutzen.

Für das Plugin Custom Post Type UI hat der Plugin-Autor Brad Williams ein praktisches, kleines Video-Tutorial für die Verwendung des Plugins vorbereitet:


Custom Post Type UI Screencast von Brad Williams auf Vimeo.

3. Custom Post Types und Permalinks

Falls du beim Aufrufen deiner neuen Inhalte nur eine 404-Fehlermeldung siehst, kann es sein, dass du die die Permalink-Einstellungen im WordPress-Admin noch einmal neu speichern musst.

Falls das nicht hilft kannst du in deiner functions.php Datei die Funktion flush_rewrite_rules einfügen. Diese solltest du aber nur bei Aktivierung oder Deaktivierung tun. Mehr Infos zu Custom Posts Types und Permalinks findest du auch im Artikel “Custom Post Types and Permalinks” auf WPEngineer und auf Frank Bültges Blog unter “WordPress Custom Post Type und Permalinks”.

Um auch ein Archiv, z.B. unter deindomain.de/projects/ anlegen zu können (was leider bisher noch nicht standardmäßig der Fall ist), kannst du übrigens das Plugin Simple Custom Post Type Archives verwenden.

4. Noch mehr Lesestoff

Wie gesagt gibt es etliche hilfreiche Blog-Artikel, die das Thema Custom Post Types in WordPress bereits aufgenommen haben. Um dein Wissen über die praktische WP-Funktion noch zu erweitern, kannst du dir folgende Beiträge anschauen. Am besten probierst du die Funktion auch einmal selbst auf einer lokalen WordPress-Testinstallation aus. So bekommst du am schnellsten ein Bild davon, was mit den Custom Post Types so alles möglich ist.

Hast du Fragen oder weitere Tipps zur Verwendung der Custom Post Types in WordPress oder kennst du Tutorials oder interessante Blog-Artikel, die sich mit der Umsetzung von individuellen Inhalten in WordPress auseinandersetzen? Über dein Feedback und deine Tipps freue ich mich sehr!

46 Kommentare

  1. Ein kleiner Hinweise:
    flush_rewrite_rules() sollte nur EINMAL ausgeführt werden und nicht bei jedem, in diesem Fall init Hook, ausgeführt werden. Einmal reicht; ein Besuch der Permalinks Seite bzw erneutes abspeichern der aktuellen Einstellungen hilft auch meistens.

      • @ocean90, @Anne Jan Roeleveld,

        vielen Dank für euer Feedback und den Hinweis auf die flash_rewrite_rules.

        Ich habe den Absatz im Artikel gleich angepasst und auch noch auf den entsprechenden Artikel bei WPEngineer verwiesen, auf dem das Thema bereits etwas ausführlicher diskutiert wurde.

        Vielen Dank und viele Grüße,
        Ellen

        • Die Nutzung der Funktion nur einmal zu nutzen ist sehr wichtig, da man sonst schnell in Performanceprobleme läuft; wie ich auch in dem verlinkten WPEngineer-Beitrag und auch im deutschen Pardon schreibe.
          In allen Fällen ich die CPT via Plugin ein und nicht via Theme, da sie Inhalte einbringen und nicht Frontendgetrieben sind. Daher nutze ich dort immer den Aktivierungs- bzw. Deaktivierungshook um den Rewrite anzustoßen.
          register_activation_hook() bzw. register_deactivation_hook()

          • Jan

            Ich denke auch, daß CPTs durch ein Plugin geregelt werden sollten. Sonst muss man bei einem Wechsel des Themes ständig an die Änderung der functions.php denken.

            Ein Theme sollte jedoch niemals bestimmen, welche Inhalte dargestellt werden können und somit gehört eine solche “Konfigurations-Einstellung” nicht in das Theme, sondern in die Datenbank und dafür scheint mir das vorgestellte Plugin genau richtig zu sein.

            Deswegen mei Dank an Ellen für die Vorstellung des Plugins.

            • Hallo Jan,

              vielen Dank für deinen Kommentar und deine Einschätzung zur Nutzung der Custom Post Types. Ja, ich denke auch mit Hilfe des Plugins ist die Umsetzung zumindest für die meisten Projekte sehr viel einfacher und unabhängiger :-)

              Viele Grüße,
              Ellen

  2. Vielen Dank dafür. Ein kleiner Hinweis noch zum letzten Punkt: Die Archive sind ab der kommenden Version 3.1 von WordPress auch mit Bordmitteln möglich – auch wenn damit Simple Custom Post Type Archives nicht komplett ersetzt werden kann…

    Damit das funktioniert, muss man einfach einen weiteren Parameter beim Registrieren des Post Types übergeben:

    ‘has_archive’ => true

    Damit fällt das Archiv auf den Post-Type-Slug zurück. Man kann aber auch eigene Titel übergeben:

    ‘has_archive’ => ‘projects’

    Als Template wird dann die archive-{$post_type}.php aufgerufen. Falls die nicht existiert, zieht wie immer die archive.php.

    Mehr dazu:

    http://mark.mcwilliams.me/2010/10/wordpress-3-1-introduces-custom-post-type-archives/

    http://core.trac.wordpress.org/ticket/13818

    • Olaf

      Tut mir leid, aber ich habe noch eine Frage: Ich habe ein kleines Textfeld, in das ich gerne auch Umbrüche “hineinschreiben” würde, dummerweise wird mir der HTML Tag mit ausgegeben, also “1, 2, 3, </br> 4, 5, 6″. Gibt es einen Art “Trick oder Lösung” für dieses Art Problem?

          • ja, war es.
            naja, du willst in dem textarea die Werte in versch. Zeilen schreiben, was ich eh überlegenswert finde. Aber wenn du das willst, dann sollte die werte so kommen 1 2 3
            4 5 6, somit wird ein Break dazwischen erstellt (eventuell hilft das). Beim Auslesen, wo auch immer, musst du damit ja was machen, daher der Hinweis auf preg_split(). Hier mache ich sowas mal, da ich pro Zeile einen Listpunkt zulasse und daher im textarea auch zeilenweise ausgeben will.

            • Olaf

              Vielen lieben Dank, funktioniert leider nicht so :( Ich nutze “Ultimate Post Type Manager”, was ich eigentlich für Anfänger wie mich ideal finde, aber dieses break-Problem :( Muss ich wohl oder übel auf die Antwort des Entwicklers warten….

  3. Danke Ellen, wie immer ein umfassender und sehr hilfreicher Beitrag! Hab bei meinem letzten Projekt wirklich ausgiebig von den Custom-Post-Types gebrauch gemacht und da steckt richtig Potenzial drin. So kann der Kunde auf seiner Website nun neben klassischen Newsbeiträgen weitere Inhaltstypen wie Downloads, Event und Aktionen anlegen. Diese lassen sich dann über ein eigenes Page-Template und einer entsprechenden Abfrage mit wp_query ebenso komfortabel wie die normalen Beiträge auflisten, separat in der Darstellung anpassen und wie Du schon schreibst auch mit einer eigenen single.php darstellen. Ab WordPress 3.1 gibt es dann übrigens auch die Möglichkeit, für die Custom-Taxonomies eigene Archiv-Templates anzulegen – damit bleiben dann fast keine Wünsche mehr offen … Außerdem kann man beim Anlegen der Custom-Post-Types gleich noch benutzerdefinierte Felder (auch via functions.php) anlegen und diese nur bestimmten Post-Types zuweisen und auf diesem Wege dann wirklich individuelle Inhaltstypen anlegen. Viele Grüße an alle, Markus

  4. @Andre: diese beiden Hooks werden gezogen, wenn ich ein Plugin aktiviere bzw. deaktiviere. Bei den Custom Post Types setze ich damit z.b. die neuen Rechte-Objekte und schreibe die Rewrite Rules eben auch, das gleiche muss ich beim deaktivieren tun, da ich keine Reste in der DB lassen will.
    Ich mache dies via Plugin, da ich strickt zw. Plugin und Theme trenne. Das Theme stellt Inhalte dar, legt keine Daten an und kümmert sich um die Darstellung, um das Frontend. Wenn ich das Theme wechsel, dann sollten alle Daten weiterhin da sein und nutzbar sein. Insofern also ein Plugin.

    • Andre

      Danke Frank :)
      Das Hilft mir als WordPress Anfänger (als Webdesigner) schonmal weiter. Wie das mit den Hooks so läuft kann ich mir ja auf der Homepage von WordPress ansehen.

  5. @alle: Vielen herzlichen Dank für euer Feedback zum Artikel!

    @Frank, @Markus, @Christian, @Claudio,
    vielen Dank für die hilfreichen Ergänzungen. Eure Hinweise und Tipps haben mir beim Verständnis der Custom Post Types / Custom Taxonomies auch noch einmal sehr weiter geholfen :-)

    Viele Grüße,
    Ellen

  6. Sebastian B.

    Hallo Ellen und alle Mitleser,

    wie immer vielen Dank für den Artikel. Ganz kurze Verständnisfrage zu den Einsatzmöglichkeiten. Für ein Kundenprojekt in dem WP als klassisches CMS eingesetzt wird werden für die unterschiedlichen Rubriken wie z. B. “Leistungen”, “Referenzen” etc. andere Templates eingesetzt mit jeweils individueller Sidebar. Gerne möchte ich den Kunden ermöglichen aus dem Backend heraus alle Punkte der Sidebar zu verändern bzw. zu ergänzen. Angedacht war dies über die benutzerdefinierten Felder zu lösen. Allerdings wirkt inzwischen im Backend die Bearbeitung der einzelnen Seiten schon recht unübersichtlich und müsste was geändert bzw. ergänzt werden müsste dies dann ja auf allen Unterseiten auf denen die jeweilige Sidebar eingeblendet wird verändert werden.

    Macht es Sinn für die unterschiedlichsten Sidebars die Custom Post Types einzusetzen und aus jeder dieser Sidebar ein einzelnen Custom Post Type zu machen?

    Ich werde auch so schnell wir möglich meine Hausaufgaben erledigen und mich näher damit beschäftigen!

    Vielen Dank !

    • @Sebastian Vielleicht hilft Dir das Display Widgets Plugin weiter.
      Damit lassen sich einzelne Widgets auf bestimmten Seiten (page.php) oder Artikelseiten (single.php) sowie div. anderen (search.php, archive.php, 404.php etc.) verbergen bzw. anzeigen.
      Ich persönlich habe damit die Notwendigkeit für zu viele einzelne Sidebars drastisch reduzieren können. 2-3 Sidebars + das Plugin = schön übersichtlicher Widget-Screen im Backend! :-)

  7. Andre

    Kann man die Custom Post Types auch wie Artikel ausgeben? Oder sind sie nur wie statische Seiten? Ich stehe gerade vor einem Problem, weil ich sie nun endlich in mein Theme einbinden wollte. :D

  8. Hallo Ellen,

    super Serie über die Custom Post Types. Was ich mich gerade Frage ist, wie kann ich den das single.php Template eines bestimmten Custom Post Types abfragen?

    Page Templates kann man ja über
    abfragen – gibt es sowas auch für die single-xyz.php?

    Danke und viele Grüße,
    Daniel

  9. Fatih M. Piontek

    Kann ich eigentlich auch eigene Felder zur Eingabe definieren? Ich will gerne den allgemeinen Bildupload sperren und ein Eingabefeld für ein einzelnes Bild hinzufügen.

  10. Jorge

    Bisher habe ich nur mit einfachen Bordmitteln gearbeitet. An welcher Stelle der function.php wird der Code eingebaut ? Beim Twenty Ten 1.3 Template gibt es rund 500 Zeilen Code.
    Frage 2 wie bekomme ich dann das Projekt in die Menueleiste- oder Artikel? Dank für Antwort

  11. Vielen Dank für Deinen hilfreichen Artikel. Meine Tendenz geht eher dahin keine Plugins, bzw. so wenig wie möglich, zu verwenden, sondern die Taxonomie-Funktion via funtion.php umzusetzen, um eine bessere Kontrolle zu bewahren.
    Um Kategorien zu den Taxonomien hinzuzufügen hat mir Dein Linktipp: http://net.tutsplus.com/tutorials/wordpress/introducing-wordpress-3-custom-taxonomies auf Anhieb weitergeholfen.
    WordPress wird echt noch zu meinem Liebling, speziell, weil ich mich beruflich viel mit TYPO3 auseinandersetzen muss. Die Dokumentationen und Tutorials, wie Deine, sind für mich wie spanende Krimis
    P.S.
    Ich betreibe einen Fotoblog und bin selbst leidenschaftlicher Hobbyfotograf und finde Deine bereitgestellten Fotos auf Flickr klasse.
    Viele Grüße aus Augsburg
    Dietmar

  12. Dilli

    Ich hatte Probleme mit dem Plugin “Custom Post Type UI”. Immer wenn ich die zugehörigen Taxonomies im Template per “get_the_term_list();” abrufen wollte kam es zu dem Fehler: “Catchable fatal error: Object of class WP_Error could not be converted to string in …”. Nach langem Suchen habe ich die Custom Post Types und Taxonomies wie hier beschrieben in der functions.php erstellt und alles funktioniert. Vielleicht hilft das jemandem der ein ähnliches Problem hat. Vielen Dank für die Anleitung.

  13. Vielen Dank für Eure ausführliche Beschreibung der Custom Post Types und der Taxonomien. Eine Frage habe ich allerdings: wisst Ihr, welchen Datentyp die Methode get_the_term_list( ) zurückgibt?
    Ist das ein Array, String oder ein Objekt? Ich benötige nur den tatsächlichen Wert meiner angelegten Taxonomie, bekomme aber eine Liste mit Links zurück. Diese würde ich entsprechend meinem Wünschen zerlegen, finde aber keinen Hinweis darauf, was für ein Datentyp da zurückgegeben wird.
    Gruß, Thomas

  14. Hallo,
    meine Frage hat sich erledigt. Die Methode get_the_terms( $post->ID, ‘taxonomy’) liefert einen Array mit den einzelnen Werten und ohn Links. Genau das, was ich brauche. Vielen Dank trotzdem.
    Grüße, Thomas

  15. Mario

    Gerne würde ich die Struktur der Themen in den Links (Adressleiste) abbilden:
    Beispiel:
    domain.tld/
    =Startseite

    dann
    domain.tld/thema/
    =Seite mit Inhalt zum Thema (es gibt 3 Hauptthemen)

    dann
    domain.tld/thema/unterthema/
    =Seite mit Inhalt zum Unterthema (es gibt 5 Unterthemen)

    und schließlich
    domain.tld/thema/unterthema/beitragsname/
    =Beitrag (1,2,3….)

    Wie lässt sich das realisieren (WP 3.6.1 und das wunderschöne Oita-Theme)? Geht das überhaupt?

    Mario

Schreibe eine Antwort