Ich möchte statistikähnliche Tabellen mit der Anzahl der Posts in bestimmten benutzerdefinierten Taxonomiebegriffen erstellen und diese nach Jahr zusammen mit der Gesamtzahl der Posts aus diesem Jahr anzeigen.
Zum Beispiel:
2014
| _Taxonomy Term A: 8 Stellen
| _ Taxonomiebegriff B: 12 Stellen
Gesamtzahl der Beiträge im Jahr 2014: 20 Beiträge
Die Funktion muss offensichtlich Folgendes tun:
Um eine dynamische Liste für die Jahre zu erstellen , habe ich ein Snippet verwendet, das ich irgendwo gefunden habe und es sieht so aus:
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;
}
In meiner benutzerdefinierten Seitenvorlage verwende ich:
<?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; ?>
Meine Frage ist:
Wie erstelle ich die wp_query, um die Anzahl der Posts pro Taxonomie-Begriff pro Jahr ausgeben zu können? Ich wäre so froh, wenn mir jemand dabei helfen würde, das zu regeln.
PS: Ich habe bereits eine Tabelle, in der ALLE veröffentlichten Posts von my-custom-post-type pro Taxonomiebegriff gezählt werden. Ich habe die Hilfe hier gefunden und den deflime-Code verwendet.
Bearbeiten:
Dies ist Pieter Goosens Ausschnitt mit meinen Modifikationen:
$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
Hier ist eine andere Version des Codes in EDIT 1. Dieser Code ist viel schneller. Hier ist mein Test zwischen dem Code in EDIT 1 und EDIT 2
EDIT 1 Datenbankabfragezeit = +/- 0,25 und Datenbankabfragen = 69
EDIT 2 Datenbankabfragezeit = +/- 0,07 und Datenbankabfragen = 29
Hier ist der 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
?>
Dies gibt die gleiche Ausgabe aus wie die Tabelle in EDIT 1, außer dass keine leeren Begriffe angezeigt werden, sondern nur Begriffe mit Beiträgen
EDIT 1
Nach Ihrer bearbeiteten Frage sehen Sie hier den neuen Code. Ich musste ein oder zwei Dinge hier wegwerfen und einige Elemente neu anordnen, damit dies funktionierte. Die große Herausforderung bestand darin, die Prozentsätze zu berechnen, da die Variablen, anhand derer dies berechnet wird, in separaten foreach
-Schleifen lebten. Variablen innerhalb von foreach
-Schleifen leben nur innerhalb dieser foreach
, nicht außerhalb
Die großen Änderungen am Code (von meiner ursprünglichen Antwort, @deflime Code und Ihrem integrierten Code) von Ihrer Bearbeitung sind
Die beiden Tabellen mit der Gesamtzahl der Posts und den Prozentsätzen und Termnamen wurden nach außen direkt unter die $terms
foreach
-Schleife verschoben
Die Anzahl der Termnamen und Posts von jedem Term wurde in ein Array außerhalb der $terms
foreach
-Schleife verschoben
@Deflime Code verschrottet, $total_posts = 0;
entfernt und nur $percentage = round( (($yearly_posts_per_term->post_count / $total_posts)*100), 2 );
beibehalten und modifiziert
Verwendet array_sum
, um die Gesamtzahl der Posts für das Jahr aus der Reihe der Postcounts pro Term zu ermitteln
Verwendet array_combine
, um ein assoziatives Array mit den Termnamen und der Anzahl der Posts aus jedem Term zu erstellen
Schließlich habe ich eine foreach
-Schleife verwendet, um jeden Termnamen und die zugehörige Anzahl der Posts abzurufen und diese in die Tabelle zurückzuspeisen
Hier ist der endgültige 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');
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
?>
Bitte beachten Sie Wie in meiner ursprünglichen Antwort habe ich zu Testzwecken den Beitragstyp in post
und die Taxonomie in category
geändert.
Ihr Endergebnis ist eine Tabelle, die so aussieht. Bitte beachten Sie Alle meine Termnamen sind in Afrikaans, da ich sie auf meiner Testsite in Afrikaans getestet habe.
URSPRÜNGLICHE ANTWORT
Dies ist ein sehr grober Entwurf einer Idee, die ich dazu hatte. Ich habe kein HTML-Markup eingefügt und zum Testen des Codes den Standardposttyp post
und die eingebaute Taxonomie category
verwendet.
Hier ist, wie ich die vollständige Abfrage erstellt habe
Ermitteln Sie zunächst das Datum des ältesten Beitrags (sollte der erste Beitrag sein) auf der Website. Dies geschieht durch eine einfache Abfrage von get_posts
. Passen Sie diese an Ihre Bedürfnisse an
$oldest = get_posts( 'post_status=publish&posts_per_page=1&order=ASC' );
$oldest_date = $oldest[0]->post_date;
Entfernen Sie als Nächstes das zurückgegebene Datum, um nur das Jahr vom Post-Datum zu erhalten. Verwenden Sie die Funktion strtotime()
, um das Jahr in einen Unix-Zeitstempel zu konvertieren
$first_date = date('Y', strtotime($oldest_date));
Geben Sie das aktuelle Datum zurück, Sie möchten nur das Jahr. Verwenden Sie die Funktion date()
$current_date = date('Y');
Geben Sie beide Daten an die Funktion range()
zurück, um einen Bereich von Jahren zwischen den beiden Daten zu drucken
$year_range = range($current_date, $first_date);
Fügen Sie diese Bereiche wieder zu einem foreach loop
hinzu, um Ihre Beiträge in Jahreslisten zu erhalten
Ich habe get_terms()
verwendet, um eine Liste aller verfügbaren Begriffe der betreffenden Taxonomie abzurufen
$terms = get_terms('category');
Jetzt müssen alle diese Informationen mit tax_query
in einen WP_Query
zurückgeführt werden
$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);
Zuletzt möchten Sie den Termnamen und die Anzahl der Beiträge pro Term zurückgeben
echo $term->name . '(' . $posts->post_count . ')';
Jetzt alle zusammen !!
<?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 . ')';
}
}
}
?>
Wie gesagt, dies kann verfeinert werden. Nehmen Sie diese Idee und kodieren Sie sie und passen Sie sie an und ändern Sie sie, wie Sie es für richtig halten. Hoffe das hilft.
Es gibt eine viel einfachere Lösung als die, die Sie mit nur einer einzigen Abfrage akzeptiert haben. Ich illustriere hier für den benutzerdefinierten Beitragstyp "Produkt" und die benutzerdefinierte Taxonomie "product_cat" (egory) in Woocommerce, nur weil ich zufällig eine praktische Installation habe, um sie zu testen. Der $query
ist:
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
In meiner Beispielinstallation ergibt dies:
So gibt es zum Beispiel 10 Beiträge von Kleidung im Jahr 2013 und 2 im Jahr 2012.
Sie müssen nur $wpdb->get_results($query)
aufrufen (und $ wpdb-> Präfix anstelle von 'wp_' verwenden), um diese Tabelle in ein Array oder Objekt einzufügen, die Prozentsätze zu berechnen und sie anzuzeigen. Die group_concat-Spalten werden meistens zum Debuggen hinzugefügt (daher möchten Sie sie wahrscheinlich entfernen). Andererseits können die IDs beispielsweise auch für eine andere Verarbeitung nützlich sein (indem Sie die Werte in der Spalte in Arrays auflösen).
Für den Fall, dass jemand nach einem einfacheren, kürzeren Code sucht, um nur ein bestimmtes Jahr anzuzeigen, anstatt eine Schleife zu starten, in der alle Jahre des Beitrags angezeigt werden. Das ist der Code .
Dies beinhaltet auch den Link zum Taxonomiebegriffsarchiv. `
$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>';
}
`