WordPress(按自定义日期字段排序WP_Query并在每个月后拆分循环)

我正在使用WordPress自定义帖子类型来管理和显示网站上的事件。为了对事件进行排序, 我使用了带有日期的自定义元字段(存储方式如下:YYYY-MM-DD)。我对照当前日期检查meta字段。像这样:

$current_date_query = date ('Y-m-d'); $temp = $wp_query; $wp_query= null; $wp_query = new WP_Query(); $wp_query-> query( array( 'post_type' => 'event', 'meta_key' => 'event_date', 'meta_compare' => '> =', 'meta_value' => $current_date_query, 'post_status' => 'publish', 'posts_per_page' => '99', 'orderby' => 'meta_value', 'order' => 'ASC', 'paged' => $paged ) ); ?> ... Loop stuff ...< ?php endif; $wp_query = null; $wp_query = $temp; wp_reset_query(); ?>

我现在想在每个新月之前添加一个标题。像这样:
一月2018
  • Event 1
  • Event 2
  • Event 3
2018年2月
  • Event 4
  • Event 5
2018年三月
  • Event 5
等等…
有没有办法在每个月后拆分循环?我想我必须使用meta字段中的月份, 但我不知道如何使用。
我尝试了以下解决方案(由于@FluffyKitten的评论):
< ?php/* declare an array to save the data */ $quarters = array(); foreach($posts as $q) {$donor_date = get_post_meta($q-> ID, 'gid_22', true); $donor_month = date('m', strtotime($donor_date)); /* format the date once - best practice is not to repeat code */ $formatteddate = date('d/m/Y', strtotime($donor_date)); /* organise the dates by quarter, using the heading as the key for easy display */ if(in_array($donor_month, array('01'))) $quarters["January"][] = $formatteddate; else if(in_array($donor_month, array('02'))) $quarters["February"][] = $formatteddate; else if(in_array($donor_month, array('03'))) $quarters["March"][] = $formatteddate; else if(in_array($donor_month, array('04'))) $quarters["April"][] = $formatteddate; else if(in_array($donor_month, array('05'))) $quarters["May"][] = $formatteddate; else if(in_array($donor_month, array('06'))) $quarters["June"][] = $formatteddate; else if(in_array($donor_month, array('07'))) $quarters["July"][] = $formatteddate; else if(in_array($donor_month, array('08'))) $quarters["August"][] = $formatteddate; else if(in_array($donor_month, array('09'))) $quarters["September"][] = $formatteddate; else if(in_array($donor_month, array('10'))) $quarters["Ocotber"][] = $formatteddate; else if(in_array($donor_month, array('11'))) $quarters["November"][] = $formatteddate; else if(in_array($donor_month, array('12'))) $quarters["December"][] = $formatteddate; } /* now go through your array and display the results */ foreach ($quarters as $quartername => $quarter){ /* $quarters won't have any entry for quarters with no dates, so technically this 'if' isn't needed, however I've added it in case it will be needed it for any other changes you make */ if ($quarter){ ?> < h3> < ?php echo $quartername; ?> < /h3> < table> < ?phpforeach ($quarter as $qdate ){ ?> < tr> < td> < ?php echo $qdate; ?> < /td> < /tr> < ?php}// end foreach($quarter...) ?> < /table> < ?php } // end if } // end foreach($quarters...) ?>

现在我得到这样的结果:
Ocotber
  • 02/10/2018
  • 2017/10/29
一月
  • 2018/02/01
十二月
  • 2017/02/12
  • 2017年1月12日
可以
  • 02/05/2018

订单基于过帐日期, 而不基于自定义字段。年份之间也没有差异。 2017年应该与2018年一样都有自己的循环。
如果我尝试将自己的数组放在循环的第一个数组中, 则它没有任何作用, 并且仅在前端显示为文本。
编辑:我可以通过使用这样的自定义查询来订购月份:
$posts = query_posts( array( 'post_type' => 'event', 'meta_key' => 'event_date', 'meta_compare' => '> =', 'meta_value' => $current_date_query, 'post_status' => 'publish', 'posts_per_page' => '99', 'orderby' => 'meta_value', 'order' => 'ASC', 'paged' => $paged ) );

现在的问题只是一年。都是按月排序的, 每个月都有不同的年份。
#1你从@FluffyKitten尝试的解决方案无法正常工作, 因为它分为同一个月(而不是同一年和同一年)的分组, 因此当不同年份的同一月中有帖子时, 该解决方案将失效
正如@ChinLeung所建议的那样, 你需要将当前月份存储在变量中, 以测试它是否已更改并输出标头。要为你的示例实现此功能, 请执行以下操作:
// Set current month $current_month = ''; // Get event posts in order $events = query_posts( array( 'post_type' => 'event', 'meta_key' => 'event_date', 'meta_compare' => '> =', 'meta_value' => date ('Y-m-d'), 'meta_type'=> 'DATE', 'post_status' => 'publish', 'posts_per_page' => '99', 'orderby' => 'meta_value', 'order' => 'ASC', 'paged' => $paged ) ); // Iterate over events foreach($events as $key => $event){// Get event date from post meta $event_date = get_post_meta($event-> ID, 'event_date', $single = true); // Cache event month/year $event_month = date('F Y', strtotime($event_date)); // Open new group if new month if($current_month != $event_month){ if($key !== 0) echo '< /ul> '; echo "< h2> {$event_month}< /h2> "; echo '< ul> '; }// Add event date as new list item echo "< li> {$event_date}< /li> "; // Cache $curret_month $current_month = $event_month; }// Close the last list if query had events if(count($events)) echo '< /ul> ';

编辑要更新此解决方案以使其适用于帖子类型存档, 请代替以上内容, 将以下内容添加到主题的functions.php或其中包含的文件中:
/** * Get event date * * @return string */ function get_event_date() {/** @global WP_Post $post */ global $post; /** Get event date from post meta */ return get_post_meta($post-> ID, 'event_date', $single = true); }/** * Get event month/year formatted * * @param string $event_date * * @return string */ function format_event_date($event_date) { return date('F Y', strtotime($event_date)); }/** * Order events archive by event date post meta * * @param WP_Query $query * * @return WP_Query */ function events_archive_pre_get_posts($query) { if (!$query-> is_main_query() || !is_post_type_archive('event')) return $query; $query-> set('meta_key', 'event_date'); $query-> set('meta_compare', '> ='); $query-> set('meta_value', date('Y-m-d')); $query-> set('meta_type', 'DATE'); $query-> set('posts_per_page', 2); $query-> set('orderby', 'meta_value'); $query-> set('order', 'ASC'); return $query; }add_filter('pre_get_posts', 'events_archive_pre_get_posts');

然后, 你可以将每页的帖子设置为所需的数量, 分页将按预期工作。这是一个示例帖子类型存档模板, 可用于在格式整齐的HTML列表之间添加日期标头, 或者至少在SO转换制表符到空格之前添加日期标头:
< ?php // Template header get_header(); ?> < ?php /** @global WP_Query */ global $wp_query; ?> < ?php // Events archive loop for($previous_month = ''; have_posts(); $previous_month = $formatted_date): the_post(); // Get event date from post meta $event_date = get_event_date(); // Format event month/year $formatted_date = format_event_date($event_date); // The formatted date is the first or not the same as previous event if($previous_month != $formatted_date):// Close previous list if this is not the first if($wp_query-> current_post !== 0) echo "\n\t< /ul> \n"; // New month template ?> < h2> < ?php echo $formatted_date; ?> < /h2> < ?php // Open new list echo "\t< ul> \n"; endif; // Event post template ?> < li> < ?php echo $event_date; ?> < /li> < ?php endfor; // Reset query wp_reset_query(); // Close the last list if query had events if(have_posts()) echo "\t< /ul> \n"; ?> < ?php // Pagination the_posts_pagination(); ?> < ?php // Template footer get_footer();

#2你可以将当前循环月份存储在变量中, 并检查是否仍在同一月份循环。
【WordPress(按自定义日期字段排序WP_Query并在每个月后拆分循环)】假设$ events是要显示为WP_Post实例的所有事件的数组。
$current = 0; foreach($events as $event){$eventDate = get_field('event_date', $event-> ID); $month = date('m', strtotime($eventDate)); // New month if($current != $month){ $current = $month; // Perform actions of new month }// Perform normal actions for the event}

    推荐阅读