Je souhaite créer des tableaux de type statistique contenant le nombre de messages dans des termes de taxonomie personnalisés et les afficher par année, ainsi que le nombre total de messages de cette année.
Par exemple:
2014
| _Taxonomie Terme A: 8 postes
| _ Taxonomie Terme B: 12 postes
Nombre total de postes en 2014: 20 postes
La fonction doit évidemment faire ce qui suit:
Pour faire une liste dynamique pour les années , j’ai utilisé un extrait que j’ai trouvé quelque part et qui ressemble à ceci:
function posts_by_year() {
// array to use for results
$years = array();
// get posts from WP
$posts = get_posts(array(
'numberposts' => -1,
'orderby' => 'post_date',
'order' => 'ASC',
'post_type' => 'my-custom-post-type',
'post_status' => 'publish'
));
// loop through posts, populating $years arrays
foreach($posts as $post) {
$years[date('Y', strtotime($post->post_date))][] = $post;
}
// reverse sort by year
krsort($years);
return $years;
}
Dans mon modèle de page personnalisé, j'utilise:
<?php foreach(posts_by_year() as $year => $posts) : ?>
<h2><?php echo $year; ?></h2>
// the code that I need to display the post counts per year
<?php endforeach; ?>
Ma question est la suivante:
Comment est-ce que je construis wp_query pour pouvoir générer le nombre de posts par terme de taxonomie par an? Je serais si heureux si quelqu'un m'aidait à résoudre ce problème.
PS: J'ai déjà un tableau qui compte TOUS les articles publiés de mon type personnalisé par type de taxinomie, j'ai trouvé help ici et utilisé le code de deflime.
Modifier:
Voici l'extrait de Pieter Goosen avec mes modifications:
$oldest = get_posts( 'post_type=my-custom-post-type&post_status=publish&posts_per_page=1&order=ASC' );
$oldest_date = $oldest[0]->post_date;
$first_date = date('Y', strtotime($oldest_date));
$todays_date = date('Y');
$year_range = range($todays_date, $first_date);
foreach ($year_range as $year) { // dynamic year-based tables
echo '<h2>' . $year . '</h2>';
$terms = get_terms('my-custom-taxonomy');
$total_posts = 0;
if ( !empty( $terms ) && !is_wp_error( $terms ) ) { // table body
echo '
<table class="statistics">
<tbody>
';
echo '
<thead>
<tr>
<td>Taxonomy Term</td>
<td>Percentage</td>
<td class="chart-count">Count</td>
</tr>
</thead>
';
echo '
<tfoot>
<tr>
<td colspan="2">Posts total</td>
<td class="chart-count">'.$total_posts.'</td>
</tr>
</tfoot>
';
foreach ( $terms as $term ) { // setup table <tr> per taxonomy term
$args = array(
'posts_per_page' => -1,
'post_type' => 'my-custom-post-type',
'post_status' => 'publish',
'year' => $year,
'tax_query' => array(
array(
'taxonomy' => 'my-custom-taxonomy',
'field' => 'slug',
'terms' => $term->slug
),
),
);
$total_posts += $term->count;
// Get %, round to 2 decimal places
$percentage = round( (($yearly_posts_per_term->post_count / $total_posts)*100), 2 );
// will add up to 100 at the end?
$total_check += $percentage;
$yearly_posts_per_term = new WP_Query($args);
echo '
<tr>
<td class="chart-item">'.$term->name.'</td>
<td class="chart-visual"><div class="chart-bar" style="width:'.$percentage.'%;"></div> '.$percentage.'%</td>
<td class="chart-count">'.$yearly_posts_per_term->post_count.'</td>
</tr>
';
} // endforeach
echo '
</tbody>
</table>
';
} //end of table
} // end of year-based list
EDIT 2
Voici une autre version du code dans EDIT 1. Ce code est beaucoup plus rapide. Voici mon test entre le code dans EDIT 1et EDIT 2
EDIT 1heure d'interrogation de la base de données = +/- 0.25 et interrogations de la base de données = 69
EDIT 2temps d'interrogation de base de données = +/- 0.07 et interrogations de base de données = 29
Voici le code
<?php
$oldest = get_posts( 'post_type=post&post_status=publish&posts_per_page=1&order=ASC' );
$oldest_date = $oldest[0]->post_date;
$first_date = date('Y', strtotime($oldest_date));
$todays_date = date('Y');
$year_range = range($todays_date, $first_date);
foreach ($year_range as $year) { // dynamic year-based tables
echo '<h2>' . $year . '</h2>';
$terms = get_terms('category');
$term_slugs = array();
if ( !empty( $terms ) && !is_wp_error( $terms ) ) { // table body
foreach ( $terms as $key=>$term){
$term_slugs[$key] = $term->slug;
}
echo '
<table class="statistics">
<tbody>
';
echo '
<thead>
<tr>
<td>Taxonomy Term</td>
<td>Percentage</td>
<td class="chart-count">Count</td>
</tr>
</thead>
';
$posts_count = array(); // Holds all term post counts in an array
$terms_array = array(); // Holds all term names in an array
$args = array(
'posts_per_page' => -1,
'post_type' => 'post',
'post_status' => 'publish',
'year' => $year,
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $term_slugs,
'include_children' => false
),
),
);
$yearly_posts_per_term = new WP_Query($args);
$posts_count[] = $yearly_posts_per_term->post_count; //Collects post counts and send them to an array
if($yearly_posts_per_term->have_posts()):
while($yearly_posts_per_term->have_posts()): $yearly_posts_per_term->the_post();
$terms = get_the_terms( $post->ID, 'category' );
if ( $terms && ! is_wp_error( $terms ) ) {
foreach ( $terms as $term ) {
$terms_array[] = $term->slug;
}
}
endwhile;
endif;
}
$total_posts = array_sum($posts_count); //Use array_sum to add up all the separate post counts
$result = array_count_values($terms_array);
foreach ($result as $term_name=>$count) {
$percentage = round( (($count / $total_posts)*100), 2 ); //Calculate the percentages of each term post cound to total year post count
echo '
<tr>
<td class="chart-item">'.$term_name.'</td>
<td class="chart-visual"><div class="chart-bar" style="width:'.$percentage.'%;"></div> '.$percentage.'%</td>
<td class="chart-count">'.$count.'</td>
</tr>
';
}
echo '
<tfoot>
<tr>
<td colspan="2">Posts total</td>
<td class="chart-count">'.$total_posts.'</td>
</tr>
</tfoot>
';
echo '
</tbody>
</table>
';
} // end of year-based list
?>
Cela donne le même résultat que le tableau dans EDIT 1, sauf qu'il ne montre pas les termes vides, seuls les termes avec posts sont affichés
EDIT 1
De votre question modifiée, voici la bande du nouveau code. J'ai dû supprimer une ou deux choses ici et réorganiser certains éléments pour que cela fonctionne. Le grand défi consistait à calculer les pourcentages, car les variables utilisées pour le calculer vivaient dans des boucles foreach
distinctes. Les variables contenues dans les boucles foreach
ne vivent que dans cette foreach
name__, et non pas dans le dehors
Les gros changements apportés au code (à partir de ma réponse originale, le code @deflime et votre code intégré) depuis votre édition sont:
Déplacement des deux tables contenant le nombre total d'articles et les pourcentages et les noms de termes à l'extérieur juste en dessous de la boucle $terms
foreach
name__
Déplacement des noms de terme et des posts de chaque terme dans un tableau situé en dehors de la boucle $terms
foreach
name__
Code @deflime mis au rebut, supprimé $total_posts = 0;
et uniquement conservé et modifié $percentage = round( (($yearly_posts_per_term->post_count / $total_posts)*100), 2 );
Utilisé array_sum
pour obtenir le nombre total de publications pour l'année à partir du tableau de décompte de publications par session
Utilisé array_combine
pour créer un tableau associatif avec les noms de termes et comptabiliser les comptes de chaque terme
Enfin, j'ai utilisé une boucle foreach
pour obtenir chaque nom de terme et le nombre de publications associé, afin de les intégrer dans la table.
Voici le code final
<?php
$oldest = get_posts( 'post_type=post&post_status=publish&posts_per_page=1&order=ASC' );
$oldest_date = $oldest[0]->post_date;
$first_date = date('Y', strtotime($oldest_date));
$todays_date = date('Y');
$year_range = range($todays_date, $first_date);
foreach ($year_range as $year) { // dynamic year-based tables
echo '<h2>' . $year . '</h2>';
$terms = get_terms('category');
if ( !empty( $terms ) && !is_wp_error( $terms ) ) { // table body
echo '
<table class="statistics">
<tbody>
';
echo '
<thead>
<tr>
<td>Taxonomy Term</td>
<td>Percentage</td>
<td class="chart-count">Count</td>
</tr>
</thead>
';
$posts_count = array(); // Holds all term post counts in an array
$term_names = array(); // Holds all term names in an array
foreach($terms as $term) {
$term_names[] = $term->name; //Collects term names and send them to an array
$args = array(
'posts_per_page' => -1,
'post_type' => 'post',
'post_status' => 'publish',
'year' => $year,
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $term->slug,
'include_children' => false
),
),
);
$yearly_posts_per_term = new WP_Query($args);
$posts_count[] = $yearly_posts_per_term->post_count; //Collects post counts and send them to an array
} // endforeach
unset($term);
}
$total_posts = array_sum($posts_count); //Use array_sum to add up all the separate post counts
$combine = array_combine($term_names,$posts_count); //Use array_combine to combine term names and post counts into assosiative array
foreach ($combine as $term_name=>$count) {
$percentage = round( (($count / $total_posts)*100), 2 ); //Calculate the percentages of each term post cound to total year post count
echo '
<tr>
<td class="chart-item">'.$term_name.'</td>
<td class="chart-visual"><div class="chart-bar" style="width:'.$percentage.'%;"></div> '.$percentage.'%</td>
<td class="chart-count">'.$count.'</td>
</tr>
';
}
echo '
<tfoot>
<tr>
<td colspan="2">Posts total</td>
<td class="chart-count">'.$total_posts.'</td>
</tr>
</tfoot>
';
echo '
</tbody>
</table>
';
} // end of year-based list
?>
Veuillez noterComme dans ma réponse d'origine, j'ai modifié le type de publication en post
et la taxonomie en category
à des fins de test.
Votre résultat final est une table ressemblant à ceci. Veuillez notertous les noms de mes termes sont en afrikaans comme je les ai testés sur mon site de test en afrikaans.
RÉPONSE ORIGINALE
C'est un brouillon d'une idée que j'avais sur la façon de procéder. Je n'ai inclus aucune balise HTML et utilisé le type de publication par défaut post
et la taxonomie intégrée category
pour tester le code.
Voici comment j'ai construit la requête complète
Tout d’abord, obtenez la date du message le plus ancien (ce devrait être le premier) sur le site. Cela se fait par une simple requête get_posts
. Modifier pour répondre à vos besoins
$oldest = get_posts( 'post_status=publish&posts_per_page=1&order=ASC' );
$oldest_date = $oldest[0]->post_date;
Ensuite, supprimez la date renvoyée pour obtenir uniquement l'année à partir de la date de publication. Utilisez la fonction strtotime()
pour convertir l'année en horodatage Unix
$first_date = date('Y', strtotime($oldest_date));
Renvoyer la date du jour, vous ne voudriez que l'année. Utilisez la fonction date()
$current_date = date('Y');
Renvoie les deux dates à la fonction range()
pour imprimer une plage d'années entre les deux dates
$year_range = range($current_date, $first_date);
Rajoutez ces plages dans un foreach loop
pour obtenir vos publications dans des listes basées sur des années.
J'ai utilisé get_terms()
pour obtenir une liste de tous les termes disponibles de la taxonomie en question
$terms = get_terms('category');
Maintenant, toutes ces informations doivent être réintroduites dans un tax_query
en utilisant WP_Query
$args = array(
'posts_per_page' => -1,
'post_type' => 'post',
'post_status' => 'publish',
'year' => $year,
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $term->slug
),
),
);
$posts = new WP_Query($args);
Enfin, vous voulez renvoyer le nom du terme et le nombre de messages par terme
echo $term->name . '(' . $posts->post_count . ')';
Maintenant tous ensemble !!
<?php
$oldest = get_posts( 'post_status=publish&posts_per_page=1&order=ASC' );
$oldest_date = $oldest[0]->post_date;
$first_date = date('Y', strtotime($oldest_date));
$current_date = date('Y');
$year_range = range($current_date, $first_date);
foreach ($year_range as $year) {
echo $year;
$terms = get_terms('category');
if ( !empty( $terms ) && !is_wp_error( $terms ) ){
foreach ( $terms as $term ) {
$args = array(
'posts_per_page' => -1,
'post_type' => 'post',
'post_status' => 'publish',
'year' => $year,
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $term->slug
),
),
);
$posts = new WP_Query($args);
echo $term->name . '(' . $posts->post_count . ')';
}
}
}
?>
Comme cela a été dit, cela peut être affiné, alors prenez cette idée et codez-la, adaptez-la et modifiez-la à votre guise. J'espère que cela t'aides.
Il existe une solution beaucoup plus simple que celle que vous avez acceptée, en utilisant une seule requête. J'illustre ici le type d'article personnalisé 'product' et la taxonomie personnalisée 'product_cat' (egory) dans Woocommerce, simplement parce que je dispose d'une installation pratique pour le tester. Le $query
est:
SELECT YEAR(p.post_date), t.name, COUNT(*), GROUP_CONCAT(p.ID), GROUP_CONCAT(p.post_title)
FROM wp_posts p
JOIN wp_term_relationships tr ON p.ID = tr.object_id
JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms t ON tt.term_id = t.term_id
WHERE tt.taxonomy = 'product_cat' AND p.post_type = 'product' AND p.post_status='publish'
GROUP BY YEAR(p.post_date), tt.term_taxonomy_id
ORDER by YEAR(p.post_date) DESC, tt.term_taxonomy_id ASC
Dans mon exemple d'installation, cela donne:
Ainsi, par exemple, il y a 10 postes d’habillement en 2013 et 2 en 2012.
Il vous suffit d'appeler $wpdb->get_results($query)
(et d'utiliser $ wpdb-> prefix au lieu de 'wp_') pour obtenir cette table dans un tableau ou un objet, calculer les pourcentages et les afficher. Les colonnes group_concat sont ajoutées principalement pour le débogage (par conséquent, vous voudrez probablement les supprimer), mais d'un autre côté, l'id peut aussi être utile pour un autre traitement (en décomposant les valeurs de la colonne dans des tableaux).
Dans le cas où quelqu'un recherche un code plus simple et plus simple pour afficher uniquement une année spécifique au lieu d'exécuter une boucle pour afficher toutes les années à compter de la publication. C'est le code .
Cela inclut également un lien vers l'archive des termes de taxonomie. `
$terms = get_terms('your-taxonomy'); //grab the taxonomy name
$year = 2015; // The year you want to pull the terms and count from
if ( !empty( $terms ) && !is_wp_error( $terms ) ){
echo '<div class="barometer">'; //class to apply css if you want
echo '<ul>';
foreach ( $terms as $term ) {
$args = array(
//'posts_per_page' => -1,
'post_type' => 'post', // disable this line if you want to grap from all post types
'post_status' => 'publish',
'year' => $year,
'tax_query' => array(
array(
'taxonomy' => 'your-taxonomy',
'field' => 'slug',
'terms' => $term->slug
),
),
);
$post_year = new WP_Query($args);
$term = sanitize_term( $term, 'your-taxonomy' );
$term_link = get_term_link( $term, 'your-taxonomy' ); //Get the links to the term archive page
// If the term has no post, it does not display. You can remove the if statement from here if you want to display empty terms
if ($post_year->post_count > 0 ) {
echo '<li><a href="' . esc_url( $term_link ) .'" title="' . sprintf( __( 'View all %s stories','media-foundation' ), $term->name ) . '">' . $term->name . '<span>' .$post_year->post_count. '</span>' . '</a></li>';
} // End of if $post_year->post_count
} // End of Foreach term loop
echo '</ul>';
echo '</div>';
}
`