WordPress: Spalten im Adminbereich mit PHP hinzufügen

Kevin
Kevin

11. Feb, 2022 | 5 Min. Lesezeit

Es gibt zahlreiche Plugins, die es dir ermöglichen, eigene Spalten im WordPress-Admin anzulegen. Das tolle daran ist, dass du hier keine großen Programmierkenntnisse benötigst, ähnlich wie mit ACF (Advanced Custom Fields). Da uns das aber zu einfach wäre, geht es hier heute darum, wie du deine eigenen Spalten mit PHP erstellst. Viel Spaß!

In unserem Beispiel geht es darum, dass wir ein Metafeld „Sponsored“ als Spalte in der Übersicht unserer Beiträge haben wollen. Das Metafeld wird von uns verwendet, um unseren eigenen Beiträge von gesponserten Beiträgen zu unterscheiden.

Das Metafeld heißt hier: sponsored

Es gibt immer ein true, oder false zurück. Dies lässt sich auch gut mit ACF und der Wahr/Falsch-Feldart umsetzen und wird auch in unserem Beispiel so gemacht. Deshalb rufen wir unser Metafeld folgendermaßen ab:

get_field( 'sponsored' );

Sprunkmarken

Name der Spalte festlegen

Damit unsere Spalten auch angezeigt werden, müssen wir ihnen erst einmal einen Namen geben. Dafür registrieren wir die Spalten mit dem Filter manage_{post_type}_posts_columns:

/**
 * Registriert die neue Spalte, direkt nach der "Titel"-Spalte.
 *
 * @param array $defaults Die bisherigen Spalten.
 *
 * @return array
 */
function jl_register_columns( $defaults ) {
	$columns = array();

	foreach ( $defaults as $key => $value ) :
		$columns[ $key ] = $value;

		/**
		 * Eine Spalte direkt nach der Spalte Titel
		 */
		if ( 'title' === $key ) {
			/* Die neue Spalte: key = id, value = Name */
			$columns['sponsored'] = 'Gesponsert';
		}
	endforeach;

	/* Wir übergeben unseren neuen Array */
	return $columns;
}

Inhalt der Spalte festlegen

Deine Spalte sollte schon zu sehen sein. Leider bringt uns das noch nicht so viel, da wir noch keinen Inhalt festgelegt haben. Das können wir mit der Action manage_{post_type}_posts_custom_column:

/**
 * Bestimmt den Inhalt der neuen Spalte.
 *
 * @param string $column_name Name der Spalte.
 * @param int    $post_id ID des Beitrags.
 */
function jl_populate_columns( $column_name, $post_id ) {

	/* Wenn die Spalte "sponsored" durchlaufen wird */
	if ( 'sponsored' === $column_name ) {

		/* Beispiel mit get_field */
		if ( get_field( 'sponsored', $post_id, true ) ) {
			echo 'Gesponsert';
		} else {
			echo '-';
		}
	}
}

Sortierung der Spalte

Jetzt wird eigentlich schon alles gemacht, was wir wollten. Wie wäre es jetzt, wenn wir unsere Beiträge sortieren könnten. Also das dann bspw. die gesponsorten Beiträge zuerst gezeigt werden. Dafür nutzen wir den Filter manage_edit-{post_type}_sortable_columns:

/**
 * Registriert die sortierbare neue Spalte.
 *
 * @param array $columns Aktuelle Spalten.
 *
 * @return array
 */
function jl_register_sortable_columns( $columns ) {
	$columns['sponsored'] = 'sponsored';

	return $columns;
}

Jetzt werden zumindest schon einmal die Spaltennamen anklickbar, aber es passiert noch nichts. Damit auch was passiert, müssen wir den globalen WP_Query in unserer Beitragsübersicht manipulieren. Wenn du auf eine Spalt klickst, wirst du bemerken, dass sich die URL ändert. Dort wird nämlich ein Parameter orderby mit dem Inhalt sponsored angehängt. Das können wir nutzen, um unseren WP_Query zu manipulieren.

Einen WP_Query manipulieren wir grundsätzlich mit der Action pre_get_posts. Wichtig ist, dass du innerhalb der Action angibst, dass es sich um den Adminbereich handelt, da sonst jeder WP_Query betroffen ist.

Mit pre_get_posts lassen sich WP_Query manipulieren. Mit is_admin sorgen wir dafür, dass er auch nur im Adminbereich manipuliert wird.

