WP Suchergebnisse mit der Anzahl von Treffern in Kategorien anzeigen


Paginierung für Blätterseiten zur Suche hinzufügen

Der Ausgangspunkt für das auf dieser Seite vorgestellte Script war eine Fragestellung im WordPress Forum Deutschland. Der Fragesteller beabsichtigte die Datei search.php seines Themes so umzugestalten, dass auf der Ergebnisseite nicht nur die Ergebnisse und deren Anzahl ausgeben werden sollten, sondern zusätzlich noch die Anzahl der Treffer in den einzelnen Kategorien. Weiterhin sollten die einzelnen Kategorien, in denen Beitragsseiten mit den gesuchten Begriff/en gefunden wurden, bei der Ausgabe zusätzlich noch auf die entsprechenden Kategorien verlinkt werden.

Nähere Einzelheiten zur Frage- und Aufgabenstellung können dem Thread WP_Query mit Suchbegriff im WordPress Forum entnommen werden. Nach den ersten Tests wurde aus einem kleinen Code-Listing ein etwas längeres Script, da zusätzlich noch die Ergebnisseiten eine neu gestaltete Paginierung (Pagnitation) für Blätterseiten erhielt, um leichter in den Ergebnissen Blättern zu können. Siehe Screenshot:

Suchergebnisse und Kategorien

Suchergebnisse und Treffer in Kategorien anzeigen

Genau genommen handelt es sich weder um ein eigenständiges Script noch um ein Plugin, da praktisch nur die vorhanden search.php ergänzt wurde. Bei dieser etwas umfangreicheren Ergänzung wurde folgender Code-Abschnitt von get_header() bis * Start the Loop * gegen den weiter unten auf dieser Seite vorgestellten Code ersetzt.

get_header(); ?>

// Neu eingefügter und zum Teil ersetzter Code-Abschnitt

            <?php /* Start the Loop */ ?>

Auf Grund des Umfangs des Code-Listings möchten wir nicht auf einzelne Details eingehen, zumal einige wesentliche Stichpunkte ohnehin den Kommentaren zu entnehmen sind. Angemerkt sei hingegen, dass die SQL Query nicht auf unseren Mist wachsen wollte und die verwendete SQL Abfrage freundlicherweise von Jörg in seinem Webmaster-Forum veröffentlicht wurde.

Weiterhin sei angemerkt, dass eine zusätzliche Abfrage der Datenbank nur auf der ersten Ergebnisseite erfolgt, da beim Weiterblättern das Ergebnis der Abfrage und dessen Auswertung nur noch als QueryString von einer Seite zur nächsten Seite übernommen wird.

get_header();

/*-----------------------------------------------------------------------------------
 Einige WP Query-Variablen abfragen und zur weiteren Verwendung bereitstellen. 
 Obwohl die Werte von 's' bereits von WP gefiltert werden, kann eine zusätzliche 
 prophylaktische Kontrolle zumindest nicht schaden.
 ------------------------------------------------------------------------------------
*/
$anzahl  = 0;
$gesucht = false;
$suseite = false;

function prophylaktische_Kontrolle($eingang) {

    $eingang = preg_replace("/[^a-zA-ZäöüÄÖÜß0-9.,:;!?\s+_-]/", "", $eingang);
    return $eingang;
}
if (isset($wp_query->found_posts))    $anzahl  = $wp_query->found_posts;
if (isset($wp_query->query["s"]))     $gesucht = $wp_query->query["s"];
if (isset($wp_query->query["paged"])) $suseite = $wp_query->query["paged"];

$anzahl  = prophylaktische_Kontrolle($anzahl);
$gesucht = prophylaktische_Kontrolle($gesucht);
$suseite = prophylaktische_Kontrolle($suseite);

/*-----------------------------------------------------------------------------------
 Eine Klasse zur Abfrage der DB und zur Auswertung der Kategorien, wobei ein 
 zusätzlicher Query nur auf der ersten Ergebnisseite erfolgt, auf den weiteren Seiten 
 hingegen nur noch er QueryString ausgewertet wird.
 ------------------------------------------------------------------------------------
*/
class AbfrageKategorieDaten {

