StartseiteWordPress / 30. April 2010

WordPress: Begriffe im Suchergebnis jederzeit hervorheben

Suche

Wird die Blog-interne Suche in Anspruch genommen, so erwartet der Nutzer übersichtlich gelistete Beiträge mit überdurchschnittlicher Trefferquote. Die Suchfunktion würde weiter punkten, wenn der ins Suchfeld eingegebene Begriff in den Ergebnissen direkt im Text kenntlich gemacht wird. Optische Hervorhebung der Treffer erleichtert dem Leser das “Scannen” und erhöht die Einschätzung der möglichen Relevanz. Vladimir Simovic zeigt in einem seiner Artikel, wie unkompliziert solch ein Ansatz im eigenen WordPress-Blog eingebunden werden kann. Mit meinem Kommentar und entsprechender Lösung versuche ich die Idee für mehr Usability und Nutzen auszuweiten.

Das Problem der Ursprungslösung
Je nach Theme arbeitet WordPress in der Suchausgabe mit Textausschnitten, einem so genannten post_excerpt. Befindet sich der gesuchte Keyword innerhalb des verwertbaren Excerpt, so würde der oben erwähnte Schnipsel das Suchwort mithilfe eines HTML-Tags selbstverständlich markieren. Trüb und ungemütlich wird es ausgehen, wenn der Begriff z.B. am Ende des Posts zu finden ist – in diesem Fall würde keine Hervorhebung erfolgen, da auf der Ergebnisseite nur der Teil jeweiliger “Kurzfassung” erscheint und das Fundstück entsprechend außerhalb des sichtbaren Bereiches liegt.

WordPress-Suche ohne Hervorhebung
Keine Fettung: Folge einer WordPress-Suche ohne das angekündigte Skript

Mehr Dynamik für mehr Benutzerfreundlichkeit
Meinerseits vorgeschlagene Technik würde ein klein wenig Intelligenz besitzen, also die Trefferstelle fokussieren und nach folgender Vorgehensweise agieren:

Nach diesem Prinzip wäre das Gesuchte (und hoffentlich Gefundene) permanent sichtbar und vorteilhaft visuell betont. Soweit die Theorie.

WordPress-Suche mit Hervorhebung
Fett: Fundstück mit hervorgehobenen Keywords JavaScript & CSS

Für euch, nicht für mich
In diesem Blog findet der entwickelte Code keine Verwendung. Der Grund liegt an der simplen und verständlichen Tatsache, dass sich das gesuchte Wort überall im Text befinden kann – sei es Teile von Bildunterschriften, Listen oder Aufzählungspunkten. Einmal gefunden, ist der Schnipsel mit der “Ausgrabung” inhaltlich rausgerissen. Das sieht hier im Playground-Blog nicht unbedingt befriedigend aus. Das Design der Suchergebnisse versagt an der Stelle.

Doch zwei Tage Entwicklung und ausgiebiger Tests sollen und wollen nicht umsonst sein – der Code gehört veröffentlicht. Mit Sicherheit werden sich Blog-Abnehmer für das gute Stück Software finden, wo das Theme-Layout vielleicht anders strukturiert ist oder das Skript entsprechend an eigene Bedürfnisse angepasst werden kann.

Funktion für die Hervorhebung der Suchtreffer (functions.php)

/**
* Markiert Treffer in den WordPress-Suchergebnissen
*
* @date 30.04.2010
* @author Sergej Müller
*/

