I am trying to build an Custom Post Type for showing information about events. The Custom Post Type has name 'Event', with the following meta fields:
This works fine for the single-event listing, however in the archive listing I would like to see a grouping like:
I have found some questions and answers on using wp_get_archives(), however this seems to group the posts by published date, rather on the actual date of the event (event.startdate). I also found some posts on sorting by metavalue, however not grouping. Thanks in advance for any advice or hint on how to accomplish this!
I am trying to build an Custom Post Type for showing information about events. The Custom Post Type has name 'Event', with the following meta fields:
This works fine for the single-event listing, however in the archive listing I would like to see a grouping like:
I have found some questions and answers on using wp_get_archives(), however this seems to group the posts by published date, rather on the actual date of the event (event.startdate). I also found some posts on sorting by metavalue, however not grouping. Thanks in advance for any advice or hint on how to accomplish this!
OK, so this problem has two parts:
You can use pre_get_posts
to achieve this.
add_action( 'pre_get_posts', function ( $query ) {
if ( is_post_type_archive( 'event' ) && $query->is_main_query() ) {
$query->set( 'orderby', 'meta_value' );
$query->set( 'order', 'ASC' );
$query->set( 'meta_key', 'event_startdate' );
}
} );
So now events will be sorted ascending by start_date.
You'll have to modify the archive-event.php
file, so these events get in their groups.
<?php
$current_year = $current_month = '';
while ( have_posts() ) :
the_post();
$last_year = $current_year;
$last_month = $current_month;
$current_year = date( 'Y', strtotime( get_post_meta( get_the_ID(), 'event_startdate', true ) ) );
if ( $last_year != $current_year ) {
$last_month = '';
}
$current_month = date( 'F', strtotime( get_post_meta( get_the_ID(), 'event_startdate', true ) ) );
?>
<?php if ( $last_year != $current_year ) : ?><h2><?php echo $current_year; ?></h2><?php endif; ?>
<?php if ( $last_month != $current_month ) : ?><h3><?php echo $current_month; ?></h3><?php endif; ?>
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
<?php endwhile; ?>
Based on the code from @krzysiek-dróżdż my archive-eventi.php
is now like below. Posting it here incase anyone else is trying to achieve the same thing. Note that the event custom post type is named eventi
.
<?php
/**
* The template for displaying event archive
*
* @package Eventi
* @since 1.0.0
*/
get_header();
?>
<section id="primary" class="content-area">
<main id="main" class="site-main">
<?php
if ( have_posts() ) :
?>
<header class="page-header">
<?php
the_archive_title( '<h1 class="page-title">', '</h1>' );
?>
</header><!-- .page-header -->
<?php
// Start the Loop.
$args = [
'post_status' => 'publish',
'post_type' => 'eventi',
'posts_per_page' => 100,
'orderby' => 'meta_value',
'order' => 'ASC',
'meta_type' => 'DATE',
'meta_key' => 'eventi_startdate',
];
$posts = new WP_Query( $args );
$current_year = '';
$current_month = '';
while ( $posts->have_posts() ) {
?>
<article id="event-<?php the_ID(); ?>" <?php post_class(); ?>>
<div class="entry-content">
<?php
$posts->the_post();
$post_id = get_the_id();
$startdate = strtotime( get_post_meta( $post_id, 'eventi_startdate', true ) );
$enddate = strtotime( get_post_meta( $post_id, 'eventi_enddate', true ) );
$dateformat = get_option( 'date_format' );
$last_year = $current_year;
$last_month = $current_month;
$current_year = date_i18n( 'Y', $startdate );
if ( $last_year != $current_year ) {
$last_month = '';
}
$current_month = date_i18n( 'F', $startdate );
if ( $last_year != $current_year ) {
echo '<h2>' . $current_year . '</h2>';
}
if ( $last_month != $current_month ) {
echo '<h3>' . $current_month . '</h3>';
}
$post_id = get_the_ID();
if ( is_sticky() && is_home() && ! is_paged() ) {
printf( '<span class="sticky-post">%s</span>', _x( 'Featured', 'post', 'eventi' ) );
}
echo '<a href="' . esc_url( get_permalink() ) . '" class="event-details-link">' . get_the_title() . '</a>';
echo ' — ' . get_the_excerpt();
// Date and times
echo ' — ' . date_i18n( $dateformat, $startdate );
if ( $startdate !== $enddate ) {
echo ' - ' . date_i18n( $dateformat, $enddate );
}
?>
</div>
</article>
<?php
}
wp_reset_postdata();
// If no content, include the "No posts found" template.
else :
?>
<section class="no-results not-found">
<header class="page-header">
<h1 class="page-title"><?php _e( 'No events yet!', 'eventi' ); ?></h1>
</header><!-- .page-header -->
<div class="page-content">
<?php
if ( current_user_can( 'publish_posts' ) ) :
printf(
'<p>' . wp_kses(
/* translators: 1: link to WP admin new post page. */
__( 'Ready to publish your first event? <a href="%1$s">Get started here</a>.', 'eventi' ),
array(
'a' => array(
'href' => array(),
),
)
) . '</p>',
esc_url( admin_url( 'post-new.php?post_type=eventi' ) )
);
else :
?>
<p><?php _e( 'It seems we can’t find any events.', 'eventi' ); ?></p>
<?php
endif;
?>
</div><!-- .page-content -->
</section><!-- .no-results -->
<?php
endif;
?>
</main><!-- #main -->
</section><!-- #primary -->
<?php
get_footer();