私は与えられたカスタム分類学用語の中の投稿の数で統計のような表を作り、その年からの総投稿数と共に年ごとにそれらを表示したいです。
例えば:
2014
| _分類学用語A:8件の投稿
| _分類学用語B:12件の投稿
2014年の総投稿数: 20の投稿
この関数は明らかに以下のことをする必要があります。
年の動的リストを作るために 、私はどこかで見つけたスニペットを使いました、そしてそれはこのように見えます:
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; ?>
私の質問です:
年ごとの分類期間ごとの投稿数を出力できるようにwp_queryを作成する方法を教えてください。誰かが私がそれを整理するのを手伝ってくれたら私はとてもうれしいです。
シモンズ:私はすでに分類学用語ごとの私のカスタムポストタイプからのすべての公開されたポストを数えるテーブルを持っています、私は助けを見つけました ここ そしてdeflimeのコードを使いました。
編集:
これは私の修正を含む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
編集2
これはEDIT 1のコードの別のバージョンです。このコードはもっとずっと速いです。これがEDIT 1とEDIT 2のコードの間のテストです。
EDIT 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
?>
これはEDIT 1の表と同じ出力を表示しますが、空の用語は表示されず、投稿のある用語のみが表示されます。
編集1
編集した質問から、これが新しいコードの削除です。私はここで1つか2つのことをスクラップし、この仕事をするためにいくつかの要素を並べ替える必要がありました。ここでの大きな課題は、パーセンテージを計算することでした。これを計算するために使用される変数は別々のforeach
ループに存在していたからです。 foreach
ループ内の変数はそのforeach
内にのみ存在し、outsieには存在しません。
あなたの編集からの(私の最初の答え、@deflimeコードとあなたの統合されたコードからの)コードへの大きな変更はあります。
総投稿数と割合と用語名を保持する2つのテーブルを$terms
foreach
ループのすぐ下の外側に移動しました
用語名と投稿数を各用語から$terms
foreach
ループの外側の配列にプッシュしました
@deflimeコードを破棄し、$total_posts = 0;
を削除し、$percentage = round( (($yearly_posts_per_term->post_count / $total_posts)*100), 2 );
のみを保持および変更しました
期間ごとの投稿数の配列から、その年の投稿の総数を取得するために array_sum
を使用しました
array_combine
を使用して、用語名と各用語の投稿数を含む連想配列を作成しました。
最後に、foreach
ループを使用して各用語名と関連する投稿数を取得し、それをテーブルにフィードバックしました。
これが最終的なコードです。
<?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
に変更しました。
あなたの最終結果はこのように見えるテーブルです。 注意してください私はアフリカーンス語にある私のテストサイトでそれをテストしたので私の名前はすべてアフリカーンス語にあります。
元の答え
これは私がこれを行う方法について私が持っていたアイデアの非常に大まかなドラフトです。私は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');
2つの日付の間の年の範囲を印刷するには、両方の日付を 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);
最後に、用語名と1用語あたりの投稿数を返します。
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 . ')';
}
}
}
?>
すでに述べたように、これは洗練されたものになる可能性があるので、このアイデアとコードを取り入れて、必要に応じて調整および変更します。お役に立てれば。
1つのクエリだけを使用して、あなたが受け入れたものよりもはるかに簡単な解決策があります。ここでは、私がたまたまそれをテストするのに便利なインストールがあるという理由だけで、Woocommerceのカスタム投稿タイプ 'product'とカスタム分類法 'product_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
私のサンプルインストールでは、これは次のようになります。
そのため、たとえば、2013年には10の投稿、2012年には2の投稿があります。
このテーブルを配列またはオブジェクトにしてパーセンテージを計算して表示するには、$wpdb->get_results($query)
を呼び出して(そして 'wp_'の代わりに$ wpdb-> prefixを使用するだけ)必要があります。 group_concat列は主にデバッグのために追加されます(したがって、おそらく削除する必要があります)が、idなどの他の処理にも便利です(列の値を配列に展開することによって)。
投稿からすべての年を表示するためのループを実行する代わりに、誰かが特定の年だけを表示するためのより簡単で短いコードを探している場合。これはコードです 。
これは分類学用語アーカイブへのリンクも含みます。 `
$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>';
}
`