Der folgende Beitrag stammt von Jason Witt. Hier teilt Jason eine Methode, um etwas zu tun, das man vielleicht für ziemlich einfach hält, sich aber als etwas komplizierter erweist, als man es sich wünschen würde. Glücklicherweise kann es mit Jasons Code und Beispielen einfach sein.
Kürzlich musste ich eine benutzerdefinierte WordPress-Abfrage erstellen, die Posttitel in alphabetischer Reihenfolge auflistet. Ich begann mit einer einfachen Abfrage wie dieser.
$my_query = new WP_Query(array(
'post_type' => 'post',
'orderby' => 'title',
'order' => 'ASC'
));
Meine Ergebnisse waren

Die Ergebnisse sind technisch in alphabetischer Reihenfolge, aber nicht so, wie ich es wollte. Ich wollte, dass das Wort „the“ ignoriert wird, wenn der Titel damit beginnt, und stattdessen nach dem nächsten Wort alphabetisiert wird. Die gewünschte Reihenfolge sollte so aussehen

Das „the“ wird als Initialartikel bezeichnet. Sie wissen schon: „A“, „An“ und „The“, das, was manchmal am Anfang von Eigennamen steht. Wenn Sie international werden wollen, können Sie „La“ (Spanisch) und „Les“ (Französisch) einschließen. Nach langem Suchen und Durchforsten des WordPress Codex konnte ich keine native WordPress WP_Query-Lösung zum Ignorieren eines Initialartikels finden.
Was ich fand, waren zwei sehr hilfreiche Filter, mit denen ich dies erreichen kann: posts_fields und posts_orderby. Mit ein wenig SQL-Kenntnissen und PHP-Tricks konnte ich das gewünschte Ergebnis erzielen.
Was vielleicht nicht überraschend ist, ist, dass dies ein ziemlich häufiger Bedarf ist. Stellen Sie sich eine Musikbibliothek vor. Alle Bands, die mit „The“ beginnen, unter „T“ zu gruppieren, wäre unnötig verwirrend. Stattdessen ist es so

