Skip to main content

Shortcodes (Developer Reference)

Full attribute tables, output filters, and extension points for all Benecaster shortcodes. For customer-facing usage examples see Shortcodes Reference.

All output filters receive at minimum (string $html, int $show_id, array $atts) where $atts is the resolved attribute array. All filters are Free unless noted.


Subscriber Feeds & Playback

[benecaster_player]

Embeds an episode audio or video player inline. Renders the locked-state message when the current user does not have access to the episode.

Access: Free — no license check; renders in all contexts.

Attribute Type Default Description
episode_id int current episode post ID Episode to play
show_id int If episode_id is omitted, plays the latest episode for this show
style string 'standard' Player style: standard, minimal, or card
show_title bool true Render the episode title above the player
show_artwork bool true Render episode artwork

benecaster_player_output( string $html, int $episode_id, array $atts ): string

Fires before the rendered HTML is returned. $atts contains the resolved (not raw) shortcode attributes.

When the current user cannot access the episode, the player renders the locked-state message instead. Override it via [benecaster_locked_content_message](/docs/benecaster_locked_content_message/). Override the access decision itself via [benecaster_episode_is_accessible](/docs/benecaster_episode_is_accessible/).

// Wrap every player in an analytics data container
add_filter( 'benecaster_player_output', function( string $html, int $episode_id, array $atts ): string {
    return '<div class="my-analytics-wrapper" data-ep="' . esc_attr( $episode_id ) . '">'
        . $html
        . '</div>';
}, 10, 3 );

[benecaster_subscribe]

Renders a subscription call-to-action with tier options. Tier cards fire benecaster_subscribe_tier_content — the canonical extension point for injecting tier-specific pricing or CTAs.

Access: Premium — renders nothing without an active license.

Attribute Type Default Description
show_id int Required. Show to subscribe to
tiers string all tiers Comma-separated tier slugs to display
style string 'cards' Layout: cards, list, or minimal
highlight_tier string Tier slug to visually highlight as the recommended option

benecaster_subscribe_output( string $html, int $show_id, array $atts ): string — Premium

benecaster_subscribe_tier_content action — ( string $tier_slug, int $show_id )

Fires inside each tier card. Hook here to output tier-specific content: price, a feature list, or a custom subscribe button.

add_action( 'benecaster_subscribe_tier_content', function( string $tier_slug, int $show_id ): void {
    $bridge = benecaster_get_bridge( $show_id );
    foreach ( $bridge->get_all_tiers() as $tier ) {
        if ( $tier['slug'] !== $tier_slug ) {
            continue;
        }
        if ( ! empty( $tier['price'] ) ) {
            echo '<p class="tier-price">$' . esc_html( number_format( $tier['price'], 2 ) ) . '/mo</p>';
        }
        if ( ! empty( $tier['subscribe_url'] ) ) {
            echo '<a class="tier-cta" href="' . esc_url( $tier['subscribe_url'] ) . '">Subscribe</a>';
        }
        break;
    }
}, 10, 2 );

[benecaster_feed_url]

Displays the current subscriber’s personal RSS feed URL. Shows nothing to unauthenticated visitors or logged-in users with no active token for this show.

Access: Premium — requires an active license.

Attribute Type Default Description
show_id int Required
format string 'link' Display as link (anchor tag), text (plain text), or input (copyable input field)
label string 'Your podcast feed URL' Label text rendered above or alongside the URL

benecaster_feed_url_output( string $html, int $show_id, array $atts ): string — Premium

Use to change the masked URL display format or inject additional copy around the token reset CTA.

When generating links to the subscriber account page elsewhere, use the benecaster_account_page_url filter rather than hard-coding the URL:

$account_url = apply_filters( 'benecaster_account_page_url', get_permalink( benecaster_get_account_page_id() ) );

[benecaster_episodes]

Renders an episode list or grid. Respects tier access — locked episodes show a teaser when show_locked=true.