/**
 * Bestimmt wie die Inhalte sortiert werden sollen, wenn man auf die Spalte klickt.
 *
 * @param WP_Query $wp_query Globaler WP_Query.
 */
function jl_sort_columns_query( $wp_query ) {
	if ( ! is_admin() ) {
		return;
	}

	$orderby = $wp_query->get( 'orderby' );

	if ( 'sponsored' === $orderby ) {
		$meta_query   = array( 'relation' => 'OR' );
		$meta_query[] = array( 'key' => 'sponsored' );

		$wp_query->set( 'meta_query', $meta_query );
		$wp_query->set( 'orderby', 'meta_value' );
	}
}

Finale Initialisierung

Damit jetzt alles funktioniert, müssen wir alles noch initialisieren. Dafür nutzen wir die Action admin_init und legen hier unsere Filter und Actions ab:

/**
 * Initialisiert die neue Spalte.
 *
 * @global $pagenow, $post
 */
function jl_init_columns() {
	global $pagenow, $post;

	if ( is_admin() && 'edit.php' === $pagenow ) {
		add_filter( 'manage_post_posts_columns', 'jl_register_columns' );
		add_action( 'manage_post_posts_custom_column', 'jl_populate_columns', 10, 2 );
		add_filter( 'manage_edit-post_sortable_columns', 'jl_register_sortable_columns' );
		add_action( 'pre_get_posts', 'jl_sort_columns_query' );
	}
}

add_action( 'admin_init', 'jl_init_columns' );

Zusammenfassung

Jetzt haben wir eine eigene Spalte, inklusive Sortierung gebastelt. Sehr cool! Damit du nicht alles selbst zusammensetzen musst, findest du hier den gesamten Code. Viel Spaß damit!

/**
 * Registriert die neue Spalte, direkt nach der "Titel"-Spalte.
 *
 * @param array $defaults Die bisherigen Spalten.
 *
 * @return array
 */
function jl_register_columns( $defaults ) {
	$columns = array();

	foreach ( $defaults as $key => $value ) :
		$columns[ $key ] = $value;

		/**
		 * Eine Spalte direkt nach der Spalte Titel
		 */
		if ( 'title' === $key ) {
			/* Die neue Spalte: key = id, value = Name */
			$columns['sponsored'] = 'Gesponsert';
		}
	endforeach;

	/* Wir übergeben unseren neuen Array */
	return $columns;
}

/**
 * Bestimmt den Inhalt der neuen Spalte.
 *
 * @param string $column_name Name der Spalte.
 * @param int    $post_id ID des Beitrags.
 */
function jl_populate_columns( $column_name, $post_id ) {

	/* Wenn die Spalte "sponsored" durchlaufen wird */
	if ( 'sponsored' === $column_name ) {

		/* Beispiel mit get_field */
		if ( get_field( 'sponsored', $post_id, true ) ) {
			echo 'Gesponsert';
		} else {
			echo '-';
		}
	}
}
/**
 * Registriert die sortierbare neue Spalte.
 *
 * @param array $columns Aktuelle Spalten.
 *
 * @return array
 */
function jl_register_sortable_columns( $columns ) {
	$columns['sponsored'] = 'sponsored';

	return $columns;
}

/**
 * Bestimmt wie die Inhalte sortiert werden sollen, wenn man auf die Spalte klickt.
 *
 * @param WP_Query $wp_query Globaler WP_Query.
 */
function jl_sort_columns_query( $wp_query ) {
	if ( ! is_admin() ) {
		return;
	}

	$orderby = $wp_query->get( 'orderby' );

	if ( 'sponsored' === $orderby ) {
		$meta_query   = array( 'relation' => 'OR' );
		$meta_query[] = array( 'key' => 'sponsored' );

		$wp_query->set( 'meta_query', $meta_query );
		$wp_query->set( 'orderby', 'meta_value' );
	}
}

/**
 * Initialisiert die neue Spalte.
 *
 * @global $pagenow, $post
 */
function jl_init_columns() {
	global $pagenow, $post;

	if ( is_admin() && 'edit.php' === $pagenow ) {
		add_filter( 'manage_post_posts_columns', 'jl_register_columns' );
		add_action( 'manage_post_posts_custom_column', 'jl_populate_columns', 10, 2 );
		add_filter( 'manage_edit-post_sortable_columns', 'jl_register_sortable_columns' );
		add_action( 'pre_get_posts', 'jl_sort_columns_query' );
	}
}

