Last updated July 11, 2026, Version 0.34
GatherPress registers multiple invisible block-patterns, that are used as template properties for the main post types.
Patterns allow to be filtered by the (upgraded since WordPress 6.5) Block Hooks API. Making use of this API brings some advantages, which are at least:
- GatherPress’ blocks can be easily moved, modified, or removed by extenders via standardized core code
- GatherPress provides central entry points for plugin developers to hook-in own blocks, to extend GatherPress
- GatherPress’ blocks will provide their hooking code themself, which keeps concerns separate and code clean
For example, the gatherpress/event-template pattern is the Block Hooks anchor that companion plugins extend; the user-facing “Event with RSVP” starter pattern surfaced in the new-event chooser modal seeds the same canonical block layout.
Overview of hookable patterns
GatherPress combines four of such block-patterns to curate the creation of:
New Event
Creating a new event opens WordPress’s “Choose a pattern” starter modal —
the same UX Twenty Twenty-Five uses on new pages. The bundled patterns
live in includes/core/templates/event/; each file returns a
name/title/description/content array and the loader registers it
scoped to core/post-content plus every post type declaring
gatherpress-event-date support. Adding a new pattern is just dropping
a file into that directory.
The bundled default ships with the plugin:
gatherpress/event-with-rsvp(title “Event with RSVP”) seeds the
canonical event layout: event-date + add-to-calendar + venue +
online-event + RSVP + description paragraph + rsvp-response. Venue,
RSVP, and rsvp-response carrypatternPicked: trueso their
in-block pattern pickers stay suppressed.
Third parties can append their own without forking by hooking the
gatherpress_event_starter_patterns filter. The second argument is the
array of post types declaring gatherpress-event-date support that the
patterns will be registered against — branch on it to scope an entry to
your own event-acting post type only:
add_filter(
'gatherpress_event_starter_patterns',
function ( array $patterns, array $post_types ): array {
if ( ! in_array( 'production', $post_types, true ) ) {
return $patterns;
}
$patterns[] = array(
'name' => 'my-plugin/minimal-event',
'title' => __( 'Minimal Event', 'my-plugin' ),
'description' => __( 'Date + RSVP only.', 'my-plugin' ),
'content' => '<!-- wp:gatherpress/event-date /--><!-- wp:gatherpress/rsvp {"patternPicked":true} --><div class="wp-block-gatherpress-rsvp"></div><!-- /wp:gatherpress/rsvp -->',
);
return $patterns;
},
10,
2
);
Per-user dismissal is handled by the modal’s own “Always show starter patterns for new pages” toggle — that’s a WordPress-core user preference, not a GatherPress setting.
The gatherpress/event-template pattern still exists as the Block Hooks
anchor for companion plugins that hook blocks before/after the event-date
block via hooked_block_types.
New Venue
Same shape as the event flow. Bundled venue starter patterns live in
includes/core/templates/venue/; each file returns a
name/title/description/content array and the loader registers it
scoped to core/post-content plus every post type declaring
gatherpress-venue-information support.
The bundled default:
gatherpress/venue-with-map(title “Venue with Map”) seeds a
singlegatherpress/venueblock withpatternPicked: trueso the
block’s in-block picker stays suppressed.
Third parties can append their own via the
gatherpress_venue_starter_patterns filter — same shape as the event
filter above.
Per-user dismissal is handled by the modal’s own “Always show starter patterns for new pages” toggle — that’s a WordPress-core user preference, not a GatherPress setting.
The gatherpress/venue-template pattern still exists — it is the
Block Hooks anchor and the seed used by Venue\Setup::maybe_apply_venue_template()
when venues are created programmatically (e.g., via REST without
content).
New Event Queries within any post
…
Venue Details within any post
…
Modify the blocks in the patterns
Change order of the default blocks
Example: To move the RSVP-Response block directly behind the RSVP block for every new created Event, you could call:
/**
* Move the "RSVP-Response" block directly behind the "RSVP" block.
*
* @param string[] $hooked_block_types The list of hooked block types.
* @return string[] The modified list of hooked block types.
*/
add_filter( 'hooked_block_types', function( array $hooked_block_types ) : array {
$index = array_search('gatherpress/rsvp-response', $hooked_block_types);
if ( $index !== false ) {
// Remove the "RSVP-Response" block from its current position.
$block = array_splice( $hooked_block_types, $index, 1 );
// Find the index of the "RSVP" block.
$rsvp_index = array_search( 'gatherpress/rsvp', $hooked_block_types );
// Insert the "RSVP-Response" block directly behind the "RSVP" block.
array_splice( $hooked_block_types, $rsvp_index + 1, 0, $block );
}
return $hooked_block_types;
});
Add blocks to the default patterns
Example: To add the Featured Image block before the Event Date block for every new created Event, you could call:
/**
* Add the 'Featured Image' block before the 'Event Date' block.
*
* @see https://developer.wordpress.org/reference/hooks/hooked_block_types/
*
* @param string[] $hooked_block_types The list of hooked block types.
* @param string $relative_position The relative position of the hooked blocks. Can be one of 'before', 'after', 'first_child', or 'last_child'.
* @param string|null $anchor_block_type The anchor block type.
* @param \WP_Block_Template|array $context The block template, template part, or pattern that the anchor block belongs to.
* @return string[] The list of hooked block types.
*/
add_filter( 'hooked_block_types', function ( array $hooked_block_types, string $relative_position, ?string $anchor_block_type, $context ): array {
// Check that the place to hook into is a pattern and
// hook block into the "gatherpress/event-template" pattern.
if (
is_array( $context ) &&
isset( $context['name'] ) &&
'gatherpress/event-template' === $context['name'] &&
'gatherpress/event-date' === $anchor_block_type &&
'before' === $relative_position
) {
$hooked_block_types[] = 'core/post-featured-image';
}
return $hooked_block_types;
}, 10, 4 );
Remove default blocks
Example: To remove the RSVP-Response block, you could call:
/**
* Remove every use of the RSVP-Response block (everywhere).
*
* @see https://developer.wordpress.org/reference/hooks/hooked_block_types/
*
* @param string[] $hooked_block_types The list of hooked block types.
* @return string[] The modified list of hooked block types.
*/
add_filter( 'hooked_block_types', function( array $hooked_block_types ) : array {
return array_diff( $hooked_block_types, array( 'gatherpress/rsvp-response' ) );
});