Wie man es macht
Ich werde Ihnen zeigen, wie ich es gemacht habe, damit Sie es in jedem WordPress-Projekt verwenden können, das eine alphabetische Sortierung einer WordPress-Abfrage erfordert, während Initialartikel ignoriert werden.
Fügen Sie in Ihrer `functions.php`-Datei die folgenden beiden Funktionen hinzu.
function wpcf_create_temp_column($fields) {
global $wpdb;
$matches = 'The';
$has_the = " CASE
WHEN $wpdb->posts.post_title regexp( '^($matches)[[:space:]]' )
THEN trim(substr($wpdb->posts.post_title from 4))
ELSE $wpdb->posts.post_title
END AS title2";
if ($has_the) {
$fields .= ( preg_match( '/^(\s+)?,/', $has_the ) ) ? $has_the : ", $has_the";
}
return $fields;
}
function wpcf_sort_by_temp_column ($orderby) {
$custom_orderby = " UPPER(title2) ASC";
if ($custom_orderby) {
$orderby = $custom_orderby;
}
return $orderby;
}
Die erste Funktion, wpcf_create_temp_column, erstellt zur Zeit der Abfrage eine virtuelle Spalte namens „title2“. Sie füllt die Spalte mit den Titeln Ihrer Beiträge. Wenn der Titel den Initialartikel „The“ enthält, wird er entfernt.
Die zweite Funktion, wpcf_sort_by_temp_column, erstellt eine neue benutzerdefinierte orderby. Sie sortiert die Beiträge nach der virtuellen Spalte „title2“ in aufsteigender Reihenfolge (`ASC`).
Damit diese Funktionen ihre Magie auf Ihre Abfragen wirken, fügen Sie sie einfach zu den zuvor erwähnten Filtern hinzu.
add_filter('posts_fields', 'wpcf_create_temp_column');
add_filter('posts_orderby', 'wpcf_sort_by_temp_column');
Nun werden Ihre Abfragen Ihre Posttitel in alphabetischer Reihenfolge sortieren, während der Initialartikel „The“ ignoriert wird. Wenn Sie zusätzliche Initialartikel hinzufügen möchten, die ignoriert werden sollen, müssen Sie sie nur zur Variable $matches in der Funktion wpcf_create_temp_column hinzufügen und sie mit einem senkrechten Strich trennen.
$matches = 'A|An|The|La|Les';
Nehmen wir an, Sie haben mehrere WordPress-Abfragen, die nach dem Titel sortiert werden, aber Sie möchten diese Filter nicht auf diese Abfragen anwenden. Indem Sie die Filter in Ihrer `functions.php`-Datei hinzufügen, wirken sie sich auf jede Abfrage auf Ihrer Website aus, daher möchten Sie das wahrscheinlich nicht. Ganz zu schweigen davon, dass es die Leistung Ihrer Website beeinträchtigen kann, indem unnötige Filter verwendet werden. Hier erfahren Sie, wie Sie diese Filter auf bestimmte Abfragen anwenden können.
Entfernen Sie zuerst die Funktionen add_filter aus Ihrer `functions.php`-Datei. Fügen Sie dann in Ihrer Vorlagendatei mit der gewünschten Abfrage die Funktionen add_filter zusammen mit den Funktionen remove_filter wie folgt ein.
add_filter('posts_fields', 'wpcf_create_temp_column'); // Add the temporary column filter
add_filter('posts_orderby', 'wpcf_sort_by_temp_column'); // Add the custom order filter
$query = new WP_Query(array('post_type' => 'post')); // Your custom query
remove_filter('posts_fields','wpcf_create_temp_column'); // Remove the temporary column filter
remove_filter('posts_orderby', 'wpcf_sort_by_temp_column'); // Remove the temporary order filter
if (have_posts()) : while ($query->have_posts()) : $query->the_post(); // The query output
the_title();
echo '<br/>';
endwhile; endif; wp_reset_postdata();
Im obigen Code fügen Sie die Filter hinzu, führen die Abfrage aus und entfernen dann sofort die Filter. Indem Sie den Abfragecode in den Filter einbetten, isolieren Sie diese Filter für diese spezifische Abfrage.
Viel Spaß beim Sortieren!
Wirklich nützlicher Beitrag, vielen Dank, Chris, für das Teilen von Jasons Arbeit.
Wenn jemand Spanisch/Französisch verwenden muss, sind die vollständigen Artikel
$spanish_articles = ‘La|El|Las|Los|Una|Unas|Un|Unos’;
$french_articles = ‘La|Le|Les|Un|Une|Des’;
Ein Problem im Französischen: Wenn ein Nomen mit einem Vokal beginnt, nimmt der Artikel die Form L' an, zum Beispiel
L’Orchestre Philharmonique.
Interessanter Ansatz. Ohne externe Bibliotheken zu verwenden, ist dies wirklich der eleganteste Ansatz, um dieses Ergebnis zu erzielen? Ohne dies auf einer lokalen WP-Installation implementiert zu haben, frage ich mich nach der Leistung dieser Methode.
Ich habe versucht, dies in PHP ohne eine virtuelle Tabelle zu tun, und bin zu etwas gekommen, das ziemlich hässlich aussieht, aber gut zu funktionieren scheint. Ist nicht WordPress-spezifisch, könnte aber die Abfrageergebnisse mit etwas Herumspielen sortieren.
Ich habe dies auf einer Live-Website für einen Kunden verwendet, ohne Leistungsprobleme. Die Abfrage, die ich dafür verwendet habe, ist tatsächlich eine der am schnellsten ladenden Seiten der Website.
Ihr Ansatz ist interessant und scheint die Aufgabe zu erfüllen, aber ich glaube nicht, dass er dem „WordPress Way“ entspricht. Die Filter, die ich hier verwendet habe, sind nur für solche Situationen.
Anstatt den Filter zu entfernen, würde ich eine Abfragevariable erstellen, die die beiden Funktionen prüfen würden.
Ich stimme zu. Das habe ich für meine Version gemacht
Implementiert als Gist (wenn auch ungetestet): https://gist.github.com/mcaskill/d3ada21f9ff0800a6970
Das wird furchtbar für die Leistung sein. Sobald Sie 10.000+ Zeilen haben, werden Sie massive Probleme bemerken. Viel besser, dies MySQL als Teil der Abfrage zu übergeben, was Sie mit CASE- oder IF-Anweisungen tun könnten.
Ach ja, wenn Sie mehr als 10.000 Zeilen abfragen, werden Sie überall Leistungsprobleme haben. Dann verwenden Sie Transients oder Caching-Plugins wie WP Super Cache.
Was würden Sie vorschlagen?
Wenn Sie wirklich glauben, dass die Sortierung im Code schneller ist als in der Datenbank, dann bauen Sie bitte nichts Kompliziertes.
Ich bin mir nicht sicher, woher Sie kommen. Der Code im Artikel erstellt eine benutzerdefinierte MySQL-Abfrage mit der CASE-Methode.
Wie würden Sie eine MySQL-Abfrage erstellen, die in Vorlagendateien verwendet werden kann, ohne sie zu codieren?
Eine weitere Option ist die Verwendung von
trim()in der MySQL-Abfrage, z. B....ORDER BY TRIM(LEADING 'a ' FROM TRIM(LEADING 'an ' FROM TRIM(LEADING 'the ' FROM LOWER(`post_title`)))).Eine einfache rekursive Funktion könnte diese ORDERBY-Klausel generieren.
Wenden Sie dann auf der Designseite CSS auf die
$matchesan, um die Deckkraft zu verringern oder die Farbe zu ändern, um den Initialartikel zu minimieren und dem Benutzer klar zu machen, dass die Liste nach dem operativen ersten Wort alphabetisiert ist.Zwei Worte: The The ;)
Ein paar Worte mehr: „Lies den Regexp genauer, bevor du antwortest“ :)
Toller Share – Es ist lustig, wie etwas so Einfaches wie das Ignorieren von „the“ so kompliziert erscheint, um es tatsächlich zu implementieren.