如何按年和月对 Wordpress 帖子进行分组?

How to group Wordpress posts in years and then months?

我正在尝试创建一个带有 post 查询并在输出中具有以下结构的函数:

    2021
      January
        1.Post Title
        2.Post Title
      March
        3.Post Title

    2020
      May
        4.Post Title

这是我到目前为止所做的:

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();

问题是多月的同一年没有分组在一个元素中..

当前输出:

    2021
      January
        1.Post Title
        2.Post Title
    
    2021
      March
        3.Post Title
    
    2020
      May
        4.Post Title

像这样创建一个多维数组并打印出来。你可能会得到合适的结果。

$master = [];

foreach ( $posts as $post ) {
    setup_postdata( $post );

    $time = strtotime( $post->post_date );
    $year = date( 'Y', $time );
    $mon = date( 'F', $time );
    
    $master[$year][$mon][] = $post;
}

wp_reset_postdata();

echo '<pre>';
print_r($master);
echo '</pre>';

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.

正如我们在 上讨论的那样,当您使用 get_posts 时,它将 return post objects。每个 post object 包含以下 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] =>
)

例如,如果您需要 titlecontentauthorexerpt 的 post,那么您可以创建一个多维的数组并使用 array_push 函数创建自定义数组,如下所示:

$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();

对于debugging/investigating数组,你可以使用这个:

echo "<pre>";
print_r($your_custom_array_yearly);
echo "</pre>";

既然您已经有了自己的自定义数组,那么您可以遍历它并输出您的数据:

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

以上代码会输出如下结果:

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