Behandlung depublizierter Artikel in WordPress

Vor kurzen wurde ich vor eine spannende Aufgabe gestellt: Eine Seite musste eine ganze Menge alter Artikel depublizieren. Die Besucher dieser Artikel sollten jedoch nicht einfach von einer 404-Fehlerseite abgefangen werden, sondern ihnen sollte mitgeteilt werden, weshalb der Fehler aufgetreten ist und sie sollten - möglichst automatisch - auf die Startseite umgelenkt werden.

Dabei gab es mehrere Hindernisse: Zum einen musste eine Datenbasis geschaffen werden, welche URLs nicht mehr verfügbar sind und es musste bei deren Aufruf der entsprechend angepasste Inhalt angezeigt werden. Anstatt jedoch anzufangen, die gesamte Seite abzugrasen, um an die URLs zu gelangen, hatte ich eine bessere Idee: Die Artikeldatenbank selbst würde diese Datenbasis darstellen.

Um die Artikel offline zu nehmen, sollten diese nicht gelöscht, sondern lediglich deren Sichtbarkeit auf "privat" gestellt werden. Damit könnte man eine generalisierte Lösung erstellen, die für alle privaten Artikelseiten funktioniert. Das gute: Private Artikel führen bei externen Besuchern zu einer 404-Seite. Der Inhalt der 404-Seite wird durch die Datei "404.php" des Themes repräsentiert. Dort könnte man sich einklinken und vor dem Anzeigen des Fehlers prüfen, ob der Fehler aufgetreten ist, weil der Artikel nicht existiert oder weil er privat ist. Je nach Ergebnis könnte man dann den einen oder den anderen Inhalt anzeigen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php
  $private_404_args    = wp_parse_args($wp->matched_query);
  $private_404_content = "";
  $private_404_done    = false;
  $private_404_result  = 0;

  if (isset($private_404_args["p"]) || isset($private_404_args["name"])) {

    if ((!$private_404_done) && isset($private_404_args["p"])) {
      $private_404_result = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $wpdb->posts WHERE id = %d AND LOWER(post_status) = 'private' AND LOWER(post_type) = 'post';"), intval($private_404_args["p"]));

      $private_404_done = (intval($private_404_result) === 1);
    }

    if ((!$private_404_done) && isset($private_404_args["name"])) {
      $private_404_result = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $wpdb->posts WHERE LOWER(post_name) = LOWER(%s) AND LOWER(post_status) = 'private' AND LOWER(post_type) = 'post';", $private_404_args["name"]));

      $private_404_done = (intval($private_404_result) === 1);
    }

  }

  if ($private_404_done) {
    $private_404_content = $wpdb->get_var("SELECT post_content FROM $wpdb->posts WHERE LOWER(post_title) = '[410]' AND LOWER(post_status) = 'private' AND LOWER(post_type) = 'page';");

    if ($private_404_content != null) {
      print(apply_filters('the_content', $private_404_content));
    }
  } else {
    $private_404_content = $wpdb->get_var("SELECT post_content FROM $wpdb->posts WHERE LOWER(post_title) = '[404]' AND LOWER(post_status) = 'private' AND LOWER(post_type) = 'page';");

    if ($private_404_content != null) {
      print(apply_filters('the_content', $private_404_content));
    }
  }
?>

Die schlussendliche Lösung ist etwas komplizierter geworden. Eigentlich hatte ich vor, einfach per "url_to_postid()" herauszufinden, ob unter der URL, die aufgerufen wurde, ein Artikel existiert. Leider funktioniert die Funktion offenbar nicht bei privaten Artikeln, wenn sie von außen aufgerufen wurden.

Im Feld "$wp->matched_query" stehen glücklicherweise die Teile der erfolgreichen erkannten URL-Teile, wie sie die Bildungsregeln in der WordPress-Konfiguration vorgeben. In meinen Fall wäre das z.B. "/%year%/%postname%/". Der Inhalt von matched_query wäre demnach für den aktuellen Artikel hier "year=2014&name=behandlung-depublizierter-artikel-in-wordpress". Anhand des Namen, der in WordPress eindeutig ist, kann dann der zugehörige Artikel in der "wp_posts"-Tabelle gefunden werden.

Da ich sowieso gerade dabei war, habe ich auch noch eine weitere Vereinfachung vorgenommen - nämlich die, den angezeigten Inhalt der entsprechenden Fehlerseiten über das WordPress-Backend bestimmen zu können. Dazu müssen zwei Seiten (nicht Artikel!) erstellt werden, deren Sichtbarkeit ebenfalls auf "privat" gesetzt wird. Die Seite, die für generelle 404-Fehlermeldungen genutzt werden soll, muss den Titel "[404]" erhalten (ohne Anführungszeichen). Die Seite, die für depublizierte Fehlermeldungen genutzt werden soll, muss hingegen den Titel "[410]" erhalten (ebenfalls ohne Anführungszeichen). Um das ganze einmal zu visualisieren, habe ich hier zwei URLs:

Ich hoffe, die Erläuterungen sind den für den ein oder anderen hilfreich. 🙂

Depublizierende Grüße, Kenny

Schreibe einen Kommentar

Um Ihnen beim weiteren Kommentieren auf dieser Webseite die erneute Eingabe Ihrer Daten zu ersparen, wird beim Absenden Ihres Kommentars ein Cookie an Ihren Browser gesendet und von diesem gespeichert. Mit dem Absenden eines Kommentars auf dieser Webseite stimmen Sie der Speicherung und Übertragung dieses Cookies explizit zu.

Pflichtfelder sind mit * markiert.