Using Custom Field Data in Pie Calendar Popover

This option is available from Pie Calendar Free 1.2.3 and Pie Calendar Pro 1.3.2.

Sometimes you need to insert custom data into your event popover. This can be data such as additional event details, venues, images, and more.

Pie Calendar offers hooks and filters that allow you to make any data available in the popover, and then display it using HTML, PHP, and JS.

Here is a quick example, followed by an explanation:

// Step 1, add the required custom field data to the event array so that it's available in the Pie Calendar JavaScript.
add_filter('piecal_event_array_filter', function( $event ) {
    if( !get_the_ID() ) {
        return $event;
    }

    // Get custom field data and assign it to the event array
    $event['venue'] = get_field('venue');

    return $event;
}, 10, 4);

// Step 2, make sure this data is passed to the calendarEngine object on event click so it can be output in the popover.
// Properties added this way are always located under info.event._def.extendedProps
add_action('piecal_additional_event_click_js', function() {
    ?>
    Alpine.store("calendarEngine").venue = info.event._def.extendedProps.venue;
    <?php
}, 10, 0);

// Step 3, output the data in the popover using Alpine
// Available locations include: 
// piecal_popover_before_title
// piecal_popover_after_title
// piecal_popover_before_meta
// piecal_popover_after_meta
// piecal_popover_before_details
// piecal_popover_after_details
// piecal_popover_before_view_link
function my_inject_custom_field_in_popover( $atts ) {
	// Note: $atts is available so you can check for shortcode attributes before making modificats, e.g. make sure showcustomfields=true.
	ob_start();
	?>
		<style>
		.piecal_popover_custom_field {
		border-radius: 8px;
		padding: 12px;
		background: #EFEFEF;
		}
		</style>
		<p class="piecal_popover_custom_field" x-show="$store.calendarEngine.venue" x-text="'Venue: ' + $store.calendarEngine.venue"></p>
	<?php
	echo ob_get_clean();
}

add_action( 'piecal_popover_before_details', 'my_inject_custom_field_in_popover', 10, 1 );

In order to display custom data in the popover, there are three important steps involved in making the data available and outputting it.

Step 1: Add the data to the event array.

In PHP, Pie Calendar events are arrays. They have properties that are used later by FullCalendar.js as object properties. If you want some data that's available in PHP to be available in JavaScript when using Pie Calendar, you must first make sure that data is a part of the event array.

// Step 1, add the required custom field data to the event array so that it's available in the Pie Calendar JavaScript.
add_filter('piecal_event_array_filter', function( $event ) {
    if( !get_the_ID() ) {
        return $event;
    }

    // Get custom field data and assign it to the event array
    $event['venue'] = get_field('venue');

    return $event;
}, 10, 4);

This code uses the Advanced Custom Fields (ACF) function get_field(), but you can use get_post_meta() or any other PHP function to assign a value to any arbitrary event array key. In this case, we create and assign a value to the key 'venue'. This means later, we can use this value in JavaScript via info.event._def.extendedProps.venue.

Step 2: Pass the clicked event's custom properties to the calendarEngine object.

The calendarEngine object temporarily holds the values for any post that is clicked. This allows us to use Alpine.js to render those values in the popover. Because of this approach, custom values (e.g. our venue value) must be assigned when an event is clicked. This is because the same popover is used for every event, and we just swap the data out on click.

The upside of this approach is, no matter how many events you have, there will only ever be one popover, which will reduce the size of your markup and avoid impacting the performance of your page negatively.

Let's take a look at how to pass our custom venue data to the calendarEngine object.

// Step 2, make sure this data is passed to the calendarEngine object on event click so it can be output in the popover.
// Properties added this way are always located under info.event._def.extendedProps
add_action('piecal_additional_event_click_js', function() {
    ?>
    Alpine.store("calendarEngine").venue = info.event._def.extendedProps.venue;
    <?php
}, 10, 0);

Note that though we're only dealing with a single property (venue), you can do this for as many properties as you'd like.

Step 3: Output the custom properties in the popover using Alpine.

Now the data is available in JavaScript for us to use in the popover when an event is clicked.

The way we do this is with Alpine.js.

If we want our custom property value to be output inside an element, we can use x-text. We can also use our custom property in logical evaluations, but this example won't go into that.

If you're familiar with JavaScript and reactive libraries, this will be simple for you to implement.

// Step 3, output the data in the popover using Alpine
function my_inject_custom_field_in_popover( $atts ) {
	// Note: $atts is available so you can check for shortcode attributes before making modifications, e.g. make sure showcustomfields=true.
	ob_start();
	?>
		<style>
		.piecal_popover_custom_field {
		border-radius: 8px;
		padding: 12px;
		background: #EFEFEF;
		}
		</style>
		<p class="piecal_popover_custom_field" x-show="$store.calendarEngine.venue" x-text="'Venue: ' + $store.calendarEngine.venue"></p>
	<?php
	echo ob_get_clean();
}

add_action( 'piecal_popover_before_details', 'my_inject_custom_field_in_popover', 10, 1 );

Note that in this example we're using the piecal_popover_before_details hook to output our custom data before the event details in the popover. The full list of available locations is below.

  • piecal_popover_before_title
  • piecal_popover_after_title
  • piecal_popover_before_meta
  • piecal_popover_after_meta
  • piecal_popover_before_details
  • piecal_popover_after_details
  • piecal_popover_before_view_link
Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.