Access: Free — no license check.

Attribute Type Default Description
show_id int Required
limit int 10 Number of episodes to render
offset int 0 Offset for manual pagination
tier string current user’s tier Filter to episodes accessible at this tier slug
style string 'list' list or grid
show_locked bool true Show locked episodes with teaser; false to hide entirely
orderby string 'date' date or episode_number
order string 'DESC' ASC or DESC

benecaster_episodes_output( string $html, int $show_id, array $atts ): string

Use to inject pagination controls, change the list wrapper markup, or add data attributes.


Marketing & Social Proof

[benecaster_subscriber_count]

Attribute Type Default Description
show_id int current show Which show to count
tier string (all tiers) Restrict count to one tier slug
type string paying paying — active tokens joined to is_free_tier = 0 tiers; total — paying + free-tier; free — free-tier only
format string full full (“1,247”) or compact (“1.2k”)
minimum int 10 Render nothing if count is below this value; set 0 to always render
label string (none) Text appended after the formatted number

Premium. Reads directly from benecaster_tokens. Returns empty string when count is below minimum — the shortcode renders nothing, not a zero.

benecaster_subscriber_count_output

add_filter(
    'benecaster_subscriber_count_output',
    function ( string $html, int $count, array $atts ): string {
        // $count is the raw integer before formatting and minimum check.
        // $html is empty string when count < minimum — respect it.
        if ( $html === '' ) {
            return $html;
        }
        // Wrap in an animated counter element.
        return '<span class="js-counter" data-count="' . $count . '">' . $html . '</span>';
    },
    10,
    3
);

Parameters: $html (string), $count (int) — raw integer before formatting, $atts (array).


[benecaster_episode_count]

Attribute Type Default Description
show_id int current show Which show
tier string (all) Count only episodes accessible to this tier slug
label string (none) Text appended after the number

Free.

benecaster_episode_count_output

Parameters: $html (string), $count (int), $atts (array). Returns empty string when no episodes found.


[benecaster_tier_price]

Attribute Type Default Description
show_id int Required. Show whose active bridge to look up the tier in
tier string Required. Internal tier slug to look up

Premium. Outputs the raw price number as text (e.g. 15). Wrap in HTML for currency formatting:

From $[benecaster_tier_price show_id="1" tier="gold"]/month
→ From $15/month

Returns empty string if the tier slug is not found in the active bridge or price is unavailable (e.g. membership plugin uses a pricing model Benecaster cannot read).

benecaster_tier_price_output

Parameters: $output (string), $price (float|null), $atts (array). $price is the raw float from the bridge, or null when unavailable.


[benecaster_tier_name]

Attribute Type Default Description
show_id int Required. Show whose active bridge to look up the tier in
tier string Required. Internal tier slug whose display name to output

Premium. Returns empty string if slug not found.

benecaster_tier_name_output

Parameters: $output (string), $name (string), $atts (array). $name is the raw name string from the bridge.


[benecaster_pricing_table]

Attribute Type Default Description
show_id int current show Which show’s tiers to render
exclude string (none) Comma-separated internal tier slugs to hide
cta_text string Subscribe Subscribe button label on each tier column
cta_url_base string auto-detected Base URL for subscribe links; auto-detection reads from the active bridge’s signup URL

Premium. Tiers where is_public_tier = 1 are excluded automatically — they have no subscribe button and do not belong in a pricing comparison.

All rendered elements carry CSS classes for styling. Classes follow the pattern benecaster-pricing-* — inspect the rendered HTML for the full list.

benecaster_pricing_table_output

add_filter(
    'benecaster_pricing_table_output',
    function ( string $html, array $tiers, int $show_id, array $atts ): string {
        // $tiers: array of {slug, name, price, external_tier_id} — after exclude is applied.
        // Replace or augment the rendered HTML.
        return $html;
    },
    10,
    4
);

