Eventonomy

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.php file layer to copy. (An evnm_get_template_part( string $name, array $args = [] ): void helper does exist in includes/template-loader.php, with the evnm_template_part / evnm_template_part_args filters, 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 with locate_template():

  1. Block markup - {theme}/eventonomy/blocks/{slug}.php
  2. Email templates - {theme}/eventonomy/emails/{relative}
  3. 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 through wp_kses_data() or esc_attr() mangles the markup. Every bundled render.php does 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_template filter 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

  1. Copy a bundled file into the matching {theme}/eventonomy/... path and change something visible.
  2. Reload the surface: the block page for a block override, or trigger the email (e.g. submit an RSVP) for an email override.
  3. Confirm your markup appears instead of the bundled markup.
  4. With Query Monitor open, confirm the override added no new database queries.

Related

  • Blocks & Templates - the block layer and the evnm_block_output filter.
  • docs/EXTENDING.md §7 - the block/email override paths and $view_data shape.
  • Recipes Index