Anderer Ansatz: WordPress ähnliche Artikel durch Statifizierung anzeigen
Nachdem die Datei mit unseren verwandten Artikeln erzeugt ist, wollen wie diese natürlich auch anzeigen lassen. Dafür fügen wir folgendes Schnippsel in die Datei functions.php ein und rufen die Funktion in der Datei single.php mittels bitblokes_show_related() auf.
function bitblokes_show_related() { if (is_file("./related_articles")) { $file_line = file("./related_articles");// Datei einlesen $related_array = unserialize($file_line[0]);// Datei-Inhalt in Array wandeln } $global post; $bb_post_id = $post->ID;// ID des aufgerufenen Artikels abfragen. if (!empty($related_array[$bb_post_id])) { { // Box nur anzeigen, wenn es ein Ergebnis gibt echo "<div id=\"bb_related\">"; echo "<h3>Ähnliche Artikel</h>"; echo "<ul>"; foreach ($related_array[$bb_post_id] as $related_key => $related_value) {// Links erzeugen echo "<li><a href=\"" . $related_value[0] . "\">" . $related_value[1] . "</a> (" . $related_value[2] . ")</li>"; } echo "</ul>"; echo "</div>"; } }
Einziges Problem ist, dass frisch publizierte Artikel keine verwandten Beiträge anzeigen. Das lässt sich aber ändern, indem man noch eine else-Anweisung im Falle eines leeren Ergebnis einbaut. Nachdem wir die Datenbank sowieso bemühen, die können wir das Ergebnis auch gleich in die Datei zurückschreiben. Somit haben wir zumindest, wer mit unserem neuen Artikel verwandt ist (aus Sicht des neuen Artikels). Was wir nicht wissen, ob andere Artikel mit unserem Neuling Ähnlichkeiten aufweisen (aus Sicht der anderen Artikel). Dazu müssen wir das Script erst wieder komplett aufrufen. Bis dahin zeigt WordPress allerdings etwas an, das nicht völlig dem Zufall überlassen ist. Das Script selbst könnten wir in der else-Anweisung auch abfeuern, was wir hier tun, sobald mehr als sechs Stunden vergangen sind. Hier das erweiterte Script. Achtung! Bei großen Installationen kann unsere Lösung aber an der Datenbank nagen.
function bitblokes_show_related() { $check_preview = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; if(!preg_match("/preview=true/",$check_preview)) { // bei Artikel-Vorschau nichts machen include_once("./bb_related_articles.php"); // komplettes Script aufrufen, das ausgeführt wird, x Sekunden (Variable in Script) + Timestamp vergangen sind if (is_file("./related_articles")) { $file_line = file("./related_articles"); // Datei einlesen $related_array = unserialize($file_line[0]); $related_title_plink = unserialize($file_line[1]); } global $post; $bb_post_id = $post->ID; if (!empty($related_array[$bb_post_id])) { // wenn ID bereits in der Cache-Datei ist echo "<div id=\"bb_related\">"; echo "<h3>Ähnliche Artikel</h>"; echo "<ul>"; foreach ($related_array[$bb_post_id] as $related_key => $related_value) { echo "<li><a href=\"" . $related_title_plink[$related_value[0]][1] . "\">" . $related_title_plink[$related_value[0]][0] . "</a> <span class=\"bb_related_brack\">(". $related_value[1] ." Tags)</span></li>"; } echo "</ul>"; echo "</div>"; } else { // wenn ID nicht in der Cache-Datei ist $table_prefix = "wp_"; // wird bei der Installation angegeben, in den meisten Fällen wohl wp_ $related_limit = 5; // Maximale Anzahl der anzuzeigenden Artikel $post_tags = get_the_tags(); $compare_temp = array(); if (!empty($post_tags)) { foreach ($post_tags as $tags) { array_push($compare_temp, $tags->term_id); } } $compare_tags = implode(",",$compare_temp); // String mit Tag-IDs erzeugen, die wir in der DB-Abfrage verwenden if (empty($compare_tags)) { $compare_tags = 0; } $sql = "SELECT p.ID, p.post_title, count(t_r.object_id) as cnt FROM " .$table_prefix. "term_taxonomy t_t," .$table_prefix. "term_relationships t_r, " .$table_prefix. "posts p WHERE t_t.taxonomy ='post_tag' AND t_t.term_taxonomy_id = t_r.term_taxonomy_id AND t_r.object_id = p.ID AND (t_t.term_id IN (" . $compare_tags . ")) AND p.ID != " .$bb_post_id. " AND p.post_status = 'publish' GROUP BY t_r.object_id ORDER BY cnt DESC LIMIT ". $related_limit; $result = mysql_query($sql); echo mysql_error(); $num_rows = mysql_num_rows($result); if (!empty($num_rows)) { echo "<div id=\"bb_related\">"; echo "<h3>Ähnliche Artikel</h>"; echo "<ul>"; $related_new = array(); while ($related_result = mysql_fetch_row($result)) { echo $related_result[3]; $temp_plink = get_permalink($related_result[0]); echo "<li><a href=\"" . $temp_plink . "\">" . $related_result[1] . "</a> <span class=\"bb_related_brack\">(". $related_result[2]." Tags)</span></li>"; array_push($related_new, array($related_result[0], $related_result[2])); $related_title_plink[$related_result[0]] = array($related_result[1], $temp_plink); } echo "</ul>"; echo "</div>"; $sql_check_if_published = "SELECT post_status FROM " .$table_prefix. "posts WHERE ID=" . $bb_post_id ." AND post_status=\"publish\""; // Workaround für Artikel-Vorschau und mehr als zwei Seiten $result = mysql_query($sql_check_if_published); echo mysql_error(); $num_rows_publish = mysql_num_rows($result); if (!empty($num_rows_publish)) { $related_array[$bb_post_id] = $related_new; $related_title_plink[$bb_post_id] = array(get_the_title($bb_post_id),get_permalink($bb_post_id)); $serialized_array = serialize($related_array); // für das Schreiben in die Datei vorbereiten $serialized_title_plink = serialize($related_title_plink); // für das Schreiben in die Datei vorbereiten $filename_temp = "related_temp"; $filename = "related_articles"; $handler = fopen($filename_temp, "w+"); // Temporäre Datei öffnen fwrite($handler, $serialized_array); // Temporäre Datei füllen fwrite($handler, "\r\n"); // Zeilenumbruch fwrite($handler, $serialized_title_plink); // Temporäre Datei füllen fclose($handler); // Temporäre Datei schließen rename($filename_temp, $filename); // Datei umbenennen } } } } }
Nun würde uns natürlich interessieren, ob Ihrer Meinung nach die Idee etwas taugt oder kompletter Schwachsinn ist. Kommentare, Verbesserungsvorschläge und so weiter sind herzlich Willkommen. Und nochmal: Stimmt, der Code ist nicht schön (funktioniert aber – siehe unten), aber um das geht es zunächst nicht. Hier geht es noch mal zum Download.
Hallo Jürgen,
du triffst den Nagel auf den Kopf. GENAU diese Gedanken, zum Thema "wie eine verwandte Posts Abfrage auszusehen hat", hatte ich auch. Da ich allerdings keine Programmierkenntnisse besitze, war ich schon am verzweifeln, und dachte, ich müsste doch so ein blödes standart PlugIn nutzen.
Einzig über die Performance mache ich mir ein wenig sorgen. Ich denke, ich werde es einfach ausprobieren! Vielen Dank!
Also meine Datei, die die verwandten Beiträge enthält ist nun knapp 800 KByte groß. Und das bei über 2100 Beiträgen ... die Performance scheint ok zu sein. Kommt natürlich auch immer auf den Server an, wo das liegt.