Parameters: $html (string), $tiers (array), $show_id (int), $atts (array). Use $tiers to read per-column tier slugs when injecting feature list rows.


Content

[benecaster_show_description]

Outputs the show’s long or short description.

Access: Free — no license check.

Attribute Type Default Description
show_id int Required. Show to read the description from
type string 'long' long — main show description; short — the short description field

benecaster_show_description( string $description, int $show_id, string $type ): string

Filters the raw description string before shortcode attribute processing. Use to apply transformations to the stored value — merge tag replacement, custom formatting — regardless of where the description is rendered.

benecaster_show_description_output( string $html, int $show_id, array $atts ): string

Filters the final rendered HTML.


[benecaster_episode_description]

Outputs the episode’s description (the post excerpt or full content).

Access: Free — no license check.

Attribute Type Default Description
episode_id int current episode post ID Episode to read
show_id int If episode_id is omitted, falls back to the latest episode for this show

benecaster_episode_description( string $description, int $episode_id ): string

Filters the raw description string before rendering.

benecaster_episode_description_output( string $html, int $episode_id, array $atts ): string

Filters the final rendered HTML.


[benecaster_latest_episode]

Renders a composite block for the show’s most recently published episode: artwork, title, description, and an audio player.

Access: Free — no license check.

Attribute Type Default Description
show_id int Required. Show to query
episode_id int (latest) Override automatic latest-episode selection with a specific episode ID
sections string 'artwork,title,description,player' Comma-separated sections to render
style string 'card' Layout: card or minimal
link_title bool true Wrap the episode title in a link to the episode permalink
title string Override the rendered title text (does not change the episode title in the database)
link_text string 'Listen now' Label for the “listen now” link rendered below the player

benecaster_latest_episode_output( string $html, int $episode_id, array $atts ): string

Filters the final rendered HTML.


[benecaster_member_thanks]

Renders a list of members to thank on a podcast episode — by default, new subscribers since the last episode. Useful in show notes, episode pages, or any content area where you acknowledge your supporters.

Access: Free — no license check.

Attribute Type Default Description
show_id int Required
query_type string 'random_cycling' Built-in strategies: new_since_last_episode, random_cycling, milestone. Add custom types via benecaster_member_thanks_query_types
count int 5 Maximum number of members to include
tier string Limit results to one tier slug; omit for all tiers
format string 'list' list (unordered list), prose (comma-separated sentence), names (bare comma-separated)
episode_id int When set and the Podcast Workflow add-on is active, outputs the accepted Member Thanks list for that specific episode rather than a live query

benecaster_member_thanks_query_types( array $types ): array

Filters the available query strategy instances. Keys are type slugs; values implement BenecasterMemberThanksQueryInterface. Use to register custom query logic — types added here appear automatically in the Podcast Workflow tile’s dropdown. See [benecaster_member_thanks_query_types](/docs/benecaster_member_thanks_query_types/).

benecaster_member_thanks_output( string $html, array $members, array $atts ): string

Filters the final rendered HTML before it is returned. $members is the raw result array from the active query type. See [benecaster_member_thanks_output](/docs/benecaster_member_thanks_output/).


Episode Page

[benecaster_episode_nav]

Renders Previous / Next episode navigation links.

Access: Free — no license check.

Attribute Type Default Description
episode_id int current episode post ID Episode to navigate from
show_id int Required when episode_id is not set on an episode post
style string 'standard' standard or minimal
show_titles bool true Render the adjacent episode title alongside the Previous / Next label
prev_label string 'Previous' Label for the Previous link
next_label string 'Next' Label for the Next link
scope string 'show' Navigation scope: show — across all show episodes; season — within the same season number

benecaster_episode_nav_prev( WP_Post|null $episode, int $current_episode_id, array $atts ): WP_Post|null

Filters the resolved Previous episode. Return a different WP_Post to swap the target, or return null to suppress the Previous link entirely.

benecaster_episode_nav_next( WP_Post|null $episode, int $current_episode_id, array $atts ): WP_Post|null

