Issue
I am trying to create a function with post query and with following structure in output:
2021 January 1.Post Title 2.Post Title March 3.Post Title 2020 May 4.Post Title
Here is what I’ve done so far:
global $post;
$posts = get_posts( array(
'post_type' => 'history',
'orderby' => 'date'
) );
$_year_mon = '';
$_has_grp = false;
foreach ( $posts as $post ) {
setup_postdata( $post );
$time = strtotime( $post->post_date );
$year = date( 'Y', $time );
$mon = date( 'F', $time );
$year_mon = "$year-$mon";
if ( $year_mon !== $_year_mon ) {
// Close previous group, if any.
if ( $_has_grp ) {
echo '</div>';
echo '</div>';
}
$_has_grp = true;
echo '<div class="year">';
echo "<span>$year</span>";
echo '<div class="month">';
echo "<span>$mon</span>";
}
// Display post title.
if ( $title = get_the_title() ) {
echo "<div>$title</div>";
} else {
echo "<div>#{$post->ID}</div>";
}
$_year_mon = $year_mon;
}
if ( $_has_grp ) {
echo '</div>';
echo '</div>';
}
wp_reset_postdata();
The problem is that same year with multiple month is not grouped in one element..
Current output:
2021 January 1.Post Title 2.Post Title 2021 March 3.Post Title 2020 May 4.Post Title
Solution
The following solution has been fully tested and works seamlessly fine for the default wordpress
post
type. If you want to run it for your custome post type that has its own custom fields then you may encounter some discrepancies. Therefore, feel free to customize it for your own custom post type as needed.
As we talked on this question, when you use get_posts
it will return post objects
. Each post object
contains the following properties/data:
WP_Post Object
(
[ID] =>
[post_author] =>
[post_date] =>
[post_date_gmt] =>
[post_content] =>
[post_title] =>
[post_excerpt] =>
[post_status] =>
[comment_status] =>
[ping_status] =>
[post_password] =>
[post_name] =>
[to_ping] =>
[pinged] =>
[post_modified] =>
[post_modified_gmt] =>
[post_content_filtered] =>
[post_parent] =>
[guid] =>
[menu_order] =>
[post_type] =>
[post_mime_type] =>
[comment_count] =>
[filter] =>
)
For example if you need, title
, content
, author
, exerpt
of the post, then you could create a multi-dimensional array and use array_push
function to create your custom array like so:
$posts = get_posts(array(
'post_type' => 'history', // Since 'history' is a custom post type, I tested it on 'post'
//'post_type' => 'post'
'posts_per_page' => -1,
'orderby' => 'date'
));
// You could see the number of posts for your query
echo "Number of posts found: ". count($posts) . "<br>";
$your_custom_array_yearly = array();
foreach ($posts as $post) {
setup_postdata($post);
$time = strtotime($post->post_date);
$year = date('Y', $time);
$mon = date('F', $time);
if (!($your_custom_array_yearly[$year][$mon])) {
$your_custom_array_yearly[$year][$mon] = array();
array_push(
$your_custom_array_yearly[$year][$mon],
[
'title' => $post->post_title,
'excerpt' => $post->post_excerpt,
'author' => $post->post_author,
'content' => $post->post_content,
]
);
} else {
array_push(
$your_custom_array_yearly[$year][$mon],
[
'title' => $post->post_title,
'excerpt' => $post->post_excerpt,
'author' => $post->post_author,
'content' => $post->post_content,
]
);
};
}
wp_reset_postdata();
For debugging/investigating the array, you could use this:
echo "<pre>";
print_r($your_custom_array_yearly);
echo "</pre>";
Now that you have your own custom array, then you could loop through it and output your data:
foreach ((array)$your_custom_array_yearly as $yearly => $yvalue) {
echo $yearly . ": <br>";
echo "<ul>";
foreach ($yvalue as $monthly => $mvalue) {
echo "<li>" . $monthly . ": </li><ul>";
foreach ($mvalue as $monthly_k => $monthly_v) {
foreach ($monthly_v as $post_title_k => $post_title_v) {
echo "<li>" . $post_title_k . ": " . $post_title_v . "</li></ul>";
}
}
}
echo "</ul>";
}
The above code will output the following result:
2021:
January:
1.Title: Post Title
1.Excerpt: Post excerpt
1.Author: Post author
1.Content: Post content
2.Title: Post Title
2.Excerpt: Post excerpt
2.Author: Post author
2.Content: Post content
March:
3.Title: Post Title
3.Excerpt: Post excerpt
3.Author: Post author
3.Content: Post content
2020:
May:
4.Title: Post Title
4.Excerpt: Post excerpt
4.Author: Post author
4.Content: Post content
Answered By – Ruvee
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0