WP_Post – neue Klasse in Wordpress 3.5

Mit Version 3.5 von Wordpress kommt in den nächsten Tagen ein neues Werkzeug für Theme- und Plugin-Entwickler mit: die Klasse WP_Post. Sie bietet lesende Schnittstellen (getter) zu einem Post und zu dessen Meta-Daten, sowie zu dessen Kategorien und Tags.

Immer dort, wo Wordpress ein Post-Objekt an Funktionen oder Hooks als Parameter übergibt, bekam man bisher eine Instanz der PHP-Klasse stdClass übergeben. Diese »leere« Klasse definiert eine Sammlung öffentlicher Eigenschaften, die dynamisch geändert werden können. Im Fall von Wordpress bildet das Objekt die Datenbank-Felder der Tabelle wp_post ab. Beispiel:

# prior Wordpress 3.5
# I know post 1792 exists ;)
$post = get_post( 1792 );
var_dump( $post ); // stdClass

# the raw post title
$title = $post->post_title; 

In Wordpress 3.5 ändert sich daran zunächst nicht viel:

# since Wordpress 3.5
$post = get_post( 1792 );
var_dump( $post ); // instance of WP_Post

# the raw title
$title = $post->post_title;

Zugreiffen auf Post-Metas

WP_Post besitzt die gleichen Eigenschaften wie das anonyme Objekt und ist damit abwärtskompatibel. Der Mehrwert zeigt sich im Zugriff auf die benutzerdefinierten Felder, die Post-Metas. Die Klasse fängt Zugriffe auf nicht definierte Eigenschaften ab und behandelt sie, bis auf vier Ausnahmen, wie potentielle Schlüssel für Post-Metas:

$post_ID = 1792;
# add a post meta
# @link http://codex.wordpress.org/Function_Reference/add_post_meta
add_post_meta( $post_ID, '_my_meta_key', 'Hello World!', TRUE );

# access post meta via WP_Post
$post = get_post( $post_ID );
isset( $post->_my_meta_key ); // TRUE
echo $post->_my_meta_key; // Hello World!

Page-Template und Taxonomien

Die vier erwähnten Ausnahmen sind:

  • post_category
  • tags_input
  • page_template
  • ancestors

Mit den ersten Beiden kann man auf die Kategorien und die Tags eines Posts zugreifen. Das klappt natürlich nur, wenn der Typ des entsprechenden Posts post heißt. Für alle andren, z.B. page erhält man ein leeres Array zurück.

Analog dazu sind Letztere eben nur für Seiten sinnvoll. page_template gibt das ggf. gewählte Template für die Seite zurück und mit ancestors gelangt man an alle übergeordneten (Eltern-)Seiten.

Das ganze birgt einiges an Fehlerpotential. Ich bin generell kein Fan von solchen dynamischen API, die über Interceptors laufen, schon allein weil sie schwer nachvollziehbar sind. Das zeigt sich hier deutlich, wo der Zugriff auf unterschiedliche Datenstrukturen über ein und die selbe »Schnittstelle« läuft. Hinzu kommt die teils inkonsistente Bezeichnung. Wenn man nicht sehr genau aufpasst und z.B. von 'post_category' auf 'post_tag' schließt, bzw. die Slugs der Taxonomien zu Grunde legt (category und post_tag), kann man schnell stolpern. Nach solchen Fehlern sucht man ewig weil die API sich über ein nicht existierende Eigenschaft einfach ausschweigt. Solche »Tippfehler« kann man zum Teil umgehen, wenn man die Post-Meta-Keys z.B. in Konstanten speichert. Vertippt man sich dann beim Namen der Konstante, kommt der Fehler von selbst zu einem.

Instanzieren von WP_Post

Beim Instanzieren neuer WP_Post-Objekte muss man beachten, dass es neben dem Konstruktor auch noch eine statische Methode WP_Post::get_instance() gibt. Der Unterschied liegt im Parameter, den man beiden übergibt. Um aus einer Post-ID ein neues Objekt zu bekommen, geht man über die statische Methode. Will man hingegen aus einem anonymen Post-Objekt, wie man es z.B. von der Datenbank-API bekommt, ein neues WP_Post-Objekt anlegen, nimmt man den Konstruktor, also den new-Operator.

# differnt ways to get a WP_Post object
$post_ID = 1792;

# … by ID
$post = WP_Post::get_instance( $post_ID );

# or by stdClass 
$_post = $GLOBALS[ 'wpdb' ]->get_row( 
	"SELECT * FROM $wpdb->posts WHERE ID = '" . $post_id ."'" 
); // stdClass
$_post = sanitize_post( $_post, 'raw' );

$post = new WP_Post( $post ); // WP_Post

Wenn man von Beginn an sauber arbeitet, dann ist die neue API eine willkommene Hilfe gerade beim Arbeiten mit Post-Metas. Schön wäre noch ein Setter gewesen, der einfach um die Funktion update_post_meta wrappt, dann hätte man sich auch das jonglieren mit der ID in Zukunft sparen können. Für größere Projekte kann man die Klasse WP_Post ja auch einfach erweitern. Kann man nicht, sie ist als finale Klasse nicht erweiterbar. Schade.

Kommentare

Es wurden noch keine Kommentarte zu diesem Artikel geschrieben.

Fragen, Ideen oder Kritik? – Hier ist Platz dafür!

Dein Kommentar

Um ein Kommentar abzugeben, reicht der Text im Kommentarfeld. Die Angabe eines Namens wäre nett, ist aber nicht erforderlich.

Du darfst folgenden HTML-Code verwenden, musst aber nicht:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>