Ne pars pas! Ce n'est pas une autre question sur la façon de commanderby meta_value!
J'ai un type de message appelé events
et chaque message que je crée a un champ méta que j'ai appelé de manière imaginative event_dates_wp
qui accepte plusieurs dates et les enregistre sous la forme d'un tableau au format Ymd
.
J'ai un WP_Query
qui retourne les posts avec une date entre les deux meta_query
value
s, comme ceci:
$args = [
'post_type' => 'event',
'order' => 'ASC',
'orderby' => 'meta_value',
'meta_key' => 'event_dates_wp',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => 'event_dates_wp',
'type' => 'DATE',
'value' => '20180801',
'compare' => '>='
],
[
'key' => 'event_dates_wp',
'type' => 'DATE',
'value' => '20180831',
'compare' => '<='
]
]
];
Tout cela fonctionne à merveille et renvoie une liste d'articles contenant une valeur event_dates_wp
comprise entre le 1er août 2018 et le 31 août 2018; mais les résultats sont plutôt "post centriques" que "centrés sur la date" - laissez-moi m'expliquer:
Ce qui précède correspond à ce à quoi on pourrait s’attendre, mais ce que je veux faire, c’est lister les dates, du 1 er août au 31, avec chaque message correspondant répertorié sous chaque date, ce qui leur permet de se répéter.
Par exemple:
Event A contains dates [20180801, 20180802, 20180803, 20180804]
Event B contains dates [20180803, 20180804, 20180805]
Event C contains dates [20180804, 20180807]
Les résultats ressemblent à quelque chose comme:
20180801 // 1st Aug 2018
Event A
20180802 // 2nd Aug 2018
Event A
20180803 // 3rd Aug 2018
Event A
Event B
20180804 // 4th Aug 2018
Event A
Event B
Event C
20180805 // 5th Aug 2018
Event B
20180806 // 6th Aug 2018
[NO RESULT]
20180807 // 7th Aug 2018
Event C
20180808 // 8th Aug 2018
[NO RESULT]
20180809 // 9th Aug 2018
[NO RESULT]
...
La seule façon pour moi de faire cela serait d'interroger une date à la fois, puis de passer à la suivante; ce qui ne peut pas être une bonne idée. Existe-t-il un moyen de réaliser ce schéma apparemment commun consistant à interroger des événements basés sur la date et à les formater comme décrit?
Un bon exemple de ce type de comportement est la page des événements Barbican , qui, je crois, utilise Drupal. Il doit sûrement y avoir un moyen WordPress de faire ce genre de chose?
Merci d'avoir lu!
Mon idée suit.
1. Récupère le tableau de toutes les méta dates de vos événements. DISTINCT
dans la requête MySQL signifie n'inclut pas les doublons.
<?php
/*
* From https://wordpress.stackexchange.com/a/9451/11761
*/
function get_all_possible_meta_dates( $key = 'event_dates_wp', $type = 'page', $status = 'publish' )
{
global $wpdb;
$result = $wpdb->get_col( $wpdb->prepare( "
SELECT DISTINCT pm.meta_value FROM {$wpdb->postmeta} pm
LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
WHERE pm.meta_key = '%s'
AND p.post_status = '%s'
AND p.post_type = '%s'
", $key, $status, $type ) );
return $result;
}
2. Parcourez tous les messages ayant la clé méta event_dates_wp
et obtenez l'objet posts. Vous en avez besoin une fois.
3. Comparez chaque publication meta aux dates possibles que vous avez. S'il y a correspondance, imprimez-la.
<?php
function print_posts_by_meta_dates()
{
$args = [
'post_type' => 'event',
'order' => 'ASC',
'orderby' => 'meta_value',
'meta_key' => 'event_dates_wp',
'posts_per_page' => -1,
];
// all events having `event_dates_wp`
$loop = new WP_Query( $args );
// all posssible event dates
$distinct_meta_dates = get_all_possible_meta_dates();
foreach( $distinct_meta_dates as $event_meta_date ) {
// date header
echo '<h1>' . $event_meta_date . '</h1>';
// loop through all events
foreach( $loop->posts as $event ) {
// get current event dates array
$event_all_dates = get_post_meta( $event->ID, 'event_dates_wp', false );
// compare
if( in_array( $event_meta_date, $event_all_dates ) ) {
// post name
echo '<p>' . $event->post_name;
}
}
}
}
4. Imprimez la liste des publications en utilisant la fonction print_posts_by_meta_dates()
dans un modèle.
5. Ou créez le shortcode à utiliser dans le message ou la page.
add_shortcode( 'test_shortcode', 'print_posts_by_meta_dates' );
Vous obtiendrez quelque chose de similaire à:
Rappelez-vous, ne séparez pas les champs personnalisés avec e. g. virgule, mais ajoutez-les séparément: