Recipe: Override a Template
Goal: Replace Eventonomy's rendered markup from your theme, without touching plugin files.
What is actually overridable. Eventonomy renders its frontend through dynamic blocks, not a library of standalone PHP page templates. There is no
single-event.php/event-card.php/rsvp-form.phpfile layer to copy. (Anevnm_get_template_part( string $name, array $args = [] ): voidhelper does exist inincludes/template-loader.php, with theevnm_template_part/evnm_template_part_argsfilters, but no shipped surface calls it - it is there for add-ons that want the same theme-first resolution for their own parts. Overriding a "part" will not change any Eventonomy screen.) There are exactly three real override seams, all resolved through the theme withlocate_template():
- Block markup -
{theme}/eventonomy/blocks/{slug}.php- Email templates -
{theme}/eventonomy/emails/{relative}- Classic-theme fullwidth page template -
{theme}/eventonomy/eventonomy-fullwidth-template.php
Seam 1: Override a Block's Markup
Every dynamic Eventonomy block passes through one render callback that first checks the active theme for eventonomy/blocks/{slug}.php (via locate_template()), and only falls back to the plugin's bundled render.php if the theme has no override. Child theme wins over parent theme wins over plugin.
The {slug} is the block's directory basename:
| Slug | Block |
|---|---|
single-event |
The single-event page (hero, RSVP, map, who's-going). |
events-list |
The events archive (grid / list / upcoming layouts). |
calendar |
The month calendar. |
upcoming |
The compact upcoming-events widget. |
rsvp |
The RSVP / checkout form. |
my-events |
The member dashboard. |
event-editor |
The frontend event create/edit form. |
search-filter |
The events search + filter bar. |
manage-attendees |
The organizer attendee/sales panel. |
Pro's nine blocks resolve through the same callback and the same flat path, so
{theme}/eventonomy/blocks/checkin.php, map-view.php, week-view.php, day-view.php,
discovery-feed.php, follow-button.php, member-events.php, organizer-analytics.php
and photo-grid.php all work. Slugs are unique across Free and Pro, so there is no
collision in the single directory.
How to override
Copy the block's bundled render.php (from eventonomy/src/blocks/{slug}/render.php) into your theme at {your-theme}/eventonomy/blocks/{slug}.php, then edit it. Eventonomy discovers it automatically; no PHP registration required.
Your override runs with the same variables in scope WordPress gives a file-based block render ($attributes, $content, and $block), so a copied render.php works unchanged. The output is still wrapped with the shared .evnm-scope isolation class and passed through the evnm_block_output filter, so theme-isolation and post-processing keep working.
<?php
// your-theme/eventonomy/blocks/upcoming.php
defined( 'ABSPATH' ) || exit;
// $attributes, $content, $block are already in scope (same as core file render).
// Read event data through the public view-data helper - never query the DB here.
$view_data = function_exists( 'evnm_get_view_data' )
? evnm_get_view_data( 'event', get_the_ID() )
: [];
?>
<div <?php echo get_block_wrapper_attributes(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- pre-escaped by core. ?>>
<!-- your custom upcoming-events markup -->
</div>
get_block_wrapper_attributes()returns a pre-escaped attribute string. Echo it raw as above - passing it throughwp_kses_data()oresc_attr()mangles the markup. Every bundledrender.phpdoes it this way.
Post-process without a full override
If you only need to tweak the rendered HTML (inject a banner, rewrite a class), filter the output instead of copying the whole template:
add_filter( 'evnm_block_output', function ( string $html, string $name, array $attributes, $block ): string {
if ( 'eventonomy/single-event' === $name ) {
$html .= '<p class="my-addon-sponsor">Sponsored by Acme</p>';
}
return $html;
}, 10, 4 );
Seam 2: Override an Email Template
Notification emails resolve each part through the theme first, at {theme}/eventonomy/emails/{relative}, the WooCommerce-style override site builders expect. Bundled files live in eventonomy/templates/emails/:
| Relative path | Renders |
|---|---|
rsvp-confirmation.php |
The attendee RSVP confirmation body. |
magic-link.php |
The guest magic-link email body. |
organizer-notification.php |
The organizer "new RSVP" notification body. |
parts/header.php |
Shared branded email header. |
parts/footer.php |
Shared footer (unsubscribe / legal). |
Copy the file you want to change into {your-theme}/eventonomy/emails/{relative} and edit it:
your-theme/eventonomy/emails/parts/footer.php
your-theme/eventonomy/emails/rsvp-confirmation.php
The override is picked up automatically the next time that email is sent.
Seam 3: Classic-Theme Fullwidth Page Template
On classic themes, Eventonomy swaps in a fullwidth template for its plugin pages (Events, single event, dashboard, editor) so its blocks are not squeezed into a narrow content column. Override or opt out:
- Override the template: place your own at
{your-theme}/eventonomy/eventonomy-fullwidth-template.php(bundled copy:eventonomy/templates/eventonomy-fullwidth-template.php). - Opt out entirely (keep your theme's default template):
add_filter( 'evnm_use_fullwidth_template', '__return_false' );
Block themes: this seam does nothing on a block theme (FSE). Block themes render Eventonomy pages through their own templates and template parts; edit those in the Site Editor instead. The fullwidth swap and the
evnm_use_fullwidth_templatefilter are classic-theme only.
The Golden Rule: No Queries in Overrides
Whether you override a block template or an email, run zero database queries. Read prepared data through evnm_get_view_data( 'event', $id ) (which returns [ 'event' => row, 'occurrences' => [...] ]) or add fields upstream via evnm_rest_prepare_event. Install Query Monitor and confirm your override adds no queries.
Verify It Worked
- Copy a bundled file into the matching
{theme}/eventonomy/...path and change something visible. - Reload the surface: the block page for a block override, or trigger the email (e.g. submit an RSVP) for an email override.
- Confirm your markup appears instead of the bundled markup.
- With Query Monitor open, confirm the override added no new database queries.
Related
- Blocks & Templates - the block layer and the
evnm_block_outputfilter. docs/EXTENDING.md§7 - the block/email override paths and$view_datashape.- Recipes Index