Individuelle Terminliste unter WordPress mit MR Event

 9. Februar 2012

Achtung. Das MR Event Kalender-Plugin wird nicht mehr weiterentwickelt. Stattdessen setze ich nun das Plugin Very Simple Event List ein, dass sich mit Widgets und anpassbaren Templates relativ leicht individualisieren lässt.

Mit schöner Regelmäßigkeit taucht die Frage nach einer Terminliste auf, die in WordPress eingepflegt und innerhalb des Templates sortiert ausgegeben werden soll. Diese Anforderung kommt öfter vor, als man denkt und die Realisierung scheint anfangs vertrackt. Ist es aber nicht, wenn man sich an eine eigene Loop-Abfrage traut und ein simples PlugIn installiert. Mit einem zweiten wird sogar die Ausgabe einer Zeitspanne möglich.

SCHRITT 1 – DAS ERSTE PLUGIN
Zuallererst benötigt man
das Plugin «MR Event» (Link am Ende des Artikels). Nach der Installation im PlugIn-Ordner und der anschließenden Aktivierung erscheint im Backend bei jedem neu zu erstellenden Artikel die Übersicht «MR Event». Neben Tag, Monat und Jahr lässt sich auch die Zeit eintragen (in 5-Minuten-Intervallen). Das Plugin legt nach dem Speichern des Artikel ein benutzerdefiniertes Feld an, welches das Datum als generierten Zeitstempel beinhaltet. Dieser zehnstellige Zahlenwert erscheint obskur, ist aber nichts anderes, als die Anzahl der Sekunden, die vom 1.1.1970, 0.00 Uhr bis zum eingegebenen Datum vergangenen sind. Dieser Aspekt wird später noch wichtig.

SCHRITT 2 – DAS AUSLESEN DER DATEN IM LOOP
Jetzt haben wir dem Artikel
also erstmal ein Datum verpasst. Jetzt geht es an die Ausgabe im Template. Hierbei sollen alle mit solch einem Zeitstempel versehenen Artikel aufsteigend nach Datum sortiert werden. Die have_post()-Schleife taugt dazu nichts, da sie nur fixe Werte wie Kategorie, Autor etc. als Kriteritum hinzuziehen kann. Auch die eigene MR-Event-Loop-Funktion gibt alles nur in grober Listenform aus. Da wir alles individuell gestalten wollen, basteln wir uns einfach eine eigene Abfrage:

<!-- BEGINN DES LOOPS -->
<?php
$querystr = "SELECT * FROM $wpdb->posts
    LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id)
    LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
        LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
        WHERE $wpdb->term_taxonomy.term_id = 4
        AND $wpdb->term_taxonomy.taxonomy = 'category'
        AND $wpdb->posts.post_status = 'publish'
        AND $wpdb->postmeta.meta_key = 'mr_event'
        ORDER BY $wpdb->postmeta.meta_value ASC";
    $posts = $wpdb->get_results($querystr);
foreach ($posts as $post): setup_postdata($post);?>
<?php endforeach; ?>
<!-- ENDE DES LOOPS -->

Wichtig sind die vier Zeilen die mit WHERE bzw. AND beginnen.
Die bestimmen nämlich die Sortierkriterien, welche die verfügbaren Artikel eingrenzt:

term_taxonomy.taxonomy
bestimmt, dass nur Artikel in einer bestimmten Kategorie sortiert werden sollen.

term_taxonomy.term_id
sagt dann an, welche das sein soll. Hier als Beispiel die Kategorie Nummer 4. Die ID der gewünschten Kategorie findet man übrigens leicht heraus, indem man im Backend unter Artikel>Kategorien die betreffende Kategorie anklickt und die URL-Adresszeile des Browsers bei der neu geöffneten Seite untersucht. Die Zahl hinter tag_ID= ist die gesuchte ID.

posts.post_status
legt fest, dass nur Artikel gezeigt werden, die auch schon veröffentlicht worden sind.

postmeta.meta_value
legt die Sortierreihenfolge fest. In dem Fall ASC für Ascending. Also aufsteigend.