Filters the resolved Next episode. Same signature and semantics as benecaster_episode_nav_prev.

benecaster_episode_nav_output( string $html, int $episode_id, array $atts ): string

Filters the final rendered HTML.


Renders a list of related episodes from the same show.

Access: Free — no license check.

Attribute Type Default Description
episode_id int current episode post ID Episode to find related episodes for
show_id int Required when episode_id is not set on an episode post
query string 'tag' Query strategy: tag, season, guest (requires Guest Manager add-on), latest
count int 4 Maximum number of related episodes to render
style string 'list' list or grid
exclude_current bool true Exclude the current episode from results
title string 'Related Episodes' Heading rendered above the list

benecaster_related_episodes_query_types( array $types ): array

Filters the available query strategy slugs. Each entry is a slug => label pair. Use this to register a custom strategy; the slug is then a valid value for the query attribute. Implement result resolution via benecaster_related_episodes.

benecaster_related_episodes( array $episodes, int $episode_id, string $query, array $atts ): array

Filters the resolved array of related episode WP_Post objects before rendering. $query is the resolved strategy slug. Return a different array to substitute the result set — for any strategy, built-in or custom.

benecaster_related_episodes_output( string $html, int $episode_id, array $atts ): string

Filters the final rendered HTML.

To implement a custom query strategy, hook both filters:

// Register the strategy slug and label.
add_filter( 'benecaster_related_episodes_query_types', function( array $types ): array {
    $types['topic'] = 'By topic';
    return $types;
} );

// Supply results when the strategy is selected.
add_filter( 'benecaster_related_episodes', function( array $episodes, int $episode_id, string $query, array $atts ): array {
    if ( $query !== 'topic' ) {
        return $episodes;
    }
    return my_plugin_get_related_by_topic( $episode_id, (int) ( $atts['count'] ?? 4 ) );
}, 10, 4 );

Alternatively, implement the BenecasterRelatedEpisodesQueryInterface contract and register it:

interface BenecasterRelatedEpisodesQueryInterface {
    public function get_slug(): string;
    public function get_label(): string;
    /** @return WP_Post[] */
    public function query( int $episode_id, array $atts ): array;
}

benecaster_register_related_episodes_query( new MyTopicQuery() );

[benecaster_episode_share]

Renders social sharing buttons for an episode URL.

Access: Free — no license check.

Attribute Type Default Description
episode_id int current episode post ID Episode to share
show_id int Required when episode_id is not set on an episode post
style string 'buttons' buttons or icons
platforms string all built-in Comma-separated platform slugs: twitter, facebook, linkedin, email
text string episode title Override the share text

benecaster_episode_share_text( string $text, int $episode_id, array $atts ): string

Filters the share text before it is URL-encoded into sharing links. Fires before the text shortcode attribute is applied, so this filter controls the default; the text attribute takes precedence when set.

benecaster_episode_share_output( string $html, int $episode_id, array $atts ): string

Filters the final rendered HTML.


Renders the show’s social profile links.

Access: Free — no license check.

Attribute Type Default Description
show_id int Required
style string 'icons' icons or list
platforms string all configured Comma-separated platform slugs to include; others are suppressed
label string (none) Text label rendered before the link row

benecaster_show_social_links( array $links, int $show_id ): array

Filters the resolved array of social link entries before rendering. Each entry is an associative array with slug and url keys. Use to add, remove, or reorder links programmatically.

benecaster_social_links_output( string $html, int $show_id, array $atts ): string

Filters the final rendered HTML.


Renders the show’s public RSS feed URL as a styled link or badge.

Access: Free — no license check.

Attribute Type Default Description
show_id int Required
style string 'link' link (anchor tag) or badge (styled button with RSS icon)
label string 'RSS Feed' Link or button label text
icon_size string 'medium' Icon size when style=badge: small, medium, or large