function the_search_excerpt($length = 255)
{
  /* Excerpt */
  $excerpt = strip_shortcodes(
    apply_filters(
      'the_content',
      $GLOBALS['post']->post_content
    )
  );

  /* Shortcodes entfernen */
  $excerpt = strip_shortcodes($excerpt);

  /* Suchwort */
  $search = get_search_query();

  /* Leere Werte? */
  if (empty($excerpt) || empty($search)) {
    return null;
  }

  /* Suchwörter */
  $keywords = explode(' ', $search);
  $keyword = $keywords[0];

  /* Vorbereiten */
  array_walk(
    $keywords,
    create_function(
      '&$a',
      '$a = preg_quote($a);'
    )
  );

  /* Nur hervorheben */
  if (strlen($excerpt) <= $length) {
    echo preg_replace(
      '/((<[^>]*)|' .implode('|', $keywords). ')/ieu',
      '"\2"=="\1"? "\1":"<b>\1</b>"',
       $excerpt
     );

     return null;
  }

  /* Init */
  $break = '[sm]';
  $diff = round(($length - strlen($keyword)) / 2);

  /* Leerzeichen maskieren */
  $data = preg_replace_callback(
    '/<(.*?)>/ui',
    create_function(
      '$a',
      'return "<".str_replace(" ", "+", $a[1]).">";'
    ),
    $excerpt
  );

  /* Links */
  $data = wordwrap(
    $data,
    (stripos($data, $keyword) - $diff),
    $break
  );
  $data = substr(
    $data,
    (stripos($data, $break) + strlen($break))
  );
  $data = str_replace(
    $break,
    ' ',
    $data
  );

  /* Rechts */
  if (strlen($data) > $length) {
    $data = wordwrap(
      $data,
      $length,
      $break
    );
    $data = substr(
      $data,
      0,
      stripos($data, $break)
    );
    $data = str_replace(
      $break,
      ' ',
      $data
    );
  }

  /* Leerzeichen umwandeln */
  $data = preg_replace_callback(
    '/<(.*?)>/ui',
    create_function(
      '$a',
      'return "<".str_replace("+", " ", $a[1]).">";'
    ),
    $data
  );

  /* Tags prüfen */
  $data = force_balance_tags($data);

  /* Ausgeben */
  echo sprintf(
    '[...] %s [...]',
    preg_replace(
      '/((<[^>]*)|' .implode('|', $keywords). ')/ieu',
      '"\2"=="\1"? "\1":"<b>\1</b>"',
      $data
    )
  );
}

Funktionsaufruf mit der Zeichenanzahl als Parameter (search.php)

<?php the_search_excerpt(512); ?>
Sergej Müller

[Der Autor] Sergej Müller ist enthusiastischer Software Engineer mit Schwerpunkten Webentwicklung und WordPress. Seit 2007 programmiert und vertreibt er wpSEO, das weltberühmte und patentierte SEO-Plugin für WordPress-Blogs.

Soziale Werkzeuge

21 Kommentare zum Artikel

132 Tage zuvor | #1 Florian Lerch

Das klingt eigentlich wirklich nach einem echten Mehrwert für den Blog. Zumindest probeweise werd ich das mal integrieren. Und da der Code ja wirklich sehr sauber geschrieben und kommentiert ist, kann man ja auch noch anpassen. Super Arbeit!

Florian Lerch
132 Tage zuvor | #2 Tom

Da du jetzt schneller warst als ich, sich überhaupt mal praktische Gedanken zu machen, werde ich natürlich deine Arbeit nutzen und mir mal genauer ansehen. Danke schonmal! :)

Tom
132 Tage zuvor | #3 Sergej Müller

Jungs, bedient euch.

Sergej Müller
132 Tage zuvor | #4 RedParkz

Erstmal danke für die Arbeit :)

Funktioniert bei mir (fast) ohne Probleme und die Suchergebnisse gefallen mir persönlich so noch besser. Nur manchmal erzeugt es “[...] [...]” ohne wirklichen Text. Mal schaun ob ich ein Muster finde welches zu diesem “Fehler” führt.

RedParkz
132 Tage zuvor | #5 Sergej Müller

Alles klar, freut mich, dass der Schnipsel dir zusagt.

Ich hatte mal die Lösung in den letzten beiden Tagen in 3 Blogs im Einsatz, dabei ist mir der von dir gemeldete “Fehler” nicht aufgefallen. Ist aber bestimmt eine Kleinigkeit und ist schnell zu finden.

Sergej Müller
132 Tage zuvor | #6 Sergej Müller