    protected function abfrage_der_Kategorien() {

        if ($this->gesucht == false) $this->anzahl = 0;
        if ($this->anzahl > 0 and $this->suseite == false) {
            global $wpdb;

            $tpref = $wpdb->prefix;
            $suche = $wpdb->get_results("
                SELECT *
                FROM ".$tpref."posts AS p
                LEFT JOIN ".$tpref."term_relationships AS tr
                ON p.ID = tr.object_id
                LEFT JOIN ".$tpref."term_taxonomy AS tt
                ON tr.term_taxonomy_id = tt.term_taxonomy_id
                LEFT JOIN ".$tpref."terms AS t
                ON  tt.term_id = t.term_id
                WHERE (p.post_type = 'post' OR p.post_type = 'page')
                AND (
                    p.post_title LIKE '%".$this->gesucht."%'
                    OR p.post_content LIKE '%".$this->gesucht."%'
                )
            ");
            foreach ($suche as $detail) {

                if (isset($detail->post_title) and isset($detail->ID)) {

                    if ($detail->taxonomy == "category" and $detail->post_type == "post") {
                        $detailnam = str_replace("APIs &amp; ", "WP-", $detail->name);
                        $katearr[$detail->ID] = $detailnam;
                    } elseif ($detail->post_type == "page") {
                        $katearr[$detail->ID] = "statische";
                    }
                }
            }
            if (isset($katearr) and count($katearr) > 0) {
                $zaehleaus = array_count_values($katearr);

                foreach($zaehleaus as $diekates => $dieanzahl) {
                    $this->vonschle .= "_".esc_html($dieanzahl."x".$diekates);
                }
            }
        }
        elseif (isset($_GET["fcats"]) and !empty($_GET["fcats"])) {

            $this->vonschle = preg_replace("/[^a-zA-Z0-9_-]/", "", $_GET["fcats"]);
        }
    return $this->vonschle;
    }
}
/*-----------------------------------------------------------------------------------
 Eine Klasse zur Aufbereitung der Kategorien für die Ausgabe einschließlich der
 entsprechenden Links zu den Kategorien.
 ------------------------------------------------------------------------------------
*/
class AufbereitungAusgabe extends AbfrageKategorieDaten {

    public $gesucht;
    public $anzahl;
    public $suseite;
    public $vonschle;
    protected $vonfrage;

    public function fuer_Ausgabe_und_KatLinks() {

        $this->vonschle = $this->abfrage_der_Kategorien();
        $this->vonfrage = $this->vonschle;
        $this->vonfrage = preg_replace("/[^a-zA-Z0-9_-]/", " ", $this->vonfrage);
        $this->vonfrage = preg_replace("/_(\d{1,3})x{1}/", " | $1 x in ", $this->vonfrage);
        $this->vonfrage = preg_replace("/in statische/", "in einer statischen Seite", $this->vonfrage);
        $this->vonfrage = ltrim($this->vonfrage, " | ");

        if (strlen($this->vonfrage) > 68){
            $laengevon = strpos($this->vonfrage, "|", 68);

            if ($laengevon !== false) {
                $this->vonfrage = substr_replace($this->vonfrage, " und ...", $laengevon, $laengevon);
            }
        }
        $dieurl = "<a href=\"http://www.coder-welten.com/category/";

        $this->vonfrage = str_replace("Allgemein",     $dieurl."allgemein/\">Allgemein</a>", $this->vonfrage);
        $this->vonfrage = str_replace("WP-Funktionen", $dieurl."wp-funktionen/\">WP-Funktionen</a>", $this->vonfrage);
        $this->vonfrage = str_replace("CodeSchnipsel", $dieurl."code-schnipsel-fur-wp/\">CodeSchnipsel</a>", $this->vonfrage);
        $this->vonfrage = str_replace("Plugins",       $dieurl."plugins/\">Plugins</a>", $this->vonfrage);
        $this->vonfrage = str_replace("Tipps",         $dieurl."tipps/\">Tipps</a>", $this->vonfrage);

        return $this->vonfrage;
    }
}

/*-----------------------------------------------------------------------------------
 Paginierung bzw. Pagnitation für Blätterseiten
 ------------------------------------------------------------------------------------
*/
class AufbereitungBlaetterLinks {

    public  $anzahl;
    public  $suseite;
    public  $gesucht;
    public  $vonschlf;
    private $blaetter;

