conta as mensagens de termos de taxonomia personalizados por ano

4

Eu quero criar tabelas semelhantes a estatísticas com a contagem de postagens em determinados termos de taxonomia personalizada e exibi-las por ano, juntamente com a contagem total de postagens daquele ano.

Por exemplo:

  

2014

     

| _Termo de Taxonomia A: 8 posts

     

| _ Termo da taxonomia B: 12 posts

     

Total de postagens em 2014: 20 postagens

A função obviamente precisa fazer o seguinte:

  • conta as postagens do meu tipo de postagem personalizado que foram publicadas em 2014, 2013, ... (contagem total por ano)
  • conte as postagens em cada termo de taxonomia de my-custom-taxonomy na base anual

Para criar uma lista dinâmica para os anos , usei um snippet que encontrei em algum lugar e ficou assim:

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

No meu modelo de página personalizado, eu uso:

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

A minha pergunta é:

Como eu construo o wp_query para poder produzir a contagem de posts por termo de taxonomia por ano? Eu ficaria muito feliz se alguém me ajudasse a resolver isso.

PS: Já tenho uma tabela contando TODAS as postagens publicadas do meu termo personalizado-por tipo de taxonomia, encontrei ajuda aqui e usou o código do deflime.

Editar:

Este é o trecho de Pieter Goosen incluindo minhas modificações:

$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
    
por okiedokey 11.08.2014 / 11:58

3 respostas

4

EDIT 2

Aqui está outra versão do código em EDIT 1 . Este código é muito mais rápido. Aqui está o meu teste entre o código em EDIT 1 e EDIT 2

  • EDIT 1 Tempo de consulta do banco de dados = +/- 0,25 e consultas do banco de dados = 69

  • EDIT 2 Tempo de consulta do banco de dados = +/- 0,07 e consultas do banco de dados = 29

Aqui está o código

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

?>

Isso processa a mesma saída que a tabela em EDIT 1 , exceto que ela não mostra termos vazios, apenas termos com postagens são mostrados

EDIT1

Desuaperguntaeditada,aquiestáalistadonovocódigo.Eutivequedesfazerumaouduascoisasaquiereorganizaralgunselementosparafazerissofuncionar.Ograndedesafioaquifoicalcularasporcentagens,porqueasvariáveisusadasparacalcularissoviviamemforeachloopsseparados.Variáveisdentrodeforeachloopssóvivemdentrodeforeach,nãooutsie

Asgrandesmudançasnocódigo(daminharespostaoriginal,código@deflimeeseucódigointegrado)dasuaediçãosão

  • Asduastabelasforammantidascomototaldepostagenscontabilizadaseasporcentagenseosnomesdetermosparafora,logoabaixodo$termsforeachloop

  • Osnomeseaspostagensdostermosforamcontadosdecadatermoparaumamatrizforadoloop$termsforeach

  • Código@deflimedesfeito,removido$total_posts=0;emantidoemodificadoapenas$percentage=round((($yearly_posts_per_term->post_count/$total_posts)*100),2);

  • Usado array_sum para obter o total de postagens do ano da matriz de contagens de postagem por termo

  • Usado array_combine para criar uma matriz associativa com os termos nomes e post contagens de cada termo

  • Finalmente, usei um foreach loop para obter o nome de cada termo e a contagem de postagens associada, para alimentar isso de volta na tabela

Aqui está o código 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

?>

Por favor, note Como na minha resposta original, eu mudei o tipo de post para post e taxonomia para category para fins de teste.

Seu resultado final é uma tabela parecida com essa. Por favor note Todos os nomes dos meus termos estão em Afrikaans enquanto eu os testei no meu site de teste que está em Afrikaans.

RESPOSTAORIGINAL

Esteéumesboçomuitogrosseirodeumaideiaquetivesobrecomofazerisso.NãoincluínenhumamarcaçãoHTMLeuseiotipodepostagempadrãoposteataxonomiadeincorporaçãocategoryparatestarocódigo.

Vejacomoeuconstruíaconsultacompleta

  • Primeiro,obtenhaadatadopostmaisantigo(deveseroprimeiropost)nosite.Issoéfeitopormeiodeumasimplesconsulta get_posts . Modifique para atender às suas necessidades

    $oldest = get_posts( 'post_status=publish&posts_per_page=1&order=ASC' );
        $oldest_date = $oldest[0]->post_date;
    
  • Em seguida, retire a data de devolução para obter apenas o ano a partir da data da postagem. Use a função strtotime() para converter o ano em um timestamp Unix

    $first_date = date('Y', strtotime($oldest_date));
    
  • Retorna a data atual, você desejaria apenas o ano. Use a função date()

    $current_date = date('Y');
    
  • Retorne as duas datas para a função range() para imprimir um intervalo de anos entre as duas datas

    $year_range = range($current_date, $first_date);
    
  • Adicione esses intervalos a foreach loop para obter suas postagens em listas com base no ano

  • Eu usei get_terms() para listar todos os termos disponíveis da taxonomia em questão

    $terms = get_terms('category');
    
  • Agora, todas essas informações precisam ser inseridas em tax_query usando 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);
    
  • Por fim, você deseja retornar o nome do termo e a quantidade de postagens por termo

    echo $term->name . '(' . $posts->post_count . ')';
    

Agora todos juntos !!

<?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 . ')';
        }
    }
}
 ?>

Como dito, isso pode ser refinado, então pegue essa ideia e codifique e adapte e modifique como achar melhor. Espero que isso ajude.

    
por Pieter Goosen 11.08.2014 / 21:22
1

Existe uma solução muito mais simples do que aquela que você aceitou, usando apenas uma única consulta. Ilustro aqui o tipo de mensagem personalizada 'product' e a taxonomia personalizada 'product_cat' (egory) no Woocommerce, só porque tenho uma instalação útil para testá-la. O $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

Na minha instalação de amostra, isso gera:

Então, por exemplo, há 10 postagens de Roupas em 2013 e 2 em 2012.

Você só precisa chamar $wpdb->get_results($query) (e usar o prefixo $ wpdb- > em vez de 'wp_') para obter essa tabela em uma matriz ou objeto, calcular as porcentagens e exibi-las. As colunas group_concat são adicionadas principalmente para depuração (portanto, você provavelmente deseja removê-las), embora, por outro lado, as id's também possam ser úteis para outros processamentos (explodindo valores na coluna em arrays).

    
por adelval 17.08.2014 / 16:30
0

No caso de alguém estar procurando por um código menor mais fácil para exibir apenas um ano específico, em vez de executar um loop para exibir todos os anos do post. Este é o código .

Issotambémincluiolinkparaoarquivodetermosdetaxonomia.'

$terms=get_terms('your-taxonomy');//grabthetaxonomyname$year=2015;//Theyearyouwanttopullthetermsandcountfromif(!empty($terms)&&!is_wp_error($terms)){echo'<divclass="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>';          
} 

'

    
por icyNETS 20.11.2015 / 21:59