Nachdem wir im ersten Artikel dieser kleinen Serie die Post-Types genauer angesehen haben, die mit WordPress zusammen ausgeliefert werden, wird es Zeit für den nächsten Schritt: das Hinzufügen eigener Post-Types.

Vorbereitungen

Zum Anlegen unseres Custom-Post-Types benötigen wir einige Zeilen PHP-Code. Diese lassen sich entweder in der functions.php-Datei eines Child-Themes oder in Form eines kleinen Plugins für unsere WordPress-Installation bereitstellen.
Die Plugin-Lösung ist definitiv zu bevorzugen, weil wir auf diesem Weg nicht nur Design und Funktion unserer Seite voneinander getrennt halten, sondern auch sicher stellen, dass unser Post-Type unbeeindruckt von Theme-Wechseln weiter seinen Dienst verrichten kann.

Warum Custom-Post-Types?

Diese Frage habe kommt gerne auf, wenn ich das Konzept der Custom-Post-Types erkläre. Mit Seiten oder Beiträgen lassen sich schon sehr komplexe Websites bauen. Wer aber etwas mehr Struktur benötigt, mit einem eigenen Theme (oder Plugin) auf die Darstellung bestimmter Inhalten Einfluss nehmen will oder einen aufgeräumteren Admin-Bereich schätzt, sollte auf Custom-Post-Types zurückgreifen.

Was den Post-Type im Innersten zusammenhält

Stellen wir uns für dieses Beispiel einmal vor, wir wollten auf unserer Website Workshops anbieten. Jeder Workshop soll eine eigene Seite bekommen, auf der Besucher alle Informationen finden können. Zunächst benötigen wir dafür eine Funktion, die in unserem Beispiel kp_workshops() genannt wird. In diese Funktion werden wir nun nach und nach zwei Arrays einfügen, deren Inhalte unseren Workshop-Post-Type definieren.

Im ersten Schritt fügen wir das $args-Array hinzu, dass vorrangig das Verhalten unseres Custom-Post-Types steuert. Jede Zeile in diesem Array liefert WordPress Informationen, die es zur Darstellung und Verwaltung des anzulegenden Post-Types benötigt.

Werfen wir also einen Blick auf den Code:

// Register Custom Post Type - Workshop
function kp_workshops() {

	$args = array(
		'label' =>; __( 'Workshop', 'kp_workshops' ),
		'description' =>; __( 'Workshop listing', 'kp_workshops' ),
		'labels' =>; $labels,
		'supports' =>; array( 'title', 'editor', 'thumbnail', 'comments', 'revisions', 'custom-fields' ),
		'taxonomies' =>; array( 'category' ),
		'hierarchical' =>; false,
		'public' =>; true,
		'show_ui' =>; true,
		'show_in_menu' =>; true,
		'menu_position' =>; 20,
		'menu_icon' =>; 'dashicons-welcome-learn-more',
		'show_in_admin_bar' =>; true,
		'show_in_nav_menus' =>; true,
		'can_export' =>; true,
		'has_archive' =>; true,
		'exclude_from_search' =>; false,
		'publicly_queryable' =>; true,
		'capability_type' =>; 'page',
		'show_in_rest' =>; true,
	);

	register_post_type( 'workshops', $args );

}
add_action( 'init', 'kp_workshops', 0 );Code-Sprache: PHP (php)

Mit label und description geben wir Beschriftungen an, die im Backend verwendet werden. Das ähnlich benannte labels ruft ein weiteres Array auf, dem wir uns im nächsten Schritt widmen werden.

Über supports können wir eine Reihe von Optionen für unseren Custom-Post-Type aktivieren. Hier kommt eine weitere Auflistung in Array-Form zum Einsatz, die theoretisch diese Werte enthalten kann:

'title', 'editor', 'thumbnail', 'comments', 'trackbacks', 'revisions', 'custom-fields', 'page-attributes', 'post-formats'Code-Sprache: PHP (php)

Für unser Beispiel soll der Workshop-Post-Type Titel, den Editor, Beitragsbilder, Kommentare und Revisionen unterstützen.

taxonomies gibt ebenfalls in Form eines Arrays an, mit welchen Taxonomien die Inhalte des Custom-Post-Types gruppiert werden können. Standardmäßig stehen uns hier zwei Taxonomien zu Auswahl – nämlich Kategorien category und Schlagworte post_tags. Bei Bedarf können wir zusätzlich aber auch Custom-Taxonomies anlegen.

