benecaster_related_episodes_query_types
Registers additional query strategies for the benecaster_related_episodes shortcode and the Related Episodes block on episode pages, which renders through the shortcode’s pipeline. Each key in the returned array is a type slug; each value is a plain array with a label and a results callable. There is no interface to implement and no class name to know.
New types appear automatically, under their label, in the Related Episodes block’s Which episodes to list setting on a show’s Templates tab and in the Related by setting of the Blocks & Widgets Related Episodes block and Elementor widget, and are available as the shortcode’s query attribute. When the chosen type finds nothing, or is not registered (its add-on is switched off), the list shows the latest episodes instead. Tier-aware filtering is handled by the renderer — a strategy returns all matching published episodes and does not filter by subscriber access. Built-in types: by_tag, by_season, by_guest, latest.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
$types |
array |
— | Keyed array of strategy definitions: slug => [ 'label' => string, 'results' => callable ]. |
Returns:
array
Example
add_filter( 'benecaster_related_episodes_query_types', function ( array $types ): array {
$types['by_series'] = [
'label' => __( 'Same series', 'my-addon' ),
'results' => function ( int $episode_id, int $show_id, array $args ): array {
$series = get_post_meta( $episode_id, 'my_series', true );
if ( ! $series ) {
return [];
}
return get_posts( [
'post_type' => 'benecaster_episode',
'post_parent' => $show_id,
'posts_per_page' => $args['count'],
'post__not_in' => $args['exclude_current'] ? [ $episode_id ] : [],
'meta_key' => 'my_series',
'meta_value' => $series,
] );
},
];
return $types;
} );
Notes
results receives ( int $episode_id, int $show_id, array $args ) — episode first. The sibling filter benecaster_member_thanks_query_types takes the same two IDs in the opposite order. They are easy to transpose and PHP will not stop you, because both are integers.
$args carries count (int) and exclude_current (bool); honour both. Return a list of WP_Post objects.
Results are filtered to what the visitor may see before the latest fallback. Anything in the returned list that is not a WP_Post, and any episode that is not published (unless the viewer can edit it), is dropped. If nothing survives, the list falls back to latest. benecaster_related_episodes runs after that filter, so it receives only viewable episodes.
An entry whose results is missing or not callable is silently discarded, not fataled — so a strategy that never appears in the picker is usually a malformed definition rather than a registration failure. Do not reuse a built-in slug (by_tag, by_season, by_guest, latest) as your own key.
Read on first use, not at load. Benecaster applies this filter the first time a list renders or a REST request asks for the types, after every add-on has booted, so a strategy registered from benecaster_boot or from a paid add-on's own bootstrap is seen.
A strategy that throws is an empty result, not a broken page. Any exception or error from results is caught, written to Settings → Tools → Debug Log once per type per request, and counted as finding nothing, so the list falls back to latest. A subscriber never sees the error.
Affects
- benecaster_related_episodes shortcode
- Related Episodes Episode Page block
- Related Episodes block's "Which episodes to list" setting (show settings → Templates)
- Blocks & Widgets Related Episodes block and Elementor widget ("Related by")
Need this built rather than just documented? See our services →