    public function blaettern_in_Ergebnissen() {

        if ($this->anzahl > 10) {

            if ($this->suseite != false) {
                $this->blaetter .= "<a href=\"".esc_html(home_url("/")).
                                   "?s=".$this->gesucht."\">Seite 1</a>";
            } else {
                $this->blaetter .= "Seite 1";
            }
            if (preg_match("/\d+?[1-9]+\z/i", $this->anzahl)) {
                $seiten = floor(($this->anzahl/10) +1);
            } else {
                $seiten = floor($this->anzahl/10);
            }
            for ($i = 1; $i < $seiten; $i++) {
                $inlink = $i +1;

                if ($inlink != $this->suseite) {
                    $this->blaetter .= " | <a href=\"".esc_html(home_url("/page/"))."".
                                       $inlink."/?s=".esc_html($this->gesucht.
                                       "&fcats=".$this->vonschlf)."\">".$inlink."</a>";
                } else {
                    $this->blaetter .= " | ".$inlink;
                }
            }
        } else {
            $this->blaetter = false;
        }
        return $this->blaetter;
    }
}
/*-----------------------------------------------------------------------------------
 Erzeugen von Objekten als Instanzen ihrer Klassen, wobei die Klasse
 AbfrageKategorieDaten als Elternklasse für die Klasse AufbereitungAusgabe dient.
 ------------------------------------------------------------------------------------
*/
$aufbereitg = new AufbereitungAusgabe();
$aufbereitg->gesucht = $gesucht;
$aufbereitg->anzahl  = $anzahl;
$aufbereitg->suseite = $suseite;
$vnschleife = $aufbereitg->fuer_Ausgabe_und_KatLinks();
$pagnilinks = $aufbereitg->vonschle;

$blaettern = new AufbereitungBlaetterLinks();
$blaettern->gesucht  = $gesucht;
$blaettern->anzahl   = $anzahl;
$blaettern->suseite  = $suseite;
$blaettern->vonschlf = $pagnilinks;
$pagnlinks = $blaettern->blaettern_in_Ergebnissen();

?>

    <section id="primary" class="site-content">
        <div id="content" role="main">
        <?php if ( have_posts() ) :
        ?><header class="page-header">
            <h1 class="page-title"><?php
            printf("%s ", $anzahl);
            printf( __("Search Results for: %s", "twentytwelve"), "<span>".get_search_query()."</span>"); ?></h1>
            <div class="formle fuersuche fuerzeilen">
            <?php printf("%s ", "<p><strong>Gefunden in den Kategorien / Seiten:</strong></p>\n"); ?>
            <p class="comments-link fuerzeilen fuerabstand"><?php printf("%s", $vnschleife); ?></p>
            <p class="comments-link fuerzeilen fuerabstand"><?php echo $pagnlinks; ?></p>
            </div>
        </header>
            <?php
            /* Start the Loop */

CSS Stylesheets

Zusätzlich in der style.css aufgenommene CSS-Klassen.

 /* Für Suchergebnisse */
 div.fuersuche {background-color:#f8f7ea; border:1px solid #e2e2e2; padding:12px}
.fuerzeilen    {font-family:Helvetica, Arial, sans-serif; font-size:12px !important; color:#757575}
.fuerabstand   {margin-top:20px}

Bugs, Probleme und Ausblick

Bugs sind derzeit nicht bekannt (Stand: Oktober 2013).

Es sei jedoch erwähnt, weniger schön ist, dass die Anzahl der Treffer in den Kategorien nicht mit der Anzahl der Suchergebnisse übereinstimmt, wenn die Eingabe aus mehr als einen Suchbegriff besteht. Bei den Suchergebnissen werden auch die Ergebnisse gezählt, die nicht als zusammenhängende Phrase oder Long-Tail in einem Beitrag vorkommen, bei den Kategorien hingegen nur zusammenhängende Phrasen und Long-Tails.
Bei der Eingabe von einzelnen Suchbegriffen kam es hingegen bislang zu keiner Abweichung, wobei allerdings, in Abhängigkeit von der Länge und Anzahl der Zeichen, nicht immer alle Kategorien angezeigt werden, um einen Zeilenumbruch möglichst auf größeren Screens zu verhindern.

Ob und wann dieses Script weiterentwickelt wird, steht zum jetzigen Zeitpunkt noch nicht fest.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *