Sidebar
ein-/ausblenden

Duplikate im Loop von WordPress filtern

Plugin für WordPress SEO

Anzeige

Die Loop in den Templates des Theme in WordPress ist das Herz einer jeden Ausgabe. Mit zunehmenden Anforderungen wird die Aufgabe an den Entwickler aufwendiger und das Default-Theme von WordPress hilft nicht weiter als Vorlage.
Nicht selten muss daher mit klassichen PHP-Möglichkeiten im Template die Umsetzung realisiert werden, denn es gibt dafür keine eigene Funktion oder Template Tag, wie einige Nutzer meinen. Da die Frage recht oft auftaucht und man in dem Fall eine Lösung aufzeigen kann, möchte ich mal darstellen, wie ich dafür sorge, dass Inhalte, die in einem Loop ausgegeben wurden, nicht in einem weiteren Loop nochmal dargestellt werden.

WordPress identifiziert Beiträge und Seiten eindeutig via ID, die in der Datenbank angelegt sind und die auch bei der Ausgabe in der Loop eine entscheidende Rolle spielen. Alle Zuordnungen oder Verknüpfungen basieren auf der ID. Daher speichere ich im ersten Loop (Loop Nr.1) die IDs, die ausgeben werden, in einem Array. Diese Variable wurde im Vorfeld als Array bestimmt $do_not_duplicate = array();.

Loop Nr.1


<?php
$do_not_duplicate = array(); // vor den Loops Variable als Array setzen  

// 1. Loop
query_posts('ca=1,2,3&showposts=5');
while ( have_posts() ) : the_post();
    $do_not_duplicate[] = $post->ID; // IDs im Loop merken
    // Post ausgeben ...
    the_title();
endwhile;
?>

Nach dem nun durch die obige Loop 5 Artikel ausgegeben wurden, haben wir im Array 5 IDs, mit denen wir nun arbeiten können. Im Übrigen kann man sich das Array mit der PHP-Funktion var_dump() anschauen.

In der kommenden Loop Nr.2 sollen nun 15 Beiträge ausgegeben werden, wobei die schon aus Loop Nr. 1 bekannten IDs nicht nochmal erscheinen sollen. Dies könnte sein, wenn Beiträge mehreren Kategorien zugeordnet sind, da beide Loops unterschiedliche Kategorien ausgeben. Ich prüfe nun mit der Funktion in_array(), ob die aktuelle ID $post->ID im Array $do_not_duplicate vorhanden ist. Nur wenn die ID nicht ( !in_array() ) im Array vorhanden, dann wird im Loop Nr. 2 Inhalt ausgegeben.

Loop Nr.2


<?php
// 2. Loop
query_posts( 'cat=4,5,6&showposts=15' );
while (have_posts()) : the_post();
    if ( !in_array( $post->ID, $do_not_duplicate ) ) { // IDs prüfen
        // Post ausgeben ...
        the_title();
    }
endwhile;
?>

Wie so oft, gibt es eine Alternative und dazu stellt WordPress einen Parameter im Query bereit - post__not_in, siehe Codex. Auch diesem Parameter übergebe ich alternativ den Array und in diesem Query sind dann die IDs nicht enthalten. Je nach dem, welchen Weg man geht, stehen damit zwei unterschiedliche Syntax bereit, um doppelten Content zu vermeiden.


<?php
// weiterer Loop ohne Duplikat
query_posts( array(
    'cat' => 456,
    'post__not_in' => $do_not_duplicate
    )
);
while ( have_posts() ) : the_post();
    // Post ausgeben ...
        the_title();
endwhile;
?>