add_action( 'admin_init', 'jl_init_columns' );

PHP-Klasse

Falls du nicht so gerne mit Funktionen arbeitest, gibt es das Ganze auch einmal als PHP-Klasse, die du dir so kopieren kannst:

/**
 * Eine Klasse zum Hinzufügen eine Sponsored Adminspalte, in der Beitragsübersicht.
 *
 * @package JulianLang
 * @subpackage Tutorial\AdminSpalten
 */

if ( class_exists( 'SponsoredAdminColumn' ) ) {
	new SponsoredAdminColumn();
}

/**
 * ...
 */
class SponsoredAdminColumn {
	/**
	 * Konstruktor, der immer aufgerufen wird, wenn man die Klasse initialisiert.
	 */
	public function __construct() {
		add_action( 'admin_init', array( & $this, 'init_columns' ) );
	}

	/**
	 * Initialisiert die neue Spalte.
	 *
	 * @global $pagenow, $post
	 */
	public function init_columns() {
		global $pagenow, $post;

		if ( is_admin() && 'edit.php' === $pagenow ) {
			add_filter( 'manage_post_posts_columns', array( & $this, 'register_columns' ) );
			add_action( 'manage_post_posts_custom_column', array( & $this, 'populate_columns' ), 10, 2 );
			add_filter( 'manage_edit-post_sortable_columns', array( & $this, 'register_sortable_columns' ) );
			add_action( 'pre_get_posts', array( & $this, 'sort_columns_query' ) );
		}
	}

	/**
	 * Registriert die neue Spalte, direkt nach der "Titel"-Spalte.
	 *
	 * @param array $defaults Die bisherigen Spalten.
	 *
	 * @return array
	 */
	public function register_columns( $defaults ) {
		$columns = array();

		foreach ( $defaults as $key => $value ) :
			$columns[ $key ] = $value;

			/**
			 * Eine Spalte direkt nach der Spalte Titel
			 */
			if ( 'title' === $key ) {
				/* Die neue Spalte: key = id, value = Name */
				$columns['sponsored'] = 'Gesponsert';
			}
		endforeach;

		/* Wir übergeben unseren neuen Array */
		return $columns;
	}

	/**
	 * Bestimmt den Inhalt der neuen Spalte.
	 *
	 * @param string $column_name Name der Spalte.
	 * @param int    $post_id ID des Beitrags.
	 */
	public function populate_columns( $column_name, $post_id ) {

		/* Wenn die Spalte "sponsored" durchlaufen wird */
		if ( 'sponsored' === $column_name ) {

			/* Beispiel mit get_field */
			if ( get_field( 'sponsored', $post_id, true ) ) {
				echo 'Gesponsert';
			} else {
				echo '-';
			}
		}
	}

	/**
	 * Registriert die sortierbare neue Spalte.
	 *
	 * @param array $columns Aktuelle Spalten.
	 *
	 * @return array
	 */
	public function register_sortable_columns( $columns ) {
		$columns['sponsored'] = 'sponsored';

		return $columns;
	}

	/**
	 * Bestimmt wie die Inhalte sortiert werden sollen, wenn man auf die Spalte klickt.
	 *
	 * @param WP_Query $wp_query Globaler WP_Query.
	 */
	public function sort_columns_query( $wp_query ) {
		if ( ! is_admin() ) {
			return;
		}

		$orderby = $wp_query->get( 'orderby' );

		if ( 'sponsored' === $orderby ) {
			$meta_query   = array( 'relation' => 'OR' );
			$meta_query[] = array( 'key' => 'sponsored' );

			$wp_query->set( 'meta_query', $meta_query );
			$wp_query->set( 'orderby', 'meta_value' );
		}
	}
}

Links zum Thema

geschrieben von

Autor Avatar
Kevin

Im Kindergarten war Kevin in der Bastelgruppe, weshalb er auch heute noch gerne bastelt. Er bastelt hier für dich an und mit WordPress, kommentiert aber auch gerne die Arbeit anderer Bastler.

© 2015 - 2022 | Julian Lang Webentwickler | WordPress Entwickler | Webdesigner in Bayreuth und Umgebung