Sortieren einer Liste von Posts, die unter einer Liste von zugehörigen Begriffen angezeigt werden (die ohne Anfangsartikel sortiert werden sollten)

Ich habe eine Reihe von Sortierproblemen auf einer Seite, die ich versuche herauszufinden, aber bisher ohne Erfolg.

Sortieren einer Liste von CPT-Posts, die unter zugeordneten benutzerdefinierten Taxonomiebegriffen aufgeführt sind

Ich habe dieses Stück Code in einer Antwort auf diese Frage gefunden , die perfekt funktioniert, um eine Liste aller benutzerdefinierten Taxonomiebegriffe mit einer Liste von zugeordneten benutzerdefinierten Beitragstypen unter jedem zu erhalten.

$custom_terms = get_terms('custom_taxonomy'); foreach($custom_terms as $custom_term) { wp_reset_query(); $args = array('post_type' => 'custom_post_type', 'tax_query' => array( array( 'taxonomy' => 'custom_taxonomy', 'field' => 'slug', 'terms' => $custom_term->slug, ), ), ); $loop = new WP_Query($args); if($loop->have_posts()) { echo '

'.$custom_term->name.'

'; while($loop->have_posts()) : $loop->the_post(); echo ''.get_the_title().''; endwhile; } }

Die Liste der benutzerdefinierten Post-Typen, die unter jedem Taxonomie-Begriff angezeigt werden, ist jedoch nicht sortiert (oder nach Post-Datum sortiert) und ich möchte sie alphabetisch sortieren (oder besser – über die in diesem Thread angezeigte benutzerdefinierte Sortierung und die Frage unter diesem).

Normalerweise würde ich einfach einen 'orderby' => 'title' irgendwo im Mix hinzufügen, aber das scheint hier nicht zu funktionieren oder ich kann nicht herausfinden, wo es hinzugefügt werden sollte.

Weiß jemand, wie man diese sortiert bekommt?

AKTUALISIEREN

Versucht, 'orderby' => 'title' nach 'post_type' => 'custom_post_type' in $args 'post_type' => 'custom_post_type' was keinen Effekt hatte.

Ignorieren des ursprünglichen Artikels ‘The’ aus den zurückgegebenen benutzerdefinierten Taxonomiebegriffen

Mit Hilfe von Code aus diesem Blogeintrag und diesen Fixes und Verbesserungsvorschlägen konnte ich eine Liste aller Posts in einem benutzerdefinierten Post-Typ erhalten und sie alphabetisch anzeigen lassen, während das ‘The’ in den Posttiteln ignoriert wurde.

Jetzt möchte ich auch meine Liste von benutzerdefinierten Taxonomie-Begriffen auf ähnliche Weise zurückgeben, wenn es überhaupt möglich ist.

Dies ist der Code, der verwendet wird, um Posts alphabetisch zu sortieren, während das ursprüngliche ‘The’ ignoriert wird:

 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; } 

Dies ermöglicht mir, diesen Filter mit einem _custom orderby-Parameter zu verwenden:

 add_filter( 'posts_orderby', function( $orderby, \WP_Query $q ) { // Do nothing if( '_custom' !== $q->get( 'orderby' ) ) return $orderby; global $wpdb; $matches = 'The'; // REGEXP is not case sensitive here // Custom ordering (SQL) return sprintf( " CASE WHEN {$wpdb->posts}.post_title REGEXP( '^($matches)[[:space:]]+' ) THEN TRIM( SUBSTR( {$wpdb->posts}.post_title FROM %d )) ELSE {$wpdb->posts}.post_title END %s ", strlen( $matches ) + 1, 'ASC' === strtoupper( $q->get( 'order' ) ) ? 'ASC' : 'DESC' ); }, 10, 2 ); 

Ich habe versucht, mit dem obigen Code herumzuspielen, um zu sehen, ob ich eine function erstellen könnte, die auf Taxonomiebegriffe statt auf Posts angewendet wird, aber ich bin ziemlich neu in all dem und ich konnte nichts erschaffen, was so funktioniert .

Ist es möglich, den Code, der auf Taxonomiebegriffe anzuwenden ist, in einer Liste anstelle von Posts neu zu schreiben?

Begrenzen der Liste zurückgegebener Taxonomiebegriffe + verknüpfter Beiträge auf solche, die mit einem bestimmten Buchstaben beginnen

Im Moment ist die Liste der Taxonomiebegriffe + verknüpfte Beiträge sehr lang. Um es ein bisschen besser zu managen, wenn ich die Liste durchstöbere, möchte ich es in 5 oder 6 Seiten zerlegen, die die Begriffe alphabetisch von AE, FJ usw. anzeigen.

Wenn das nicht machbar ist, wäre es okay, wenn ich es komplett in A, B, C, D usw. aufteilen würde.

Ich habe versucht, frühere Fragen zu diesem Thema zu lesen, aber ich habe nichts gefunden, was mir im Entferntesten zu funktionieren schien.

AKTUALISIEREN

Ich habe diesen Beitrag gefunden, der zu tun scheint, was ich will, aber ich kann es nicht auf meiner Website arbeiten. Dies ist der Code, den ich mit Änderungen basierend auf dem verknüpften Post hinzugefügt habe. Es wird nur eine vollständig leere Liste zurückgegeben.

 $game_titles = get_terms('game'); $count = count($game_titles); $letters = 'A'; if($count > 0){ foreach($game_titles as $game_title) { wp_reset_query(); $args = array('post_type' => 'release', 'tax_query' => array( array( 'taxonomy' => 'game', 'field' => 'slug', 'terms' => $game_title->slug, ), ), ); unset($game_titles); if (preg_match("/^$letters/i", $term->name)){ $loop = new WP_Query($args); if($loop->have_posts()) { echo '

' . $game_title->name . '

'; echo '
    '; unset($game_title); unset($args); while($loop->have_posts()) : $loop->the_post(); /* code */ endwhile; echo '
'; } } } }

UPDATE – Hinzugefügt @ PieterGoosen’s Code

Ich habe den Code aus der Antwort von @ PieterGoosen unten zu meiner functions.php (Code ist identisch mit dem in der Antwort) und meiner Seitenvorlagendatei ( der Code mit meinem hinzugefügten Schleifeninhalt kann hier gesehen werden ) hinzugefügt .

Was ich bekomme, ist teilweise richtig, aber es gibt immer noch einige Dinge, die nicht stimmen. Mit dem neuen Code bekomme ich eine Liste aller Posts der release CPT sortiert nach 1 zugehörigen game . Der gewählte Begriff ist der Begriff, der mit dem frühesten vorkommenden Buchstaben im Alphabet beginnt – wie in Asteroiden wird über Pac-Man gewählt, aber Pac-Man wird über Space Invaders ausgewählt.

Was es anzeigen sollte, ist eine Liste aller game und unter jedem Begriff eine Liste aller zugehörigen release Posts. Darüber hinaus scheint es so zu sein, dass jeder release Post nur einmal angezeigt wird, während ich optimalerweise möchte, dass sie unter jedem game wenn sie mehr als einem zugeordnet sind.

Die Sortierfunktion scheint jedoch gut zu funktionieren. Dieser neue Code ignoriert “das” in allen Post-Titeln und es scheint, dass er auch in den Term-Namen basierend auf der aktuellen Sortierung ignoriert wird (es wäre klarer, wenn die Term-Namen angezeigt würden).

UPDATE 2 – Testen Sie den neuen Code von PieterGoosen

Ich habe meinen Code mit dem aktualisierten Code aktualisiert und es funktioniert wie ein Zauber. Alles, was ich tun muss, ist etwas Styling und Loop-Inhalt zu verwenden.

Als Referenz hat diese Lösung VASTLY die Anzahl der databaseabfragen auf meiner Seite im Vergleich zu meinem alten Code verbessert (siehe oben in dieser Frage. Mit get_num_queries() zu überprüfen – mein alter Code hatte 3166 databaseabfragen. Mit dem neuen Code I bin stattdessen bei 33 (+ jetzt bekomme ich tatsächlich alle Daten, die ich anzeigen möchte + die Seite lädt schneller).

Solutions Collecting From Web of "Sortieren einer Liste von Posts, die unter einer Liste von zugehörigen Begriffen angezeigt werden (die ohne Anfangsartikel sortiert werden sollten)"

Dies ist eine wirklich interessante Frage, die zu einem sehr teuren, ressourcenintensiven process führen kann, der Ihre Seite dramatisch verlangsamen kann

AUFTAKT

Der gesamte Code in dieser Frage basiert auf dem folgenden Posttyp und der folgenden Taxonomie. Stellen Sie daher vor dem Ausführen von Code sicher, dass Sie den Posttyp und die Taxonomie an Ihre eigenen Anforderungen anpassen

  • Benutzerdefinierter Beitragstyp -> release

  • Benutzerdefinierte Taxonomie -> game

WICHTIGE AKTUALISIERUNG

Da Sie alle Begriffe und den Beitrag, der zu diesen Begriffen gehört, einbeziehen müssen und nicht nur den ersten Begriff, der einem Beitrag zugewiesen ist, sortieren und einbeziehen, müssen wir uns eine andere Lösung vollständig anschauen, aber dabei die performance im Hinterkopf behalten.

Die neue Lösung würde die Lösung von @birgire perfekt zu Ihrer vorherigen Frage passen, da wir jetzt die Abfrage selbst sortieren würden, und nicht die zurückgegebenen Beiträge.

Meine ursprüngliche Lösung für die gleiche Frage, die Sie gestellt haben, wird daher nicht mehr benötigt, um dieses Problem zu lösen. Es liegt also an Ihnen, ob Sie die Schleife mit dem ausgeblendeten benutzerdefinierten Feld erstellen und sortieren möchten. Meine Lösung, die das benutzerdefinierte Feld verwendet, ist jedoch weiterhin vollständig gültig. Da meine ursprüngliche Antwort auf diese Frage meine benutzerdefinierte Feldlösung beinhaltete, werde ich sie weiterhin verwenden, obwohl ich versuchen werde, Änderungen anzuzeigen, die Sie vornehmen können, wenn Sie sich für die Lösung von @ birgire und nicht für meine benutzerdefinierte Feldlösung entscheiden

Teil eins Punkt Eins

Ihr erster Codeblock, in dem Sie Ihre Begriffe abfragen und dann für jeden Begriff eine benutzerdefinierte Abfrage ausführen, um die einem Begriff zugewiesenen Beiträge zu erhalten, ist extrem teuer. Wie Sie sagen, haben Sie eine große Anzahl von Begriffen. Mit jeder Menge von Begriffen treffen Sie die db wirklich sehr hart.

Sie können dies überprüfen, indem echo get_num_queries() nach Ihrem Code echo get_num_queries() ausführen. Dadurch wird angezeigt, wie viele databaseabfragen Sie tatsächlich beim Laden dieser bestimmten Seite ausführen. Ich würde vorschlagen, dass du dich hinsetzt, bevor du das machst 😉

( HINWEIS: echo get_num_queries() zuerst einen Benchmark. Entferne all deinen Code, echo get_num_queries() , mache eine Notiz, ersetze deinen Code und echo get_num_queries() erneut aus und subtrahiere die beiden, um eine genaue Anzahl zu erhalten)

Bevor wir irgendetwas anfangen, sehen wir uns zunächst eine Hilfsfunktion an, die die Entfernung unserer verbotenen Wörter aus Begriffs- und Postnamen behandelt. Diese function ist wichtig und wird überall verwendet, um unseren Code DRY und organisiert zu halten

 /** * Function get_name_banned_removed() * * A helper function to handle removing banned words * * @param string $tring String to remove banned words from * @param array $banned Array of banned words to remove * @return string $string */ function get_name_banned_removed( $string = '', $banned = [] ) { // Make sure we have a $string to handle if ( !$string ) return $string; // Sanitize the string $string = filter_var( $string, FILTER_SANITIZE_STRING ); // Make sure we have an array of banned words if ( !$banned || !is_array( $banned ) ) return $string; // Make sure that all banned words is lowercase $banned = array_map( 'strtolower', $banned ); // Trim the string and explode into an array, remove banned words and implode $text = trim( $string ); $text = strtolower( $text ); $text_exploded = explode( ' ', $text ); if ( in_array( $text_exploded[0], $banned ) ) unset( $text_exploded[0] ); $text_as_string = implode( ' ', $text_exploded ); return $string = $text_as_string; } 

Dieser Code sollte in die Datei ” functions.php oder in ein benutzerdefiniertes Plugin ( vorzugsweise ) geschrieben werden.

Nun, da wir das abgedeckt haben, schauen wir uns den nächsten Teil an

Teil eins Punkt zwei

HINWEIS: Wenn Sie die Methode von @ birgire verwenden, um gesperrte Wörter zu entfernen und nach den geänderten Posttiteln zu sortieren, können Sie diesen Teil komplett überspringen, da wir das versteckte benutzerdefinierte Feld festlegen, nach dem wir sortieren werden.

Noch einmal, kurz, hier ist meine Lösung aus dem obigen Link, dieser Code ( der in ein Plugin oder functions.php gehen sollte ) und muss nur einmal ausgeführt werden, um ein verstecktes benutzerdefiniertes Feld namens _custom_sort_post_title zu jedem Beitrag zu setzen. Dies speichert den Post-Titel mit dem führenden verbotenen Wort entfernt

( BIG NOTE: Ich habe die Version des Originalcodes aus meiner Antwort im Link stark bearbeitet)

 add_action( 'wp', function () { add_filter( 'posts_fields', function ( $fields, \WP_Query $q ) { global $wpdb; remove_filter( current_filter(), __FUNCTION__ ); // Only target a query where the new custom_query parameter is set with a value of custom_meta_1 if ( 'custom_meta_1' === $q->get( 'custom_query' ) ) { // Only get the ID and post title fields to reduce server load $fields = "$wpdb->posts.ID, $wpdb->posts.post_title"; } return $fields; }, 10, 2); $args = [ 'post_type' => 'release', // Set according to needs 'posts_per_page' => -1, // Set to execute smaller chucks per page load if necessary 'suppress_filters' => false, // Allow the posts_fields filter 'custom_query' => 'custom_meta_1', // New parameter to allow that our filter only target this query 'meta_query' => [ [ 'key' => '_custom_sort_post_title', // Make it a hidden custom field 'compare' => 'NOT EXISTS' ] ] ]; $q = get_posts( $args ); // Make sure we have posts before we continue, if not, bail if ( !$q ) return; foreach ( $q as $p ) { $new_post_title = strtolower( $p->post_title ); if ( function_exists( 'get_name_banned_removed' ) ) $new_post_title = get_name_banned_removed( $new_post_title, ['the'] ); // Set our custom field value add_post_meta( $p->ID, // Post ID '_custom_sort_post_title', // Custom field name $new_post_title // Custom field value ); } //endforeach $q }); 

Nachdem dieser Code entfernt wurde, ist der einzige Code, den Sie in functions.php oder einem Plugin benötigen, der folgende: ( HINWEIS: Wir fügen dieser Aktion in TEIL ZWEI weitere Arbeit hinzu)

 add_action( 'transition_post_status', function ( $new_status, $old_status, $post ) { // Make sure we only run this for the release post type if ( 'release' !== $post->post_type ) return; $text = strtolower( $post->post_title ); if ( function_exists( 'get_name_banned_removed' ) ) $text = get_name_banned_removed( $text, ['the'] ); // Set our custom field value update_post_meta( $post->ID, // Post ID '_custom_sort_post_title', // Custom field name $text // Custom field value ); }, 10, 3 ); 

Dieser Code stellt sicher, dass jeder neue Beitrag, der veröffentlicht wird, oder jeder Post, der bearbeitet wird, das benutzerdefinierte Feld _custom_sort_post_title entsprechend festgelegt wird.

ZWEITER TEIL

Dies ist der Teil, der wirklich teuer werden kann. Einfach alle Begriffe zu erhalten und sie durchzublättern und die Beiträge entsprechend abzufragen, ist KEINE Option, da es sich um eine wirklich teure db-Operation handelt.

Was wir tun müssen, ist, dass wir hier nur eine Abfrage ausführen, um alle unsere Post-IDs zu erhalten, den Term-Cache zu aktualisieren, get_object_term_cache() zu verwenden, um die Post-Terme zu erhalten, das Array von IDs nach den Bedingungen zu sortieren dann sichere unsere Ergebnisse in einer Transiente. Wir werden nur Post-IDs in out-transient sichern, da wir nicht eine große Menge Post-Daten in ein chaotisches serialisiertes Array krampfen wollen

Wir werden uns sehr auf die function get_name_banned_removed() , um get_name_banned_removed() zu erstellen und Titel mit den get_name_banned_removed() Wörtern zu veröffentlichen.

Einige Anmerkungen

  • Ich habe den Code dieses Abschnitts etwas dynamischer gemacht. Anstatt den Post-Typ und die Taxonomie hart zu kodieren, habe ich sie zu Argumenten gemacht, die Sie an die function übergeben können. Sie sollten die Code-Blöcke lesen, die mit dem Code geliefert werden

DER CODE

 /** * Function get_sorted_post_ids_terms_and_fields() * * Return a sorted array of post ids. These ID's are sorted according to * - Post title with the banned words removed before sorting * - Post terms with the banned words removed before sorting * * @param string $post_type Post type to get posts from Default 'release' * @param string $taxonomy Taxonomy to get posts from Default 'game' * @return array $ids */ function get_sorted_post_ids_terms_and_fields( $post_type = 'release', $taxonomy = 'game' ) { $array_combine = []; // Sanitize our post type and taxonomy names if ( 'release' !== $post_type ) $post_type = filter_var( $post_type, FILTER_SANITIZE_STRING ); if ( 'game' !== $taxonomy ) $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING ); // Make sure that the taxonomy exist to avoid bugs later on if ( !taxonomy_exists( $taxonomy ) ) return $array_combine; // Our taxonomy exist, let's continue // Create a unique transient name $transient_name = 'spbtaf_' . md5( $taxonomy.$post_type ); if ( false === ( $array_combine = get_transient ( $transient_name ) ) ) { // Set our query arguments. Note, we will not do any sorting here $args = [ 'fields' => 'ids', // Only get post ID's 'post_type' => $post_type, 'posts_per_page' => -1, 'meta_key' => '_custom_sort_post_title', // Remove if you use @birgire's solution 'orderby' => 'meta_value', // Change to '_custom' if you use @birgire's solution 'order' => 'ASC', 'tax_query' => [ [ 'taxonomy' => $taxonomy, 'operator' => 'EXISTS' ] ], ]; $ids = get_posts( $args ); // Make sure we have posts if ( $ids ) { // Update the object term cache, saves plenty db time and calls update_object_term_cache( $ids, $post_type ); $term_post_ids_array = []; $term_names = []; // Loop through the posts and save in an array foreach ( $ids as $id ) { // Get the post terms from our post term cache $terms = get_object_term_cache( $id, $taxonomy ); // Loop through the terms. We definitely have terms foreach ( $terms as $term ) { // Remove the banned words from the term name $term_name = strtolower( $term->name ); if ( function_exists( 'get_name_banned_removed' ) ) $term_name = get_name_banned_removed( $term_name, ['the'] ); // Save the term name and post ids in an array $term_post_ids_array[$term_name][] = $id; // Save the real term names in an array $term_names[$term_name] = $term->name; } //endforeach $terms unset( $term ); } //endforeach $ids unset( $id ); // Sort the array according to our modified term ids ksort( $term_post_ids_array ); ksort( $term_names ); // Lets replace the modified term names with their proper names $array_combine = array_combine( $term_names, $term_post_ids_array ); } // endif $ids // Set the transient set_transient( $transient_name, $array_combine, 30*DAY_IN_SECONDS ); } // endif get_transient return $array_combine; } 

Diese function sollte ein sortiertes Array von Post-IDs zurückgeben, das nach sortiert ist

  • Der Begriff, zu dem sie gehören, wird mit den führenden verbotenen Wörtern ( wie the ) entfernt

  • Post-Titel mit dem führenden verbotenen Wort entfernt

Das Array ist auch nach Begriff sortiert

Der Transient ist auf 30 Tage eingestellt, Sie können dies bei Bedarf anpassen.

Wir müssen die Transienten entfernen und zurücksetzen, wenn ein neuer Beitrag veröffentlicht wird oder wenn ein Beitrag aktualisiert, gelöscht oder gelöscht wird. Dazu verwenden wir den Aktionshaken transition_post_status . ( Um alles ordentlich und zusammen zu halten, können wir die Aktion von PART ONE POINT TWO mit dieser Aktion kombinieren. Ich habe einen Abschnitt markiert, den Sie entfernen können, wenn Sie mit dem benutzerdefinierten Filter von @ birgire sortieren. )

 add_action( 'transition_post_status', function ( $new_status, $old_status, $post ) { /* ----------START DELETE IF YOU USE @birgire's SORTING FILTER------------*/ // Make sure we only run this for the release post type if ( 'release' !== $post->post_type ) return; $text = strtolower( $post->post_title ); if ( function_exists( 'get_name_banned_removed' ) ) $text = get_name_banned_removed( $text, ['the'] ); // Set our custom field value update_post_meta( $post->ID, // Post ID '_custom_sort_post_title', // Custom field name $text // Custom field value ); /* -------------END DELETE IF YOU USE @birgire's SORTING FILTER------------*/ global $wpdb; // Delete the transients $wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE ('_transient%_spbtaf_%')" ); $wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE ('_transient_timeout%_spbtaf_%')" ); // Reset the transient if ( function_exists( 'get_sorted_post_ids_terms_and_fields' ) ) get_sorted_post_ids_terms_and_fields(); //REMEMBER TO SET POST TYPE AND TAXONOMY }, 10, 3 ); 

Wie Sie sehen können, setzen wir die Transiente in der Aktion transition_post_status , was ebenfalls eine Menge Last vom Frontend entfernt

TEIL DREI

Die Schleife ist ein bisschen schwierig. Wir haben ein mehrdimensionales Array von get_sorted_post_ids_terms_and_fields() und Post-IDs, die von der function get_sorted_post_ids_terms_and_fields() . Wir müssen hier clever sein, um unsere Db-Anrufe so niedrig wie möglich zu halten. Der schwierige Teil besteht darin, die vollständigen Postobjekte von ihren jeweiligen IDs zu erhalten. Da Beiträge zu mehreren Begriffen gehören, haben wir auch doppelte IDs.

DER PLAN

Wir werden eine benutzerdefinierte Abfrage verwenden, um alle Beiträge zu erhalten. Wir haben hier ein WP_Query Problem, da WP_Query keine doppelten Posts WP_Query . Hier kommt der Trick ins WP_Query , WP_Query fügt die Posts hinzu, die es in einen Cache zurückgibt. Sobald ein Post im Cache ist, können wir ihn immer wieder mit get_post() abfragen, ohne einen db-Aufruf zu machen. Dies ist der clevere Teil des gesamten Codes.

Zuerst müssen wir auch das multidimensionale Array abflachen, um alle post_ids zu übernehmen, bevor wir es an WP_Query

 /** * Function flatten_array() * * Function to flatten an array and get all array values * Special thanks to zdenko * @link https://gist.github.com/kohnmd/11197713 * * @param array $array The multidimensional array to flatten * @return array $array The flattened array */ function flatten_array( $array ) { // Make sure $array is an array, if not return $array as an array if ( !is_array( $array ) ) return [$array]; return array_reduce( $array, function ( $a, $b ) { return array_merge( $a, flatten_array( $b ) ); }, [] ); } 

Was wir jetzt tun werden, ist, unsere Posts aus dem flatten Array von IDs abzufragen, um sie im Post-Cache zu speichern. Dazu verwenden wir eine benutzerdefinierte SQL-Abfrage aus den folgenden Gründen

  • Es ist superschnell

  • Wir brauchen keine Filter oder Aktionen, um diese Abfrage zu ändern

  • Die ganze harte Arbeit wurde bereits in get_sorted_post_ids_terms_and_fields() erledigt. Alles, was wir jetzt tun müssen, ist, die IDs von dieser function zu nehmen und die vollständigen Post-Objekte zu erhalten.

Sobald wir die vollständigen Posts haben, können wir update_post_cache , um unsere Posts im Post-Cache hinzuzufügen

 /** * Function set_posts_to_cache() * * Function to query all the full post objects who's ID's is in the * get_sorted_post_ids_terms_and_fields() function and then to add these * post objects into the post cache so we can query them over and over again * with get_post() * * @param string $post_type Post type to get posts from Default 'release' * @param string $taxonomy Taxonomy to get posts from Default 'game' */ function set_posts_to_cache( $post_type = 'release', $taxonomy = 'game' ) { global $wpdb; // Check if the taxonomy exists if ( !taxonomy_exists( $taxonomy ) ) return false; // Sanitize the taxonomy name $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING ); // Sanitize the post type if ( 'release' !== $post_type ) $post_type = filter_var( $post_type, FILTER_SANITIZE_STRING ); // Get our post ID's if ( function_exists( 'get_sorted_post_ids_terms_and_fields' ) ) { $combined_array = get_sorted_post_ids_terms_and_fields( $post_type, $taxonomy ); if ( $combined_array ) { if ( function_exists( 'flatten_array' ) ) { // Flatten our array in order to pass it to WP_Query $flatten_array = flatten_array( $combined_array ); $unique_ids = array_unique( $flatten_array ); $string_ids = implode( ', ', array_map( 'absint', $unique_ids ) ); /** * Run our custom SQL query and add our posts in cache * * We only need to get the posts by ID and post type. Remember, the function * get_sorted_post_ids_terms_and_fields() has already taken care of all the hard * work. All this query needs to do is to retrieve the posts which ID's are returned * by get_sorted_post_ids_terms_and_fields() to add the posts in cache */ $posts_to_cache = $wpdb->get_results( $wpdb->prepare( "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE 1=1 AND $wpdb->posts.ID IN ($string_ids) AND $wpdb->posts.post_type = %s ORDER BY $wpdb->posts.post_date DESC LIMIT 0, %d", $post_type, count( $unique_ids ) ) ); // Update the post cache update_post_caches( $posts_to_cache ); } // endif function_exists( 'flatten_array' ) } // endif if ( $combined_array ) } // endif ( function_exists( 'get_sorted_post_ids_terms_and_fields' ) ) } 

Schauen wir uns jetzt die Schleife an

 if ( function_exists( 'get_sorted_post_ids_terms_and_fields' ) ) { $combined_array = get_sorted_post_ids_terms_and_fields(); // Make sure we have a valid array if ( $combined_array ) { if ( function_exists( 'set_posts_to_cache' ) ) { // Set all our posts into the post cache. remember to pass the correct post type and taxonomy set_posts_to_cache( 'release', 'game'); // Set a variable to hold the first letter of the term name $first_letter = ''; foreach ( $combined_array as $term_name=>$post_ids ) { // Display the first letter from the terms $term_name_modified = strtolower( $term_name ); if ( function_exists( 'get_name_banned_removed' ) ) $term_name_modified = get_name_banned_removed( $term_name_modified, ['the'] ); $starting_letter = strtoupper( mb_substr( $term_name_modified, 0, 1 ) ); if ( $first_letter !== $starting_letter ) echo '

' . $starting_letter . '

'; // Update the $first_letter variable $first_letter = $starting_letter; // Display the term name above the posts echo $term_name . ''; // Apply the get_post() function to all post ids to get full posts objects $posts_array = array_map( 'get_post', $post_ids ); // Now that we have full posts, lets display them in our loop foreach ( $posts_array as $post ) { setup_postdata( $post ); // APPLY YOUR LOOP AS PER NORMAL AS PER YOUR LINK. echo '
  • ' . get_the_title() . '
  • '; } // endforeach $posts_array wp_reset_postdata(); // VERY VERY IMPORTANT } // endforeach $combined_array } // endif function_exists flatten_array } // endif $combined_array } // endif function_exists get_sorted_post_ids_terms_and_fields

    Ihre Posts sollten jetzt folgendes anzeigen:

    • Alle Posts werden alphabetisch nach dem Post-Namen sortiert, wobei das gesperrte Wort bei der anfänglichen Sortierung entfernt wird

    • Alle Begriffe sind alphabetisch sortiert, wobei die gesperrten Wörter aus der anfänglichen Sortierung entfernt wurden. Alle Begriffe haben ihre Beiträge unter ihnen sortiert

    • Alle Begriffe sind unter dem Buchstaben sortiert, mit dem ihr Name beginnt, wobei die verbotenen Wörter bei der anfänglichen Sortierung entfernt wurden

    Sie müssten nur Ihr eigenes benutzerdefiniertes Styling anwenden und die Schleife markieren

    TESTERGEBNISSE – DER BEWEIS IST IM PUDDING, NJAMMIE !!!

    Nach diesem riesigen Marathon können wir die Zahlen knacken. Bei 24 Posts, mit der ganzen Menge Arbeit, die ich getan habe, um Posttitel und Termnamen zu streichen und zu sortieren, habe ich es geschafft

    • 6db ruft in etwa 0,16 Sekunden auf

    • 5db Anrufe in etwa 0,14 Sekunden

    und wir haben unseren Vergänglichen nicht missbraucht. Ziemlich beeindruckend für so eine große Arbeit, lol.

    Nur aus Interesse habe ich die Schleife von Ihrem ersten Code-Block kopiert und das folgende Ergebnis erhalten

    • 73 Abfragen in 0,5 Sekunden

    Riesiger Unterschied, hat meinen Standpunkt bewiesen 😉

    Teil im Bau

    Wenn wir die Abfrage nach dem ersten Buchstaben des Terms paginieren möchten, benötigen wir hier etwas mehr Arbeit. Dieser Abschnitt wird im Aufbau bleiben, bis ich eine richtige Lösung dafür gefunden habe.

    Welche Lösung ich auch immer vorbringe, betrifft nicht die Teile 1 und 2 meiner Antwort. Teil drei wird definitiv betroffen sein und eine Art Neuschreiben benötigen