benecaster_rss_link_output( string $html, int $show_id, array $atts ): string

Filters the final rendered HTML.


Renders the show’s “listen on” platform badge links.

Access: Free — no license check.

Attribute Type Default Description
show_id int Required
style string 'badges' badges or list
platforms string all configured Comma-separated platform slugs to include; others are suppressed. Does not affect display order

Platform data is stored on the show via ShowMeta::PLATFORM_LINKS. Read or write it programmatically:

$links = $show_meta->get_platform_links();   // Returns array of {slug, url} entries with non-empty URLs only
$show_meta->set_platform_links( $links );    // Persists the full array

Display order matches the order of entries returned by get_platform_links().

benecaster_platform_links_output( string $html, int $show_id, array $atts ): string

Filters the final rendered HTML.


Renders a frontend episode search form and results container for a show.

Access: Free — no license check.

Attribute Type Default Description
show_id int Required. Show to search within
placeholder string 'Search episodes…' Input placeholder text
per_page int 10 Number of results per page
style string 'standard' standard or minimal

Search runs against the episode FULLTEXT index on post_title and post_content. Queries are executed via the Benecaster REST endpoint — no full-page reload. To bypass FULLTEXT with a custom implementation, use the benecaster_search_query filter — see Action Hooks Reference.

benecaster_search_output( string $html, int $show_id, array $atts ): string

Filters the rendered container HTML (the form and results wrapper). Results are injected client-side after load and are not present in the filtered HTML.


Renders an inline link to another episode. Inserted automatically by the TipTap editor’s @ mention picker in episode descriptions and production notes.

Access: Free — no license check.

Attribute Type Default Description
episode_id int Required. Episode to link to
show_id int Optional — used for validation only
label string Episode title Link display text

benecaster_episode_link_output( string $html, int $episode_id, array $atts ): string

Filters the final rendered anchor tag HTML. Use to add data attributes for analytics, apply a custom CSS class, or replace the default anchor. See [benecaster_episode_link_output](/docs/benecaster_episode_link_output/).


[benecaster_timestamp]

Renders an inline timestamp that seeks the nearest Benecaster player to that position when clicked. Inserted automatically by the TipTap editor’s # trigger.

Access: Free — no license check.

Attribute Type Default Description
time int Required. Timestamp in seconds
episode_id int Optional — for association metadata; does not affect rendering
label string Formatted HH:MM:SS Display label for the timestamp

benecaster_timestamp_output( string $html, int $time, array $atts ): string

Filters the final rendered HTML (typically a <button> or <span>). Use to change the display format, apply a custom style, or inject additional metadata for a custom player integration. See [benecaster_timestamp_output](/docs/benecaster_timestamp_output/).


Subscriber Account

[benecaster_account]

Attribute Type Default Description
show_id int (all shows) Limit to one show’s subscription info; 0 or omit for all active subscriptions
sections string all Comma-separated sections to render: subscription, feed_url, token_reset, app_links, qr_code

Free (requires login). Shows a login prompt to unauthenticated visitors; shows a “no subscriptions” message when logged in but no active tokens exist.

Each section renders via benecaster_get_template_part() — theme overrides apply. Extension point: benecaster_account_sections action fires after all core sections inside each subscription card.

Per-section before/after hooks (benecaster_before_account_feed_url, etc.) are available once the account page TemplateLoader refactor ships — see Action Hooks Reference.


[benecaster_qr_code]

Attribute Type Default Description
show_id int Required
type string feed feed — subscriber’s private feed URL (Premium, requires active license); signup — show’s public signup page URL (Free)
size int 200 Display size in pixels (clamped 80–1000). Controls the inline QR code size only — download file dimensions are fixed
download bool true Show download button(s)
format string both Which download button(s) to show: both, svg, or png

Premium (type=feed) / Free (type=signup).

Download file specs (hardcoded, unaffected by size):

  • SVG — 50 mm × 50 mm with 4-module quiet zone; print-ready
  • PNG — 1000 × 1000 px (~300 DPI up to 8.4 cm)