10 Kommentare zu „Duplikate im Loop von WordPress filtern“

  1. 1
    Kommentar von Michael Oeser

    Schön erklärt und gut umsetzbar. Ich verwende diese Variante bereits seit längerem auf meinem Blog http://www.der-prinz.com. Interessant wäre nun noch eine Lösung, die in nur EINEM Loop Duplikate vermeidet.

    Beispiel: Wenn ein Beitrag in Kategorie 1 und in Kategorie 2 abgelegt ist und die jeweils drei aktuellsten Beiträge beider Kategorien im Loop ausgegeben werden, soll der Beitrag aber nur einmal angezeigt werden.

  2. 2
    Kommentar von Markus

    Guter Artikel. Hab diese Lösung genau so auch schon lange im Einsatz Gerade wenn man WP mehr als CMS einsetzt kommt man ohne diese Lösung fast nicht mehr aus.

  3. 3
    Kommentar von David Hellmann

    Danke Frank, nachdem ich ihn schon so damit genervt habe :)
    Hab das bei mir nun auch im Einsatz auf der Startseite: http://www.davidhellmann.com und es klappt wunderbar!!

  4. 4
    Kommentar von Steffen

    Sollte man vielleicht erwähnen, in Variante 1 von Loop2 erscheinen eben gerade nicht die gewünschten 15 Postings, wenn es tatsächlich doppelten Content rauszufiltern gibt. Richtig?
    Von daher wäre die Variante 2 von Loop2 ja eh vorzuziehen.
    Kann man nicht sogar sagen, dass nur Variante 2 das eigentlich WP-Bordmittel nutzt, da Variante 1 einfach nur ein Argument, welches die Funktion query_posts() mitbringt, nicht nutzt?

  5. 5
    Kommentar von Frank Bültge

    Die Variante 2 nutzt einen Parameter, während Loop Nr. 2 der Variante 1 das Filtern via PHP-Bordmitteln tut. Besser ist Variante 2, da es dann auch 15 Beiträge sind, wenn es die IDs im Array gibt. Ansonsten kann es sein, dass nur ein Teil der Artikel kommt, es wird der Loop nicht erweitert.

  6. 6
    Kommentar von Mark

    Den post_not_in - Parameter kannte ich noch nicht. Sehr praktisch. Ich finde auch, dass damit die zweite Variante noch etwas besser ist.

  7. 7
    Kommentar von Nick

    Hallo Frank,

    danke für den schönen Tipp.
    Ich baue mir grade ein Magazin-Theme worin ich diese Funktion super einbauen kann.

    Leider klappt dies aber nicht ganz so wie ich das will, deshalb brauche ich deinen Rat.

    Ich gebe auf meiner Startseite 5 Kategorien aus.
    In den Kategorien befinden sich jeweils 3 Artikel (1Großer, 2 Kleine) und eine Liste.
    Insgesammt sollen die letzten 10 News ausgegeben werden (die 3 Artikel und die restlichen 7 sollen als Liste dargestellt werden.).

    Soweit so gut.
    Ich habe es hin bekommen das er mir die ersten 3 Artikel ausgibt, in der Liste aber zeigt er mir wieder alle Artikel bis auf den Aktuellsten an (also Dublikate).

    Eigentlich ist es auch Logisch da er sich ja nur auf die eine ID des ersten Beitrages bezieht.
    Da ich aber pro Beitrag einen Loop habe müsste man das ganze in ein extra Array abspeichern, leider habe ich keine Ahnung wie das gehen soll.

    Vllt. kannst du mir da weiterhelfen.
    Meinen Code würde ich dir gern Parallel per Mail rüberschicken + ein Screenshoot für ein besseres optisches Verständnis.

    Danke!

  8. 8
    Kommentar von Frank Bültge

    @Nick: Die ID des Post speichere ich in $do_not_duplicate[] = $post->ID;, also hat diese Variable alle IDs drin, die nun im Loop ausgegeben werden. Daher muss nun im jeweiligen Loop geprüft werden, ob die ID da schon drin ist, wenn ja, dann keine Ausgabe if ( !in_array( $post->ID, $do_not_duplicate ) ) {. Eventuell lohnt es, vor jedem Loop den Query zu reseten, immer nach der Loop(endwhile): endwhile; wp_reset_query();

  9. 9
    Kommentar von Stefan

    Hallo Frank,

    danke für diesen ausführlichen Artikel.

    Aber besteht auch die Möglichkeit in einem Loop eines Seiten-Templates, Artikel und eine Seite auszugeben?

    Bspl.:

    get header

    maincol - Hier soll eine seite ausgegeben werden
    php ??????? ?

    artikel - Hier sollen Artikel ausgegeben werden
    php if (have_posts()) : while (have_posts()) : the_post();

    get sidebar
    get footer

    Hoffe Du kannst mir den helfenden Tipp geben.

    Danke. VG Stefan

  10. 10
    Kommentar von Frank Bültge

    @Stefan: ja sicher, man kann auch da eigene Loops aufbauen. Im Grunde kann man das beliebig oft machen; aber bitte die Performance nicht außer acht lassen. Alternativ arbeite mit dem WP_Query

Kommentar schreiben

Kommentarregeln: Bleib cool, kritisch ist in Ordnung, aber wenn du unhöflich bist, dann lösche ich deinen Kommentar. Bitte benutze deinen persönlichen Namen oder Initialen und nicht den Namen eines Unternehmens, dies würde als Spam gewertet und wird gelöscht. Der Zusammenhang zwischen Namen und URL sollte nicht offensichtlich auf Spam hindeuten! ♥ Ansonsten, vielen Dank für den Kommentar und viel Spaß mit meinem Blog.

E-Mail-Benachrichtigung bei weiteren Kommentaren.
Auch möglich: Abo ohne Kommentar.

Kommentar-Hilfe

händischer Spam:
Beachte die Kommentarregeln, jede Form von versuchtem Spam wird gelöscht. Warum und wieso steht in einem meiner Beiträge.

Bezug auf Textstellen:
Du kannst direkt bezug auf Textstellen im Beitrag nehmen. Dazu muss lediglich der Bereich im Artikel markiert werden; daraufhin erscheint ein Button, der den markierten Text in das Kommentarfeld übernimmt und als Zitat auszeichnet. Die Funktion ist nur bei aktivem JavaScript nutzbar.

xHTML:
Du kannst folgende Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <blockquote cite=""> <code> <pre> <em> <strong> <strike> <ul> <ul> <li>

Achte darauf, wenn du Code im Kommentar hinterlegen willst, dann muss der Code maskiert sein. Dann wird er nicht interpretiert. Der Code muss mit Hilfe von HTML-Entities dargestellt werden, d.h. dass man z.B. < als &lt; und > als &gt; einfügt.

E-Mail-Benachrichtigung bei neuen Kommentaren ?
Wenn der Haken in der Checkbox gesetzt ist, dann wirst du über neue Kommentare vie E-Mail informiert. Der Versand erfolgt nur, wenn du die URL in der Bestätigungs-E-Mail genutzt hast oder schon Abonnent hier im Blog bist.

Kommentar erscheint nicht:
Alle Kommentare werden manuell geprüft, freigegeben und nach Möglichkeit beantwortet. Bitte um etwas Geduld und Nachsicht.

Identifikationsbilder (Avatare):
Auf Gravatar.com kann man sich mit seiner E-Mail-Adresse registrieren und ein Bild hochladen, dann erscheint dieses Gravatar hier und in vielen weiteren Blogs.

Spamschutz:
Das Kommentarformular ist mit einem Spamschutz ausgerüstet. Solltest du diesen Artikel ohne JavaScript besuchen und kommentieren wollen, so muss du die Frage beantworten und das jeweilige Wort in das Textfeld eingeben.