J'ai une série de problèmes de tri sur une page que j'essaie de résoudre, mais jusqu'à présent sans résultat.
Tri d'une liste de publications du CPT répertoriées sous les termes de taxonomie personnalisée associés
J'ai trouvé ce morceau de code dans une réponse à cette question , qui fonctionne parfaitement pour renvoyer une liste de tous les termes de taxonomie personnalisés avec une liste de types de publication personnalisée associés sous chacun d'eux.
$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 '<h2>'.$custom_term->name.'</h2>';
while($loop->have_posts()) : $loop->the_post();
echo '<a href="'.get_permalink().'">'.get_the_title().'</a>';
endwhile;
}
}
Toutefois, la liste des types de publication personnalisée affichés sous chaque terme de taxonomie n'est pas triée (ou elle peut être triée par date de publication) et je souhaiterais la trier par ordre alphabétique (ou même mieux - via le tri personnalisé affiché dans ce fil et la question en dessous de celui-ci).
Normalement, j'ajouterais simplement un 'orderby' => 'title'
quelque part dans le mélange, mais cela ne semble pas fonctionner ici ou je n'arrive pas à comprendre où il devrait être ajouté.
Est-ce que quelqu'un sait comment obtenir ces triés?
UPDATE
J'ai essayé d'ajouter 'orderby' => 'title'
après 'post_type' => 'custom_post_type'
dans $args
qui n'a eu aucun effet.
En ignorant l'article initial 'Le' des termes de taxonomie personnalisée renvoyés
À l'aide d'un code provenant de cette entrée de blog _ et ces correctifs et suggestions d'amélioration J'ai réussi à obtenir une liste de toutes les publications sous dans un type d'article personnalisé et à les afficher par ordre alphabétique tout en ignorant le 'The' dans les titres de poste.
Maintenant, j'aimerais aussi que ma liste de termes de taxonomie personnalisée soit renvoyée de la même manière, si possible.
C'est le code utilisé pour trier les articles par ordre alphabétique en ignorant le 'Le' initial:
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;
}
Cela me permet d’utiliser ce filtre en utilisant un paramètre _custom
orderby:
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 );
J'ai essayé de déconner avec le code ci-dessus pour voir si je pouvais créer une fonction qui s'appliquerait aux termes de taxonomie au lieu de posts, mais je suis assez nouvelle dans tout cela et je n'ai pas pu créer quoi que ce soit qui fonctionne de cette façon. .
Est-il possible de réécrire le code pour l'appliquer aux termes de taxonomie dans une liste au lieu de posts?
Limiter la liste des termes de taxonomie renvoyés + les publications associées à ceux commençant par une lettre spécifique
Pour le moment, la liste des termes de taxonomie et des postes associés renvoyés est très longue. Pour que cela soit un peu plus facile à parcourir lorsque je parcours la liste, j'aimerais la découper en 5 ou 6 pages en affichant les termes par ordre alphabétique de A-E, F-J, etc.
Si ce n'est pas faisable, je serais d'accord pour le diviser entièrement en A, B, C, D, etc.
J'ai essayé de parcourir les questions précédentes à ce sujet, mais je n'ai rien trouvé qui semblait fonctionner à distance pour moi.
UPDATE
J'ai trouvé cet article qui semble faire ce que je veux, mais je n'arrive pas à le faire fonctionner sur mon site. C'est le code que j'ai ajouté avec des modifications basées sur le post lié. Il ne fait que renvoyer une liste complètement vide.
$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 '<h2>' . $game_title->name . '</h2>';
echo '<ul>';
unset($game_title);
unset($args);
while($loop->have_posts()) : $loop->the_post();
/* code */
endwhile;
echo '</ul>';
}
}
}
}
UPDATE - Ajouté le code de PieterGoosen
J'ai ajouté le code de la réponse de @ PieterGoosen ci-dessous à mon fichier functions.php (le code est identique à celui de la réponse) et à mon fichier de modèle de page ( le code avec le contenu de ma boucle ajoutée peut être vu ici } ).
Ce que j'obtiens est en partie correct, mais il y a encore des choses qui ne vont pas. Avec le nouveau code, je reçois une liste de tous les articles du release
CPT triés par 1 terme game
associé. Le terme choisi est celui qui commence par la lettre la plus ancienne de l'alphabet - comme dans Asteroids, celle-ci sera choisie par-dessus Pac-Man, mais par-dessus Pac-Man, par-dessus Space Invaders.
Ce qu'il devrait afficher est une liste de tous les termes game
et, sous chaque terme, une liste de tous les postes release
associés. En outre, il semble que chaque publication release
ne soit affichée qu'une seule fois, mais de manière optimale, j'aimerais les faire réapparaître sous chaque terme game
si plusieurs personnes y sont associées.
Cependant, la fonction de tri semble bien fonctionner. Ce nouveau code ignore "le" dans tous les titres de publication et il apparaît qu'il est également ignoré dans les noms de terme en fonction du tri en cours (il serait plus clair si les noms de terme étaient affichés).
UPDATE 2 - Test du nouveau code de @ PieterGoosen
J'ai mis à jour mon code avec le code mis à jour et cela fonctionne comme un charme. Tout ce que j'ai à faire est d'appliquer du contenu de style et de boucle.
Pour référence, cette solution a VASTLY amélioré le nombre de requêtes de base de données sur ma page par rapport à mon ancien code (comme indiqué en haut de cette question. Utiliser get_num_queries()
pour vérifier - mon ancien code contenait 3166 requêtes de base de données. Avec le nouveau code, je suis à la place de 33 (+ maintenant, en fait, toutes les données que je veux afficher + la page se charge plus rapidement).
C'est une question très intéressante, qui peut entraîner un processus très coûteux et gourmand en ressources, ce qui peut réellement ralentir considérablement votre page.
Tout mon code dans cette question est basé sur le type de message et la taxonomie suivants. Par conséquent, avant d'exécuter un code, veillez à ajuster le type de message et la taxonomie à vos propres besoins.
Type de message personnalisé ->release
Taxonomie personnalisée ->game
Etant donné que vous devez inclure tous les termes et le message appartenant à ces termes, et pas seulement trier et inclure le premier terme attribué à un message, nous devons examiner complètement une autre solution, tout en gardant à l'esprit les performances.
La nouvelle solution correspondrait parfaitement à la solution de @birgire à votre question précédente , car nous allons maintenant trier la requête elle-même et non les messages renvoyés.
Ma solution initiale à la même question que vous avez posée n'est donc plus nécessaire pour résoudre ce problème, il vous appartient donc de décider si vous souhaitez ou non créer et trier la boucle avec la personnalisation masquée champ. Ma solution utilisant le champ personnalisé reste cependant totalement valide. Parce que ma réponse initiale à cette question impliquait ma solution de terrain personnalisée, je continuerai à l'utiliser, bien que j'essaierai d'indiquer les modifications que vous pouvez apporter si vous décidez d'utiliser la solution @ birgire plutôt que ma solution de terrain personnalisée.
Votre premier bloc de code où vous interrogez vos termes, puis exécutez une requête personnalisée poureachterm afin d'obtenir les publications affectées à un terme est extrêmement coûteux. Comme vous le dites, vous avez une grande quantité de termes. Avec n'importe quel nombre de termes, vous frappez vraiment la base de données vraiment très fort.
Vous pouvez vérifier cela en faisant echo get_num_queries()
après votre code. Cela affichera combien de requêtes de base de données vous effectuez réellement sur cette page. Je vous suggère de vous asseoir avant de faire cela ;-)
( NOTE: Commencez par obtenir un point de repère. Supprimez tout votre code, puis exécutez echo get_num_queries()
, notez-le, remplacez-le et exécutez à nouveau echo get_num_queries()
et soustrayez les deux pour obtenir un compte précis )
Avant de commencer, examinons d'abord une fonction d'aide qui gérera la suppression de nos mots interdits des noms de terme et de publication. Cette fonction est importante et sera utilisée partout pour garder notre code DRY et organisé
/**
* 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;
}
Ce code doit aller dans functions.php
ou dans un plugin personnalisé ( de préférence )
Maintenant que nous avons couvert, regardons la partie suivante
NOTE: Si vous envisagez d'utiliser la méthode de @ birgire pour supprimer les mots interdits et trier les titres de publication modifiés, vous pouvez ignorer complètement cette partie. définira le champ personnalisé masqué que nous trierons par )
Encore une fois, voici ma solution du lien ci-dessus, ce code ( qui devrait être inséré dans un plugin ou functions.php
) et n’a besoin d’être exécuté qu’une seule fois pour définir un champ personnalisé masqué appelé _custom_sort_post_title
à chaque poster. Cela enregistre le titre du message avec le mot interdit banni en tête
( BIG NOTE: J'ai fortement édité la version du code original de ma réponse dans le lien )
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
});
Une fois ce code supprimé, le seul code dont vous aurez besoin dans functions.php
ou un plugin sera le suivant: ( NOTE: nous ajouterons encore du travail. à cette action dansPART TWO)
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 );
Ce code garantira que chaque nouvelle publication publiée, ou chaque publication modifiée, que le champ personnalisé _custom_sort_post_title
est défini en conséquence.
C'est la partie qui peut vraiment coûter cher. Obtenir simplement tous les termes, les parcourir en boucle et interroger les publications en conséquence est une optionNOT/ car il s’agit d’une opération de base de données très coûteuse.
Ce que nous devrons faire, c'est que nous n'exécuterons qu'une requête ici pour obtenir tous nos identifiants de publication, mettre à jour le cache de termes, utiliser get_object_term_cache()
pour récupérer les termes de publication, trier le tableau d'identifiants en fonction des termes auxquels ils appartiennent, puis en toute sécurité. nos résultats dans un transitoire. Nous ne ferons que sécuriser les identifiants de post-in transitoires, car nous ne voulons pas encombrer une quantité énorme de données de post dans un tableau sérialisé en désordre.
Nous allons beaucoup nous appuyer sur la fonction get_name_banned_removed()
pour créer des noms de terme et publier des titres avec les mots interdits supprimés.
QUELQUES NOTES
/**
* 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;
}
Cela devrait permettre à la fonction de renvoyer un tableau trié d’ID de publication classés en fonction de
le terme auquel ils appartiennent avec les mots les plus interdits ( comme the
) est supprimé
poste titre avec le mot interdit interdit enlevé
Le tableau est également trié par terme
Le transitoire est défini sur 30 jours, vous pouvez l’ajuster si nécessaire.
Nous devons supprimer et réinitialiser le transitoire lorsqu'un nouveau message est publié, ou lorsqu'un message est mis à jour, supprimé ou non supprimé. Pour cela, nous utiliserons le hook d’action transition_post_status
. ( Pour que tout soit bien ordonné et combiné, combinons l'action dePART ONE POINT TWOavec cette action. J'ai marqué une section que vous pouvez supprimer si vous triez avec @ birgire's filtre personnalisé )
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 );
Comme vous pouvez le constater, nous réinitialisons le transitoire dans l'action transition_post_status
, cela enlève également beaucoup de charge au début du processus.
La boucle est un peu délicate. Nous avons un tableau multidimensionnel de noms de termes et d'ID de publication provenant de la fonction get_sorted_post_ids_terms_and_fields()
. Nous devons être intelligents ici pour garder nos appels à la base de données, etc. aussi bas que possible. La partie délicate consiste à récupérer tous les objets de publication à partir de leurs identifiants respectifs. De plus, comme les messages appartiennent à plusieurs termes, nous avons également des identifiants en double.
LE PLAN
Nous allons utiliser une requête personnalisée pour obtenir tous les messages. Nous avons un léger problème ici, car WP_Query
ne renvoie pas les messages en double. C'est ici que l'astuce intervient, WP_Query
ajoute les publications renvoyées dans un cache. Une fois qu'une publication est dans le cache, nous pouvons l'interroger avec get_post()
plusieurs fois sans passer d'appel. C'est la partie intelligente de tout le code.
Premièrement, nous avons également besoin d’un moyen d’aplatir le tableau multidimensionnel pour saisir tous les post_ids avant de le passer à 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 ) );
}, [] );
}
Ce que nous allons faire maintenant, c'est interroger nos publications à partir du tableau d'ID aplaties afin de les stocker dans le cache de publication. Pour cela, nous allons utiliser une requête SQL personnalisée pour les raisons suivantes
C'est super rapide
Nous n'avons besoin d'aucun filtre ou action pour modifier cette requête
Tout le travail acharné était déjà fait dans la get_sorted_post_ids_terms_and_fields()
. Tout ce dont nous avons besoin maintenant, c’est d’extraire les identifiants de cette fonction et d’obtenir les objets post complets.
Une fois que nous avons les publications complètes, nous pouvons utiliser update_post_cache
pour ajouter nos publications dans le cache de publication.
/**
* 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' ) )
}
Regardons la boucle maintenant
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 '<p>' . $starting_letter . '</p>';
// Update the $first_letter variable
$first_letter = $starting_letter;
// Display the term name above the posts
echo $term_name . '</br>';
// 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 '<li>' . get_the_title() . '</li>';
} // 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
Vos messages devraient maintenant apparaître comme suit:
Tous les articles sont triés par ordre alphabétique sous le terme auquel ils appartiennent, en fonction du nom de l'article; Word supprimé a été supprimé lors du processus de tri initial.
Tous les termes sont triés par ordre alphabétique, les mots interdits étant retirés du tri initial. Tous les termes ont leurs messages triés sous eux
Tous les termes sont triés sous la lettre dont le nom commence par les mots interdits supprimés lors du tri initial
Il vous suffira d'appliquer votre propre style et de marquer la boucle.
Après cet énorme marathon, laisse les chiffres se croiser. Sur 24 articles, avec tout le travail considérable accompli pour effacer et trier les titres des articles et les noms de termes, je me suis retrouvé avec
6db appelle en environ 0,16 seconde
appels 5db en environ 0,14 seconde
et nous n'avons pas abusé de notre transitoire. Assez impressionnant pour un travail aussi énorme, lol.
Juste pour votre intérêt, j'ai copié la boucle de votre premier bloc de code et j'ai obtenu le résultat suivant
Une différence énorme, prouvé mon point ;-)
Si nous voulons paginer la requête en fonction de la première lettre du terme, nous aurions besoin de travail supplémentaire ici. Cette section restera en construction jusqu’à ce que j’obtienne une solutionproper.
Quelle que soit la solution proposée, elle n’affectera pas les parties 1 et 2 de ma réponse. La troisième partie sera certainement affectée et nécessitera une sorte de réécriture