按年统计自定义分类术语中的帖子

时间:2014-08-11 作者:okiedokey

我想构建类似统计数据的表,其中包含给定自定义分类术语中的帖子数量,并按年份显示它们以及当年的帖子总数。

例如:

2014

|_分类术语A:8篇文章

|_分类术语B:12个职位

Total posts in 2014: 20个职位

该函数显然需要执行以下操作:

从我的自定义帖子类型中统计2014年、2013年发布的帖子。。。(每年总计数)

  • 每年从我的自定义分类中统计每个分类术语中的帖子dynamic list for the years, 我使用了我在某处找到的一个片段,它如下所示:

    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;
    }
    
    在自定义页面模板中,我使用:

    <?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; ?>
    

    My question is:

    如何构建wp\\u查询,以便每年能够输出每个分类术语的帖子计数?如果有人帮我解决这个问题,我会很高兴的。

    附:我已经有了一个表,根据分类法术语统计了自定义帖子类型中所有已发布的帖子,我找到了帮助here 并使用消石灰的代码。

    Edit:

    这是Pieter Goosen的片段,包括我的修改:

    $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
    

  • 3 个回复
    最合适的回答,由SO网友:Pieter Goosen 整理而成

    EDIT 2

    下面是编辑1中的另一个版本的代码。这段代码要快得多。这是我在编辑1和编辑2中的代码之间的测试

    编辑1数据库查询时间=+/-0.25,数据库查询=69

    编辑2数据库查询时间=+/-0.07,数据库查询=29

    这是代码

    <?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
    
    ?>
    
    这将呈现与“编辑1”中的表格相同的输出,只是它不显示空术语,只显示带有帖子的术语

    enter image description here

    EDIT 1

    根据您编辑的问题,这里是新代码的精简部分。我不得不在这里废弃一到两件东西,重新安排一些元素,以使其工作。这里最大的挑战是计算百分比,因为用于计算百分比的变量是独立的foreach 循环。内的变量foreach 循环仅存在于其中foreach, 不超过

    您的编辑对代码(来自我的原始答案,@deflame code和您的集成代码)的重大更改是

    将包含职位总数、百分比和术语名称的两个表格移至$terms foreach

    将术语名称和帖子数从每个术语推送到$terms foreach

    去除石灰代码时报废,已删除$total_posts = 0; 仅保留和修改$percentage = round( (($yearly_posts_per_term->post_count / $total_posts)*100), 2 );

    已使用array_sum 从每个学期的职位计数数组中获取当年的职位总数

    已使用array_combine 使用每个术语的术语名称和post计数创建关联数组的步骤

    最后,我用了foreach 循环以获取每个术语名称和相关的post计数,并将其反馈到表中

    这是最后的代码

    <?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
    
    ?>
    
    请注意,与我原来的回答一样,我将帖子类型改为post 和分类法category 用于测试目的。

    您的最终结果是一个如下所示的表<请注意,我所有的学期名称都是用南非荷兰语命名的,因为我在我的测试网站上测试的是用南非荷兰语命名的。

    enter image description here

    ORIGINAL ANSWER

    这是我关于如何做到这一点的想法的一个非常粗略的草稿。我没有包含HTML标记,并且使用了默认的帖子类型post 以及内置分类法category 测试代码。

    下面是我如何构造完整查询的

    首先,获取网站上最早的帖子(应该是第一篇帖子)的日期。这是通过一个简单的get_posts 查询修改以满足您的需要

    $oldest = get_posts( \'post_status=publish&posts_per_page=1&order=ASC\' );
        $oldest_date = $oldest[0]->post_date;
    
    接下来,去掉返回的日期,只获取从发布日期算起的年份。使用strtotime() 函数将年份转换为Unix时间戳

    $first_date = date(\'Y\', strtotime($oldest_date));
    
    返回当前日期,您只需要年份。使用date() 作用

    $current_date = date(\'Y\');
    
    将两个日期返回到range() 用于打印两个日期之间的年份范围的函数

    $year_range = range($current_date, $first_date);
    
    将这些范围添加回foreach loop 在基于年份的列表中获取您的帖子

    我用过get_terms() 获取有关分类法的所有可用术语的列表

    $terms = get_terms(\'category\');
    
    现在,所有这些信息都需要反馈到tax_query 使用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);
    
    最后,您要返回术语名称和每个术语的帖子数量

    echo $term->name . \'(\' . $posts->post_count . \')\';
    
    现在大家一起!!

    <?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 . \')\';
            }
        }
    }
     ?>
    
    如前所述,这是可以改进的,所以采用这个想法和代码,并根据您的需要进行调整和修改。希望这有帮助。

    SO网友:adelval

    有一个比您接受的解决方案简单得多的解决方案,只需使用一个查询。我在这里为Woocommerce中的自定义post类型“product”和自定义分类“product\\u cat”(egory)进行了说明,只是因为我碰巧有一个方便的安装来测试它。这个$query 是:

    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
    
    在我的示例安装中,这将产生:

    taxonomy stats per year

    例如,2013年有10个服装职位,2012年有2个。

    你只需要打电话$wpdb->get_results($query) (并使用$wpdb->prefix而不是\'wp\\\')将此表放入数组或对象中,计算百分比并显示它们。group\\u concat列主要是为了调试而添加的(因此您可能希望删除它们),但另一方面,例如id也可以方便地用于其他处理(通过将列中的值分解为数组)。

    SO网友:icynets

    如果有人正在寻找更简单、更短的代码来只显示特定的年份,而不是运行循环来显示帖子中的所有年份。这是代码enter image description here.

    这还包括到分类术语归档的链接`

        $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>\';          
    } 
    
    `

    结束

    相关推荐

    Count > 1 Navigation Slider

    我有一个帖子类型slider, 当您有多个帖子要显示导航时。我的代码:<?php $count_slider = wp_count_posts(\'slider\'); echo $count_slider->publish; ?> <?php if($count_slider > 1): ?> <div id=\"slideshowcontrol\" class=\"clearfi