For type=feed, the QR code renders only after the subscriber resets their token — the full token is never stored server-side; the QR graphic is generated client-side from the token returned by the reset endpoint.

benecaster_qr_code_output

Parameters: $html (string), $show_id (int), $atts (array). Filters the wrapper container HTML. The QR graphic itself is generated client-side and is not in the filtered HTML.

Premium (type=feed) / Free (type=signup).


Output Filter Summary

Filter Parameters Free/Premium
benecaster_player_output $html, $episode_id, $atts Free
benecaster_subscribe_output $html, $show_id, $atts Premium
benecaster_feed_url_output $html, $show_id, $atts Premium
benecaster_qr_code_output $html, $show_id, $atts Premium/Free
benecaster_episodes_output $html, $show_id, $atts Free
benecaster_locked_content_message $html, $episode_id, $required_tier, $user_tier Free
benecaster_upgrade_prompt_html $html, $episode_id, $show_id, $required_tier, $user_tier Free
benecaster_subscriber_count_output $html, $count, $atts Premium
benecaster_episode_count_output $html, $count, $atts Free
benecaster_tier_price_output $html, $price, $atts Premium
benecaster_tier_name_output $html, $name, $atts Premium
benecaster_pricing_table_output $html, $tiers, $show_id, $atts Premium
benecaster_show_description $description, $show_id, $type Free
benecaster_show_description_output $html, $show_id, $atts Free
benecaster_episode_description $description, $episode_id Free
benecaster_episode_description_output $html, $episode_id, $atts Free
benecaster_latest_episode_output $html, $episode_id, $atts Free
benecaster_episode_nav_prev $episode, $current_episode_id, $atts Free
benecaster_episode_nav_next $episode, $current_episode_id, $atts Free
benecaster_episode_nav_output $html, $episode_id, $atts Free
benecaster_related_episodes_query_types $types Free
benecaster_related_episodes $episodes, $episode_id, $query, $atts Free
benecaster_related_episodes_output $html, $episode_id, $atts Free
benecaster_episode_share_text $text, $episode_id, $atts Free
benecaster_episode_share_output $html, $episode_id, $atts Free
benecaster_show_social_links $links, $show_id Free
benecaster_social_links_output $html, $show_id, $atts Free
benecaster_rss_link_output $html, $show_id, $atts Free
benecaster_platform_links_output $html, $show_id, $atts Free
benecaster_search_output $html, $show_id, $atts Free
benecaster_member_thanks_query_types $types Free
benecaster_member_thanks_output $html, $members, $atts Free
benecaster_episode_link_output $html, $episode_id, $atts Free
benecaster_timestamp_output $html, $time, $atts Free

Recipes

Wrap the subscriber count in an animated counter

add_filter(
    'benecaster_subscriber_count_output',
    function ( string $html, int $count, array $atts ): string {
        if ( $html === '' ) {
            return $html; // Respect the minimum threshold.
        }
        return '<span class="js-counter" data-target="' . $count . '">' . $html . '</span>';
    },
    10,
    3
);

The $count parameter gives the raw integer before formatting — embed it as data-target for a JavaScript counter animation library.


Add a feature list between tier columns in the pricing table

add_filter(
    'benecaster_pricing_table_output',
    function ( string $html, array $tiers, int $show_id, array $atts ): string {
        $features = [
            'basic'   => [ 'RSS feed access', 'Email support' ],
            'premium' => [ 'RSS feed access', 'Priority support', 'Early access' ],
        ];
        // Inject feature rows after the price row in each column.
        // $tiers contains {slug, name, price, external_tier_id} per rendered column.
        foreach ( $tiers as $tier ) {
            $list = $features[ $tier['slug'] ] ?? [];
            // Build and inject HTML per column using $tier['slug'] as a class target.
        }
        return $html;
    },
    10,
    4
);