Anderer Ansatz: WordPress ähnliche Artikel durch Statifizierung anzeigen

2 Kommentare Autor: Jürgen (jdo)

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.

Seiten: 1 2 3




 Alle Kommentare als Feed abonnieren

2 Kommentare zu “Anderer Ansatz: WordPress ähnliche Artikel durch Statifizierung anzeigen”

  1. Salim says:

    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!

    • jdo says:

      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.