Mittels hierarchical können wir festlegen, ob sich unser Custom-Post-Type wie Seiten verhalten soll, die nicht zeitbasiert, sondern aufgrund der Beziehung zueinander sortiert und angezeigt werden – true, oder wie Beiträge, die in umgekehrt chronologischer Reihenfolge dargestellt werden – false.

public bestimmt darüber, ob der Custom-Post-Type in der Admin-Oberfläche zugänglich sein soll. show_ui, show_in_menu, publicly_queryable, exclude_from_search, show_in_nav_menus und show_in_admin_bar haben eine ähnliche Schlagrichtung. Sie alle übernehmen, wenn nicht, wie in unserem Beispiel, gesondert angegeben, den Wert, der für public definiert wurde.

Mit menu_position kann als numerischer Wert die Position des Custom-Post-Types im Admin-Menü festgelegt werden. Mit 5 landet der Eintrag unmittelbar hinter „Beiträge“, mit 20 hinter „Seiten“. In menu_icon können wir ein Icon angegeben, dass im Admin-Menü angezeigt werden soll. Am einfachsten geht das mit den Dashicons, dem Icon-Set, das von WordPress selbst genutzt wird. Die entsprechenden Werte für bestimmte Icons lassen sich in der zugehörigen Dokumentation finden.

Zusätzlich legen wir noch fest, ob der Custom-Post-Type exportiert werden darf – can_export und ob WordPress Archiv-Seiten generieren soll – has_archive.

Mit den letzten beiden Angaben regeln wir, welche Rechte ein User haben muss, um auf den Post-Type zuzugreifen capability_type und ob die Daten des Post-Types in der REST-API auftauchen sollen show_in_rest.

Beschriftungen

Jetzt fehlt uns nur noch das in labels eingebundene Array, bevor wir unseren Custom-Post-Type zum ersten Mal benutzen können.
Mit den Texten, die in diesem Array aufgelisteten sind, werden die Interface-Elemente im WordPress-Backend beschriftet. In der Regel belaufen sich die Anpassungen an diesen Texten auf das Einsetzen des Post-Type Namens, aber auch hier sind umfassendere Veränderungen denkbar.

$labels = array(
	'name' => _x( 'Workshops', 'Post Type General Name', 'kp_workshops' ),
	'singular_name' => _x( 'Workshop', 'Post Type Singular Name', 'kp_workshops' ),
	'menu_name' => __( 'Workshops', 'kp_workshops' ),
	'name_admin_bar' => __( 'Workshops', 'kp_workshops' ),
	'archives' => __( 'Workshop Archives', 'kp_workshops' ),
	'attributes' => __( 'Workshop Attributes', 'kp_workshops' ),
	'parent_item_colon' => __( 'Parent Workshop:', 'kp_workshops' ),
	'all_items' => __( 'All Workshops', 'kp_workshops' ),
	'add_new_item' => __( 'Add New Workshop', 'kp_workshops' ),
	'add_new' => __( 'Add New', 'kp_workshops' ),
	'new_item' => __( 'New Workshop', 'kp_workshops' ),
	'edit_item' => __( 'Edit Workshop', 'kp_workshops' ),
	'update_item' => __( 'Update Workshop', 'kp_workshops' ),
	'view_item' => __( 'View Workshop', 'kp_workshops' ),
	'view_items' => __( 'View Workshops', 'kp_workshops' ),
	'search_items' => __( 'Search Workshop', 'kp_workshops' ),
	'not_found' => __( 'Not found', 'kp_workshops' ),
	'not_found_in_trash' => __( 'Not found in Trash', 'kp_workshops' ),
	'featured_image' => __( 'Workshop Image', 'kp_workshops' ),
	'set_featured_image' => __( 'Set workshop image', 'kp_workshops' ),
	'remove_featured_image' => __( 'Remove workshop image', 'kp_workshops' ),
	'use_featured_image' => __( 'Use as workshop image', 'kp_workshops' ),
	'insert_into_item' => __( 'Insert into Workshop', 'kp_workshops' ),
	'uploaded_to_this_item' => __( 'Uploaded to this Workshop', 'kp_workshops' ),
	'items_list' => __( 'Workshops list', 'kp_workshops' ),
	'items_list_navigation' => __( 'Workshops list navigation', 'kp_workshops' ),
	'filter_items_list' => __( 'Filter Workshops list', 'kp_workshops' ),
);Code-Sprache: PHP (php)

Nachdem wir auch dieses Array in unsere kp_workshops()-Funktion gepackt haben, können wir den Custom-Post-Type mit einem Aufruf von register_post_type() registrieren.

Den gesamten Code dieses kleinen Beispiels habe ich auf Github zum Download bereitgestellt.