Last updated July 11, 2026, Version 0.34
Several GatherPress blocks open a pattern picker on insert — a placeholder UI
with a Choose button that surfaces a modal of named starter layouts. The
picker is powered by the reusable PatternPicker
component and each consuming block exposes a JS filter so third parties can
register their own patterns without forking the block.
RSVP Response — gatherpress.rsvpResponsePatterns
Filters the array of starter patterns shown in the RSVP Response block’s picker. Each entry is an object:
| Key | Type | Description |
|---|---|---|
name |
string |
Stable identifier. Use a plugin namespace, e.g. my-plugin/compact. |
title |
string |
Translated, human-readable label shown beneath the preview thumbnail. |
description |
string |
Translated sentence-length summary. Surfaced for screen readers. |
template |
Array |
InnerBlocks tuple tree — [ blockName, attributes, innerBlocks ] — used to seed the block when the pattern is picked. |
The bundled default (Attendee Grid with Filter) is the only entry registered out of the box. Add your own:
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
addFilter(
'gatherpress.rsvpResponsePatterns',
'my-plugin/extra-rsvp-pattern',
( patterns ) => [
...patterns,
{
name: 'my-plugin/compact',
title: __( 'Compact', 'my-plugin' ),
description: __(
'Avatar grid only — no status filter.',
'my-plugin'
),
template: [
[
'core/group',
{ layout: { type: 'grid', columns: 3 } },
[ [ 'gatherpress/rsvp-template', {} ] ],
],
],
},
]
);
Auto-loaded RSVP Response instances
The RSVP Response block seeded into a new event post (via the
gatherpress/event-with-rsvp starter pattern surfaced in the new-event
chooser modal) carries patternPicked: true so the picker is suppressed
and the block seeds the default template directly. Authors can still swap
layouts via the block toolbar’s Choose pattern action — that opens
the same modal your filter contributes to.
Swapping the auto-loaded template — gatherpress.rsvpResponseDefaultTemplate
To change what auto-loaded instances seed (without going through the picker
flow), filter the default template directly. The filter receives an
InnerBlocks tuple tree and must return one of the same shape:
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
addFilter(
'gatherpress.rsvpResponseDefaultTemplate',
'my-plugin/swap-rsvp-default',
() => [
[
'core/group',
{ layout: { type: 'grid', columns: 3 } },
[ [ 'gatherpress/rsvp-template', {} ] ],
],
]
);
This only affects the auto-loaded path. Manual inserts still go through the
picker, which is filtered separately via gatherpress.rsvpResponsePatterns.
RSVP Form — gatherpress.rsvpFormPatterns
Same shape as RSVP Response. Filters the array of starter patterns shown in
the RSVP Form block’s picker. Each entry is { name, title, description, template }.
The bundled default (Standard RSVP Form) is the only entry registered out of the box. Add your own:
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
addFilter(
'gatherpress.rsvpFormPatterns',
'my-plugin/extra-rsvp-form',
( patterns ) => [
...patterns,
{
name: 'my-plugin/minimal',
title: __( 'Minimal', 'my-plugin' ),
description: __(
'Name + email + submit only.',
'my-plugin'
),
template: [
/* ...InnerBlocks tuples... */
],
},
]
);
Swapping the RSVP Form auto-loaded template — gatherpress.rsvpFormDefaultTemplate
Parallel to gatherpress.rsvpResponseDefaultTemplate — filters the template
seeded into auto-loaded RSVP Form blocks (currently a no-op since the block
isn’t auto-included by the event post type’s template arg, but kept for
parity in case future patterns add it).
Venue — gatherpress.venuePatterns
Same shape as RSVP Response and RSVP Form. Filters the array of starter
patterns shown in the Venue block’s picker. Each entry is
{ name, title, description, template }.
Two patterns ship by default, both always available in the chooser:
- Venue Details with Title — prepends a
core/post-titleto the
address + phone + website + map. Default for event posts (the title
names the event hosting the venue). - Venue Details — the same address + phone + website + map without a
title. Default for venue posts (the host post itself names the venue).
Authors can pick either regardless of host post type — the auto-load just picks the context-appropriate one when the picker is suppressed.
The second callback argument is the host post type — the post type of
the post being edited (resolved from block context, falling back to the
editor’s current post type). Branch on it to scope a pattern to a specific
host (e.g. only on a companion plugin’s production post type) without
affecting the standard event/venue picker.
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
addFilter(
'gatherpress.venuePatterns',
'my-plugin/extra-venue-pattern',
( patterns, hostPostType ) => {
if ( 'production' !== hostPostType ) {
return patterns;
}
return [
...patterns,
{
name: 'my-plugin/map-only',
title: __( 'Map only', 'my-plugin' ),
description: __(
'Just the embedded venue map, no contact details.',
'my-plugin'
),
template: [ [ 'gatherpress/venue-map' ] ],
},
];
}
);
Auto-loaded venue instances
Two paths seed the picker as already-picked:
- The
gatherpress/event-with-rsvpstarter pattern (surfaced in the
new-event chooser modal) includesgatherpress/venuewith
patternPicked: true— picking it from the modal pre-populates the
with-title venue layout. - The
gatherpress/venue-with-mapstarter pattern (surfaced in the
new-venue chooser modal) carries the samepatternPicked: true—
picking it pre-populates the without-title layout.
Manual venue inserts on other post types still hit the picker.
Swapping the venue auto-loaded template — gatherpress.venueDefaultTemplate
Parallel to the RSVP Response/Form variants. Filters the template seeded into auto-loaded Venue blocks. Receives the context-resolved template (with-title or without-title).
RSVP — gatherpress.rsvpPatterns
The RSVP block carries five inner-block templates — one per RSVP status
(no_status, attending, waiting_list, not_attending, past) — that
get serialized into the serializedInnerBlocks attribute. A pattern entry
therefore has a richer shape than the other blocks: alongside template
(used for the modal’s <BlockPreview> thumbnail and as the initial active
inner blocks), it exposes statusTemplates — a map of status → template
tuple tree — that the RSVP-specific pick handler uses to seed all five
statuses at once.
The bundled default (RSVP Button with Modal) is the only entry registered out of the box. Add your own:
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
addFilter(
'gatherpress.rsvpPatterns',
'my-plugin/extra-rsvp-pattern',
( patterns ) => [
...patterns,
{
name: 'my-plugin/text-rsvp',
title: __( 'Text-only RSVP', 'my-plugin' ),
description: __(
'Link-style RSVP per status, no button.',
'my-plugin'
),
// Used by the modal preview + active inner blocks on insert.
template: [ /* no_status tree */ ],
// Seeded into serializedInnerBlocks for all five statuses.
statusTemplates: {
no_status: [ /* ... */ ],
attending: [ /* ... */ ],
waiting_list: [ /* ... */ ],
not_attending: [ /* ... */ ],
past: [ /* ... */ ],
},
},
]
);
Auto-loaded RSVP instances
The RSVP block seeded into a new event post (via the
gatherpress/event-with-rsvp starter pattern surfaced in the new-event
chooser modal) carries patternPicked: true so the picker is suppressed
and the existing hydration useEffect seeds the default status templates
directly.
Swapping the RSVP auto-loaded bundle — gatherpress.rsvpDefaultStatusTemplates
Parallel to the other auto-load filters, but receives the per-status
template map rather than a single template — the RSVP block’s hydration
logic loops over its keys to populate serializedInnerBlocks.
Adding a picker to a new block
The picker component lives at src/components/PatternPicker/
and is exported as the default plus a named PatternChooserModal export for
toolbar-driven re-opens. See the RSVP Response wiring at
src/blocks/rsvp-response/edit.js
for the canonical integration: a patternPicked boolean attribute on the
block, a useSelect for inner-block count, the picker render gated on
! patternPicked && 0 === innerBlockCount, and a BlockControls toolbar
entry that re-opens <PatternChooserModal> for already-populated blocks.