{"id":1163,"date":"2018-05-09T17:26:48","date_gmt":"2018-05-09T15:26:48","guid":{"rendered":"http:\/\/evileu.de\/zum-schwarzen-pinguin\/?p=1163"},"modified":"2018-05-14T15:36:03","modified_gmt":"2018-05-14T13:36:03","slug":"wordpress-stichwortsuche-mit-treffer-highlighting","status":"publish","type":"post","link":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/2018\/05\/09\/wordpress-stichwortsuche-mit-treffer-highlighting\/","title":{"rendered":"WordPress Stichwortsuche mit Treffer-Highlighting"},"content":{"rendered":"<p>Habt ihr euch auch schon manchmal gew\u00fcnscht, WordPress w\u00fcrde die Suchergebnisse irgendwie kennzeichnen &#8211; zum Beispiel durch eine farbige Hinterlegung der gefundenen Begriffe? Manchmal ist es n\u00e4mlich gar nicht so leicht herauszufinden, wo im Text sich der gesuchte Begriff (oder die gesuchten Begriffe) verstecken. Das eine durchaus \u00fcbliche Sache, und ich hab mir mal ein paar Gedanken zu dem Thema gemacht und mich im Inselfisch-Kochbuch an die Umsetzung gemacht. Dabei ist ein Plugin herausgekommen, das sicher noch ein bisschen Optimierungspotential hat, aber so im Prinzip funktioniert die Sache. Wurde eh schon lang wieder einmal Zeit f\u00fcr ein bisschen Spa\u00df auf der Datenbank!<\/p>\n<h2>Die Anforderungen<\/h2>\n<ul>\n<li>Es sollen ein oder mehrere Suchbegriffe (durch Leerzeichen getrennt) eingegeben werden k\u00f6nnen.<\/li>\n<li>Zuerst sollen alle Rezepte ausgegeben werden, bei denen die gesuchten Begriffe schon im Titel vorkommen. Die Treffer werden farbig hinterlegt.<\/li>\n<li>Dann sollen noch alle Rezepte nachfolgen, bei denen die Suchbegriffe im Rezepttext = post content vorkommen, auch hier farbig hinterlegt<\/li>\n<li>Durch Klick auf den Rezepttitel soll man direkt zum Rezepttext gelangen.<\/li>\n<\/ul>\n<h2>Wir fangen nat\u00fcrlich mit einem Formular an<\/h2>\n<p>Das Plugin f\u00e4ngt mit einem einfachen Eingabefeld an:<\/p>\n<pre>\/*\r\nPlugin Name: Evis Suche mit Highlighting\r\nPlugin URI: http:\/\/localhost\/wp_ajax\/wp-content\/plugins\/suche\r\nDescription: Eigenes Suchmodul mit Highlighting\r\nVersion: 1.0\r\nAuthor: Evi Leu\r\nAuthor URI: http:\/\/www.evileu.de\r\n*\/\r\n\r\n\/\/Formular als Shortcode einbinden\r\n\u00a0function suche_form(){\r\n\u00a0\u00a0 \u00a0 \r\n\u00a0\u00a0 \u00a0echo \"&lt;h3&gt;Rezeptsuche mit Highlighting&lt;\/h3&gt;\";\r\n\u00a0\u00a0 \u00a0echo \"&lt;p&gt;Mehrere Stichworte mit Leerzeichen trennen&lt;\/p&gt;\";\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0echo \"&lt;form action='#' method='post'&gt;\";\r\n\u00a0\u00a0 \u00a0echo \"&lt;input type='text' size='100' name = 'suchstring' &gt;\";\r\n\u00a0\u00a0 \u00a0echo \"&lt;\/form&gt;\";\r\n\u00a0\u00a0 \u00a0\r\n<\/pre>\n<p>Der Inhalt des Textfeldes wird \u00fcbernommen, wenn der Anwender auf Return dr\u00fcckt. Dann legen wir los:<\/p>\n<pre>if (isset($_POST['suchstring'])){\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\/\/***ein oder mehrere Leerzeichen im String?\r\n\u00a0\u00a0 \u00a0<span style=\"color: #008000;\">if (strpos($_POST['suchstring'],\" \")&gt;0){<\/span>\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$suchsql = \"\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$suchsql_content = \"\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0<span style=\"color: #0000ff;\">\/\/string am leerzeichen trennen<\/span>\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$strings = explode(\" \",$_POST['suchstring']);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$anzahl = count($strings);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$ersterstring = $strings[0];\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0for ($i=1; $i &lt; $anzahl; $i++){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0<span style=\"color: #0000ff;\">\/\/suchstring f\u00fcr post_title zusammenbauen<\/span>\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$suchsql = $suchsql.\" AND post_title like '%\".$strings[$i].\"%' \";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0<span style=\"color: #0000ff;\">\/\/suchstring f\u00fcr post_content zusammenbauen<\/span>\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$suchsql_content = $suchsql_content.\" AND post_content like '%\".$strings[$i].\"%' \";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0\/\/***kein Leerzeichen im String\r\n\u00a0\u00a0 \u00a0<span style=\"color: #008000;\">else{$ersterstring = $_POST['suchstring'];<\/span>\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0}<\/pre>\n<p>Was hab ich gemacht? Wenn ein oder mehrere Leerzeichen im Suchstring vorhanden sind, zerlege ich den String mit explode() in ein Array. Dann baue ich mir aus allen vorkommenden Einzelstrings ein SQL-Snippet zusammen, eins f\u00fcr die Abfrage des post_title und eins f\u00fcr die Abfrage des post_content. Man kann die AND-Klauseln einfach hintereinanderh\u00e4ngen, es sollen ja alle Suchstrings gefunden werden. Gro\u00df\/Kleinschreibung ist egal, der MySQL-Like ist nicht case sensitive. Wenn kein Leerzeichen im Suchbegriff vorkommt, \u00fcbernehme ich ihn im Ganzen.<\/p>\n<h2>Die erste Abfrage geht auf den Titel<\/h2>\n<p>Mit dem zusammengebauten SQL-Snippet von oben starte ich die erste Abfrage: Dann gebe ich erstmal aus, wieviele Rezepte mit den Suchbegriffen im Titel gefunden wurden.<\/p>\n<pre>global $wpdb; \r\n\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\/******Suchstring im Titel?****\/\r\n\u00a0\u00a0 \u00a0$alleposts = $wpdb-&gt;get_results( \"SELECT * from \".$wpdb-&gt;prefix.\"posts \r\nwhere post_title like '%\".<span style=\"color: #ff0000;\">$ersterstring<\/span>.\"%' \".<span style=\"color: #ff0000;\">$suchsql<\/span>.\"\r\n\u00a0\u00a0 \u00a0and post_type like 'post' and post_status like 'publish' order by post_title\");\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0$gefunden = $wpdb-&gt;num_rows;\r\n\u00a0\u00a0 \u00a0if ($gefunden == 1){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo $gefunden.\" Rezept mit \".$_POST['suchstring'].\" im Titel:\";\r\n\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0if ($gefunden &gt; 1){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo $gefunden.\" Rezepte mit \".$_POST['suchstring'].\" im Titel:\";\r\n\u00a0\u00a0 \u00a0}<\/pre>\n<p>Dann klappere ich mit einem foreach alle Ergebnisse des ersten Selects ab und mache mit PHP ein paar Ersetzungen f\u00fcr das Highlighting der Suchbegriffe. Daf\u00fcr benutze ich den str_ireplace, der ist nicht case sensitive. Dabei geht der erste Suchebegriff extra, f\u00fcr alle weiteren steppe ich mit der for-Anweisung durch unser Array von oben.<\/p>\n<pre>foreach($alleposts as $einpost){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/**** ersten Suchstring im Titel highlighten\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$<span style=\"color: #008000;\">replace<\/span> = '&lt;span style=\"background-color: #FF0;\"&gt;' . <span style=\"color: #ff0000;\">$ersterstring<\/span>. '&lt;\/span&gt;'; \/\/ create replacement\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0<span style=\"color: #008000;\">$content<\/span> = <span style=\"color: #0000ff;\">str_ireplace<\/span>( <span style=\"color: #ff0000;\">$ersterstring<\/span>, <span style=\"color: #008000;\">$replace<\/span>, $einpost-&gt;post_title );\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/***** ersten Suchstring im content highlighten\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$<span style=\"color: #008000;\">rezepttext<\/span> = str_ireplace( <span style=\"color: #ff0000;\">$ersterstring<\/span>, <span style=\"color: #008000;\">$replace<\/span>, $einpost-&gt;post_content );\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/****alle weiteren Suchstrings highlighten\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0for ($j=1; $j&lt;$anzahl;$j++){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0<span style=\"color: #008000;\">$replace<\/span> = '&lt;span style=\"background-color: #FF0;\"&gt;' . <span style=\"color: #ff0000;\">$strings[$j]<\/span>. '&lt;\/span&gt;'; \/\/ create replacement\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0<span style=\"color: #008000;\">$content<\/span> = str_ireplace( <span style=\"color: #ff0000;\">$strings[$j]<\/span>, $replace, $content );\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 <span style=\"color: #008000;\">\u00a0$rezepttext<\/span> = str_ireplace( <span style=\"color: #ff0000;\">$strings[$j]<\/span>, $replace, $rezepttext );\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0<span style=\"color: #0000ff;\">\/\/als Accordeon ausgeben<\/span>\r\n<span style=\"color: #0000ff;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;details&gt;&lt;summary&gt;\".$content.\"&lt;\/summary&gt;\";<\/span>\r\n<span style=\"color: #0000ff;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo $rezepttext.\"&lt;\/details&gt;\";<\/span>\r\n<span style=\"color: #0000ff;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;hr&gt;\";<\/span>\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0}<\/pre>\n<p>Ganz am Ende benutze ich eine HTML5-Syntax f\u00fcr die Ausgabe des Rezepttitels als anklickbares Detail\/Summary Element, auch Accordeon genannt. Das sieht dann so aus:<\/p>\n<div id=\"attachment_1164\" style=\"width: 542px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1164\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1164\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/05\/accordeon.jpg\" alt=\"accordeon\" width=\"532\" height=\"402\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/05\/accordeon.jpg 532w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/05\/accordeon-300x227.jpg 300w\" sizes=\"(max-width: 532px) 100vw, 532px\" \/><p id=\"caption-attachment-1164\" class=\"wp-caption-text\">accordeon<\/p><\/div>\n<p>Wenn man auf das Dreieckssymbol klickt, wird der Rezepttext eingeblendet &#8212; mit Highlighting:<\/p>\n<div id=\"attachment_1165\" style=\"width: 576px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1165\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1165\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/05\/schweinefilet_highlighted.jpg\" alt=\"schweinefilet_highlighted\" width=\"566\" height=\"471\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/05\/schweinefilet_highlighted.jpg 566w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/05\/schweinefilet_highlighted-300x250.jpg 300w\" sizes=\"(max-width: 566px) 100vw, 566px\" \/><p id=\"caption-attachment-1165\" class=\"wp-caption-text\">schweinefilet_highlighted<\/p><\/div>\n<p>Das funktioniert auch mit mehreren Stichworten (es k\u00f6nnen beliebig viele sein), ich hab hier mal &#8222;butter tomate&#8220; eingegeben:<\/p>\n<div id=\"attachment_1166\" style=\"width: 583px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1166\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1166\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/05\/butter_tomate.jpg\" alt=\"butter_tomate\" width=\"573\" height=\"605\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/05\/butter_tomate.jpg 573w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/05\/butter_tomate-284x300.jpg 284w\" sizes=\"(max-width: 573px) 100vw, 573px\" \/><p id=\"caption-attachment-1166\" class=\"wp-caption-text\">butter_tomate<\/p><\/div>\n<h2>Und jetzt das ganz nochmal auf den Content:<\/h2>\n<p>Der SQL ist nur minimal ver\u00e4ndert und geht jetzt auf den post_content, das Highlighting funktioniert genauso wie oben, auch die Ausgabe als Accordeon:<\/p>\n<pre>\/\/*******<span style=\"color: #0000ff;\">Suchstring im Content<\/span> *\/\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0$alleposts = $wpdb-&gt;get_results( \"SELECT * from \".$wpdb-&gt;prefix.\"posts where \r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0 <span style=\"color: #0000ff;\">post_content<\/span> like '%\".<span style=\"color: #ff0000;\">$ersterstring<\/span>.\"%' \".<span style=\"color: #ff0000;\">$suchsql_content<\/span>.\" \r\n\u00a0\u00a0 \u00a0and post_type like 'post' and post_status like 'publish' order by post_title\");\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0foreach($alleposts as $einpost){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/**** ersten Suchstring highlighten\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$replace = '&lt;span style=\"background-color: #FF0;\"&gt;' . $ersterstring. '&lt;\/span&gt;'; \/\/ create replacement\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$rezepttext = str_ireplace( $ersterstring, $replace, $einpost-&gt;post_content );\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/****alle weiteren Suchstrings highlighten\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0for ($j=1; $j&lt;$anzahl;$j++){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$replace = '&lt;span style=\"background-color: #FF0;\"&gt;' . $strings[$j]. '&lt;\/span&gt;'; \/\/ create replacement\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$rezepttext = str_ireplace( $strings[$j], $replace, $rezepttext );\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0<span style=\"color: #0000ff;\">\/\/als Accordeon ausgeben<\/span>\r\n<span style=\"color: #0000ff;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;details&gt;&lt;summary&gt;\".$einpost-&gt;post_title.\"&lt;\/summary&gt;\";<\/span>\r\n<span style=\"color: #0000ff;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo $rezepttext.\"&lt;\/details&gt;\";<\/span>\r\n<span style=\"color: #0000ff;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0echo \"&lt;hr&gt;\";<\/span>\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/}\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0}<\/pre>\n<p>Das wars schon! Jetzt k\u00f6nnte man h\u00f6chstens noch anmeckern, dass manche Rezepte zweimal auftauchen, weil sie einmal mit der Suche im Titel und ein zweites Mal mit der Suche im Content gefunden wurden, aber auch daf\u00fcr sollte es eine L\u00f6sung\u00a0 geben, das ist Feintuning.<\/p>\n<p>Viel Spa\u00df beim Nachbauen! Hier noch ein Beispiel, dass es auch mit mehreren Stichworten funktioniert, ich habe &#8222;butter tomate oliven\u00f6l hackfleisch knoblauch&#8220; eingegeben:<\/p>\n<div id=\"attachment_1170\" style=\"width: 544px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-1170\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1170\" src=\"http:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/05\/5_suchworte.jpg\" alt=\"5_suchworte\" width=\"534\" height=\"562\" srcset=\"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/05\/5_suchworte.jpg 534w, https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-content\/uploads\/2018\/05\/5_suchworte-285x300.jpg 285w\" sizes=\"(max-width: 534px) 100vw, 534px\" \/><p id=\"caption-attachment-1170\" class=\"wp-caption-text\">5_suchworte<\/p><\/div>\n<h2>Bemerkung nach Testbetrieb: immer diese Umlauts<\/h2>\n<p>Darauf bin ich erst sp\u00e4ter gekommen: der MySQL-Like\u00a0ignoriert in der Kollation utf8_general_ci die deutschen Umlaute. So wird zum Beispiel zum Stichwort &#8222;<strong>huhn<\/strong>&#8220; auch &#8222;<strong>h\u00fchn<\/strong>chen&#8220; gefunden, da \u00fc wird als u behandelt. Das w\u00e4re ja soweit noch nicht weiter tragisch, aber der PHP str_ireplace() macht sehr wohl einen Unterschied zwischen Umlauten und aeoui, da f\u00e4llt das Highlighting auf die Nase&#8230; na ja, ich finde das jetzt nicht wirklich schlimm, es ist halt ein kleines Manko. Deswegen jetzt mit der Datenbankkollation rumzuexperimentieren erspare ich mir, das w\u00e4re mit Kanonen auf Spatzen geschossen.<\/p>\n<h2>Doppelt vorkommende Rezepte ausblenden<\/h2>\n<p>Bislang kamen Rezepte, die sowohl im Titel als auch im Content die eingegebenen Begriffe enthielten, doppelt vor. Das l\u00e4\u00dft sich relativ einfach unterbinden, ich merke mir einfach in einem Array, welche Rezept-IDs bei der Stichwortsuche im Titel schon gefunden wurden, und baue daraus einen String f\u00fcr eine not-in-Klausel. Daf\u00fcr kommt noch folgender Code nach dem ersten SQL rein:<\/p>\n<pre>\/\/merken, welche post ids schon gefunden wurden\r\n\u00a0\u00a0 \u00a0$merken = array();\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\/\/Falls ein oder mehrere Rezepte gefunden wurden, IDs merken\r\n\u00a0\u00a0 \u00a0if ($gefunden&gt;0){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$k=0;\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0foreach ($alleposts as $einpost){\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$merken[$k] = $einpost-&gt;ID;\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$k=$k+1;\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}else{\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/Falls kein Rezept gefunden wurde, Dummy Eintrag mit ID 0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$gemerkt = \"(0)\";\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\/\/Klammer f\u00fcr den not in aufbauen\r\n\u00a0\u00a0 \u00a0$gemerkt = \"(\";\r\n\u00a0\u00a0 \u00a0for ($l=0; $l &lt; $gefunden; $l++){\r\n\u00a0\u00a0 \r\n\u00a0\u00a0 \u00a0$gemerkt = $gemerkt.$merken[$l].\", \";\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0\/\/Klammer f\u00fcr den \"not in\" mit Dummy-Eintrag 0 abschliessen\r\n\u00a0\u00a0 \u00a0$gemerkt = $gemerkt.\"0)\";\r\n<\/pre>\n<p>Den Dummy-Eintrag mit der 0 brauchts, damit der &#8222;not in&#8220; nicht auf eine leere Klammer rennt und gar nichts ausgibt. Mit dem jetzt in der Variable $gemerkt gespeicherten String mit den IDs gehe ich in den zweiten SQL, der im Content sucht, und f\u00fcge noch eine &#8222;not in&#8220;-Klausel\u00a0 hinzu:<\/p>\n<pre>$alleposts = $wpdb-&gt;get_results( \"SELECT * from \".$wpdb-&gt;prefix.\"posts where \r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0 post_content like '%\".$ersterstring.\"%' \".$suchsql_content.\" \r\n\u00a0\u00a0 \u00a0and post_type like 'post' and post_status like 'publish' \r\n<span style=\"color: #ff0000;\">and ID not in \".$gemerkt.\"<\/span> order by post_title\");<\/pre>\n<p>Das filtert alle Rezepte heraus, die bereits in der ersten SQL-Abfrage gefunden wurden.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Habt ihr euch auch schon manchmal gew\u00fcnscht, WordPress w\u00fcrde die Suchergebnisse irgendwie kennzeichnen &#8211; zum Beispiel durch eine farbige Hinterlegung der gefundenen Begriffe? Manchmal ist es n\u00e4mlich gar nicht so leicht herauszufinden, wo im Text sich der gesuchte Begriff (oder die gesuchten Begriffe) verstecken. Das eine durchaus \u00fcbliche Sache, und ich hab mir mal ein [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[21,11,7,4,8,2],"tags":[],"_links":{"self":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1163"}],"collection":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/comments?post=1163"}],"version-history":[{"count":8,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1163\/revisions"}],"predecessor-version":[{"id":1176,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/posts\/1163\/revisions\/1176"}],"wp:attachment":[{"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/media?parent=1163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/categories?post=1163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/evileu.de\/zum-schwarzen-pinguin\/wp-json\/wp\/v2\/tags?post=1163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}