wake-up-neo.net

zählen von Beiträgen aus verwendeten Taxonomiebegriffen nach Jahr

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:

  • anzahl der Posts von my-custom-post-type, die in den Jahren 2014, 2013, ... veröffentlicht wurden (Gesamtzahl pro Jahr)
  • zählen Sie die Beiträge in jedem Taxonomiebegriff aus meiner-benutzerdefinierten-Taxonomie auf der jährlichen Basis

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
4
okiedokey

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

enter image description here

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 $termsforeach-Schleife verschoben

  • Die Anzahl der Termnamen und Posts von jedem Term wurde in ein Array außerhalb der $termsforeach-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.

enter image description here

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.

4
Pieter Goosen

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:

taxonomy stats per year

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).

1
adelval

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  enter image description here  .

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

`

0
icynets