Skip to main content

Listing Tagged Events in Event Calendar Pro

A quick and easy way to extend the Events Calendar Pro WordPress plugin to list all events based on a tag (in a series) without a plugin.
March 21, 2024

A friend of mine was having some problems using the Events Calendar Pro plugin where he wasn’t able to list events individually by a specific tag that’s part of a series.

We thought he could list all events with a given tag by calling out the shortcode “tribe_events_list” and adding the target tag like this: 

[tribe_events_list tag="my-tag"]

But what gets displayed is just the first upcoming event of the tagged series. There is a small “Event Series” icon that takes you to the page of all upcoming events tagged with that series, but it doesn’t display all of those tagged events in a list.

To overcome this without having to further bloat WordPress with yet another plugin to pay for and manage, I’ve created a short function (events_by_tag) that I’ve added to his theme’s “function.php” file that lets us workaround this issue.

But first, a couple of assumptions …

Shortcode example:

[events_by_tag tag="car-shows" limit="3"]

The code to add to Your “functions.php” file:

I’ve tried to keep this as simple as possible so that it will be easy for you to understand and tweak to your own liking. Adding a tag is required and all upcoming events will be shown unless you add a limiter.
// =========================================================================
// List events by tag
// =========================================================================

function list_events_by_tag($atts) {
  $atts = shortcode_atts(array(
    'tag' => '',
    'limit' => -1,
  ), $atts, 'events_by_tag');

  $tag = $atts['tag'];
  $limit = intval($atts['limit']);

  if(empty($tag)) {
    return 'Please specify a tag for events.';
  }

  $args = array(
    'post_type' => 'tribe_events',
    'posts_per_page' => $limit,
    'tax_query' => array(
      array(
        'taxonomy' => 'post_tag',
        'field' => 'slug',
        'terms' => $tag,
      ),
    ),
  );

  $query = new WP_Query($args);

  if(!$query->have_posts()) {
    return 'Sorry, but there are no upcoming events to show.';
  }

  ob_start();

  echo '<div class="events-by-tag">';

  while($query->have_posts()): $query->the_post();

    $event_id = get_the_ID();
    $start_date = tribe_get_start_date($event_id, false, 'c');
    $start_time = tribe_get_start_time($event_id);
    $end_time = tribe_get_end_time($event_id);
    $event_month = tribe_get_start_date($event_id, false, 'M');
    $event_day = tribe_get_start_date($event_id, false, 'd');
    $permalink = get_permalink($event_id);

    ?>
    <div class="events-by-tag-row">

      <h3><a href="<?php echo esc_url($permalink); ?>" title="<?php the_title_attribute(); ?>" rel="bookmark"><?php the_title(); ?></a></h3>

      <div class="events-by-tag-date-time">

        <time class="events-by-tag-date" datetime="<?php echo esc_attr($start_date); ?>">
          <span class="events-by-tag-month"><?php echo esc_html($event_month); ?></span>
          <span class="events-by-tag-day"><?php echo esc_html($event_day); ?></span>
        </time>

        <span class="events-by-tag-divider">|</span>

        <time class="events-by-tag-time">
          <span class="events-by-tag-start"><?php echo esc_html($start_time); ?></span> - <span class="events-by-tag-end"><?php echo esc_html($end_time); ?></span>
        </time>

      </div>

  </div>
  <?php

  endwhile;

  echo '</div>';

  wp_reset_postdata();

  $output = ob_get_clean();
  return $output;
}
add_shortcode('events_by_tag', 'list_events_by_tag');

A little CSS to get you started:

Instead of using Modern Tribe’s intricate CSS selectors that you don’t have much control over, I’ve tried to simplify the code so that it’s more cleaner and more intuitive. This choice is aimed at simplifying the customization process for you, making it more accessible to apply your own styles and adjustments and to better fit into whatever theme you have.

Also, this uses a calendar icon provided by FontAwesome. You’ll need to add in your own FontAwesome kit details (or find a CDN to link from). You don’t have to use the icon…it’s just there to make it pretty.

.events-by-tag { margin: 0 0 20px; }
.events-by-tag-row {
  position: relative;
  display: block;
  padding: 10px 20px;
  margin: 0 0 2px 0;
  cursor: pointer;
  border-radius: 6px;
}
.events-by-tag-row, .events-by-tag-row a { transition: .2s ease-in-out; }
.events-by-tag-row:hover { background: rgba(255,255,255,0.5); }
.events-by-tag-row h3:before {
  content: "\f133";
  font: normal normal normal 18px/1 FontAwesome;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  position: absolute;
  top: 13px;
  left: 10px;
}
.events-by-tag-row h3:before, .events-by-tag-row a {
  color: #31518b;
  text-decoration: none;
}
.events-by-tag-row:hover a, .events-by-tag-row:hover h3:before { color: #ce362b; }
.events-by-tag-row i { margin-right: 5px; }
.events-by-tag-row h3, .events-by-tag-date-time { margin: 0 0 0 15px; }
.events-by-tag-date-time { font-size: 0.8rem; }
.events-by-tag-divider {
  opacity: 0.5;
  margin: 0 5px;
}
.events-by-tag-date { }
.events-by-tag-month { }
.events-by-tag-day { }
.events-by-tag-time { }
.events-by-tag-start { }
.events-by-tag-end { }
I hope this helps!

What do you think?

Your email address will not be published. Required fields are marked *