@RedParkz
Schau mal, ich habe den obigen Code um eine IF-Abfrage erweitert, das sollte die Nebenwirkung eliminieren.

Sergej Müller
132 Tage zuvor | #7 RedParkz

@Sergej
Perfekt :) Jetzt zeigt es auch diese Ergebnisse richtig an. Danke

RedParkz
132 Tage zuvor | #8 Panthera-IT

Hallo Sergej,
habe gerade bei Perun auf den Beitrag aufmerksam geworden. Ich hatte zwar mir noch keine Gedanken über Hervorhebung gemacht, aber es kling sehr gut und vor allem logisch. Da ich gerade an eigenem Blog bastle, werde ich deinen Code mal übernehmen.

Panthera-IT
131 Tage zuvor | #9 Tom

So, nochmal Danke für die gute Arbeit. Habs grad eingebaut, Style etwas verändert, Stichwort Textmarker-Gelb, und es funktioniert super. :)

Tom
131 Tage zuvor | #10 Sergej Müller

@Tom
Perfekt, Handshake.

Sergej Müller
128 Tage zuvor | #11 thomas57

Danke für den Code, funktioniert, wie alles andere von Dir bestens.
Gruß aus dem Norden von
Thomas

thomas57
128 Tage zuvor | #12 Michael

Bin wie immer begeistert, vielen Dank für den Code.
VG Michael

Michael
109 Tage zuvor | #13 tboley

Ebenfalls besten Dank für den Code & Grüße aus Bielefeld!

tboley
108 Tage zuvor | #14 Francesco

Kann mich dem ersten Kommentar von Florian nur anschließen, vielen Dank für die Arbeit!

Francesco
92 Tage zuvor | #15 Jaime

Und wieder bringt mich eine Suche hierher ;-) Super, genau das hatte ich gesucht. Danke Sergej!

Allerdings ist mir eine Kleinigkeit aufgefallen da einige Suchergebnisse zwar angezeigt, aber eben nicht markiert wurden. Im Titel und im Text des Beitrages war ein “d´en”, also ein Akut (ANSI 0180) enthalten. Das Suchwort war 3 Wörter vor diesem Teilwort mit Akut zu finden und nicht markiert. Nachdem das Zeichen entfernt wurde, war im neuen Suchergebnis das vorher unmarkierte Wort richtig markiert. Im Titel des Beitrages konnte das Zeichen verbleiben.

Jaime
82 Tage zuvor | #16 Benny Neugebauer

Vielen vielen Dank dafür. Das funktioniert echt prima!

Benny Neugebauer
1 Tag zuvor | #17 daniel

ähm… hallo sergey, klingt gut. und zwei tage arbeit – hut ab!

aber ich kriegs nicht hin. obigen code kann ich doch so wie er ist in die functions.php kopieren, oder? wenn ich das mache, ist plötzlich mein ganzer header im backend voller fehlermeldungen – ca. 10 zeilen voll.

daniel
1 Tag zuvor | #18 Sergej Müller

Wenn in deiner functions.php bereits PHP-Code vorhanden war, dann sollte es reichen. Wenn es der einzige Code ist, dann müssen PHP-Tags drumherum, wie bei dem the_search_excerpt Aufruf.

Sergej Müller
1 Tag zuvor | #19 daniel

moin sergej,
wir sprechen doch von der functions.php im theme-ordner, oder? ja, da steht bereits php-code drin ( )

daniel
1 Tag zuvor | #20 Sergej Müller

Richtig. Sonst wüsste ich jetzt keinen Tipp. Kannst du mir sonst dein File schicken, ich schau rein.

Sergej Müller
1 Tag zuvor | #21 daniel

…okok, habs kapiert. danke nochmal. und sorry ;-)

daniel

2 Verlinkungen auf den Artikel

› WordPress: Suchergebnisse hervorheben und more-Tag mit Werbung e [...]

› Linkhub – Woche 17-2010 - pehbehbeh

Kommentar verfassen