postmeta.meta_key
ist nun der Dreh- und Angelpunkt unserer Abfrage. Hier wird die Sortierung noch weiter eingekreist und bestimmt, dass die Artikel nach dem Inhalt des benutzerdefiniertes Feldes «mr_event» sortiert werden sollen.

Der eigene Loop ist fertig. Jetzt muss nur noch der Artikel ausgelesen werden. Das funktioniert mit den üblichen Loop-Tags wie the_content(), the_title() usw. Die letzte Hürde ist dann die Ausgabe des Datums und erfordert ein paar kleine Zeilen PHP-Code:

<?php if($mr_event_meta = get_post_meta($post->ID, 'mr_event', true))
     {
     echo date('j.n.Y | G:i', $mr_event_meta); echo " Uhr";
     } ?>

Das Script fragt zuerst ab, ob überhaupt ein benutzerdefiniertes Feld namens «mr_event» existiert. Ist das der Fall, kann man es nicht einfach auslesen und anzeigen, denn es liegt ja noch als zehnstelliger Zeitstempel vor. Also wird das Datum einfach mit echo.date() ausgegeben. Damit auch das richtige Datum angezeigt wird (und nicht wohlmöglich das gerade aktuelle), sorgt die Variable $mr_event_meta dafür, dass der Wert aus dem benutzerdefinierten Feld genutzt wird.

Der komplette Code sieht damit so aus, wobei der Eigengestaltung durch Tags und CSS-Attribute natürlich keine Grenzen gesetzt sind:

<!-- BEGINN DES LOOPS -->
<?php
$querystr = "SELECT * FROM $wpdb->posts
    LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id)
    LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
        LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
        WHERE $wpdb->term_taxonomy.term_id = 4
        AND $wpdb->term_taxonomy.taxonomy = 'category'
        AND $wpdb->posts.post_status = 'publish'
        AND $wpdb->postmeta.meta_key = 'mr_event'
        ORDER BY $wpdb->postmeta.meta_value ASC";
    $posts = $wpdb->get_results($querystr);
foreach ($posts as $post): setup_postdata($post);?>

<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<h2><?php if($mr_event_meta = get_post_meta($post->ID, 'mr_event', true))
     {
     echo date('j.n.Y | G:i', $mr_event_meta); echo " Uhr";
     } ?></h2>
<p><?php the_content(); ?></p>

<?php endforeach; ?>
<!-- ENDE DES LOOPS -->

SCHRITT 3 – NOCH EIN PLUGIN
Einen Haken hat das Script aber noch. Daten, die bereits abgelaufen sind, werden trotzdem angezeigt. Das ist sehr oft gewünscht, da sich viele Gäste noch über abgelaufene Veranstaltungen informieren wollen. Hier hilft es, den Artikel zum gewünschten Zeitpunkt im Backend von Hand zu löschen oder in eine andere Kategorie zu verschieben.

Für den höchsten Grad an Bequemlichkeit ist dafür natürlich auch ein PlugIn erhältlich. «Post Expirator» erlaubt es, Artikel mit einem individuellen Ablaufdatum zu versehen. Das PlugIn bietet an, den Artikel nach Ablauf zu löschen oder dessen Veröffentlichungsstatus auf Entwurf zu setzen.

Das PlugIn bietet zudem die Möglichkeit, das Ablaufdatum in das Theme einzugliedern, da es den eingegebenen Zeitpunkt, so wie MR Event, in einem benutzerdefinierten Feld ablegt. Die Abfrage ist dann natürlich identisch:

<?php if($expiration_meta = get_post_meta($post->ID, 'expiration-date', true))
     {
     echo date('j.n.Y | G:i', $expiration_meta); echo " Uhr";
     } ?>

Beide PlugIn gemeinsam lassen natürlich viel Spielerei zu und dank der Eingrenzung in verschiedene Kategorien, sind pro Web-Seite dann auch mehrere Terminlisten zu unterschiedlichen Themen möglich.

>>> Post Expirator Plugin