Skip to main content

Customizing Episode Listings

Benecaster’s episode-listing shortcodes — [benecaster_episodes], [benecaster_latest_episode], and [benecaster_related_episodes] — all share a common filter that lets you control how each item renders. A single callback covers all three surfaces.


Controlling what items render: benecaster_episode_item_output

The benecaster_episode_item_output filter fires once per rendered item across all three shortcodes. You receive the default HTML, the episode and show IDs, the current user’s tier slug, and whether the episode is locked for the current visitor. Return the HTML unchanged, return a replacement string, or return "" to suppress the item entirely.

add_filter( 'benecaster_episode_item_output', function ( string $html, int $episode_id, int $show_id, string $user_tier, bool $is_locked ): string {
    // $html      — the default rendered markup for this item
    // $episode_id — post ID of the episode
    // $show_id   — post ID of the show
    // $user_tier  — the current user's active tier slug, or '' if not subscribed
    // $is_locked  — true when the user cannot access this episode
    return $html;
}, 10, 5 );

Two common patterns, both written up as complete recipes:

One thing worth knowing before you reach for the first of those: [benecaster_episodes] also takes a show_locked="false" attribute, which runs before this filter and only affects that one shortcode instance. For a single list it is the cheaper option. The filter is the right choice when you want the same behaviour everywhere without repeating the attribute.

The $is_locked value reflects all access rules — including any rules registered by third-party code via benecaster_episode_is_accessible — so you don’t need to replicate access logic in this callback.


Customizing pagination output

When [benecaster_episodes paged="true"] is set, the shortcode renders a Previous / “Page N of M” / Next navigation strip below the list. Replace it entirely with the benecaster_episodes_pagination_output filter:

add_filter( 'benecaster_episodes_pagination_output', function ( string $html, \WP_Query $query, array $atts ): string {
    $current = (int) ( $query->query_vars['paged'] ?? 1 );
    $max     = (int) $query->max_num_pages;

    if ( $current >= $max ) {
        return ''; // last page — no next link needed
    }

    $next_url = add_query_arg( 'ep_page', $current + 1 );
    return sprintf(
        '<div class="my-load-more"><a href="%s">Load more episodes</a></div>',
        esc_url( $next_url )
    );
}, 10, 3 );

The filter fires even on single-page results, so you can inject a custom strip unconditionally. Check $query->max_num_pages before building navigation to avoid rendering arrows that point nowhere.


Disambiguating multiple paged lists

When two [benecaster_episodes paged="true"] shortcodes appear on the same page, they both read ?ep_page=N by default — clicking Next on either list advances both simultaneously. Assign a unique query var per shortcode with benecaster_ep_page_query_var:

add_filter( 'benecaster_ep_page_query_var', function ( string $query_var, int $show_id, array $atts ): string {
    return 'ep_page_' . $show_id;
}, 10, 3 );

The shortcode’s Previous/Next links are updated automatically to use the new var name. If you also use benecaster_episodes_pagination_output to build custom navigation, use the same overridden var name in add_query_arg().


Further reading

See Also

Need this built rather than just documented? See our services →