Skip to main content

Recipes

Drop-in code examples for extending the Benecaster plugin.

Tier:

Count feed downloads with Podtrac, OP3 or Podscribe

Free Beginner

No code needed for the common case. Open Show Settings → Feeds and paste the service’s prefix into Enclosure URL prefix — e.g. https://dts.podtrac.com/redirect.mp3/, https://op3.dev/e/, or your Podscribe…

Redirect feed URLs to pretty permalink format

Premium Beginner

For core’s own pretty form you need no code. Tick Benecaster → Settings → Permalinks → Private feed URLs → Use pretty feed URLs and every subscriber URL…

Add a custom field to the RSS feed

Free Intermediate

Two hooks work in combination here: benecaster_episode_custom_fields exposes a custom field’s value through the episode data layer, and benecaster_rss_extra_item_tags appends the corresponding XML to each RSS item. Use…

Measure and log feed render time

Free Beginner

Pairing benecaster_feed_before_render with benecaster_feed_after_render gives you the real render duration for a feed request. Useful when you suspect feed generation is slow but want evidence rather than a…

Add Podlove chapter markers to RSS

Free Beginner

Benecaster manages chapter markers natively via the episode editor. Use this recipe when you need to append a podcast:chapters tag directly — for example, to pull chapter data…

Inject chapter markers from an external source

Free Beginner

Benecaster manages chapter data natively in the episode editor. Use this recipe when your chapter data lives in an external service — Podlove, Ausha, or a custom endpoint…

Override locked content message per tier

Premium Beginner

The default locked-content message is generic. This recipe customizes the message based on the tier required to access the episode — showing “Upgrade to Premium” for paid-only content…

Grant access based on WooCommerce product purchase

Premium Intermediate

Benecaster’s bridge system handles subscription-based access, but sometimes access should be granted based on a one-time product purchase rather than a recurring membership. This recipe uses benecaster_episode_is_accessible to…

Detect and log invalid feed token attempts

Premium Beginner

Benecaster already does this, and for most sites that is enough. Invalid token attempts are recorded in the feed request log without any code from you, and an…

React to subscription events from any bridge

Premium Beginner

Benecaster relays bridge events as WordPress actions, making the same code work regardless of whether the site uses MemberPress, WooCommerce Subscriptions, Restrict Content Pro, or a custom bridge.…

Send a Slack alert when a subscriber's tier changes

Premium Beginner

benecaster_subscription_tier_changed fires on every tier change, bridge-driven or admin-triggered. Use it to send a Slack alert, CRM event, or any secondary channel alongside the built-in tier_change email.

Sync changed episode fields to an external system

Free Intermediate

Fires on every episode save that is not the first creation. $changed_fields lists only the post-table columns that actually changed (title, content, post_status, post_date) — it is empty…

Assign episode numbers based on a custom sequence

Free Beginner

Benecaster assigns max + 1 across all published episodes by default. Use this filter to suppress auto-numbering for trailers and bonus episodes, restart numbering per season, or skip…

Sync show creation to external CRM

Premium Intermediate

Three show lifecycle hooks cover the full CRUD lifecycle. benecaster_show_created fires once on first save; benecaster_show_updated fires on every subsequent save with a $changed_fields array listing post-level changes;…

Suppress welcome email and send custom version via SendGrid

Premium Beginner

Benecaster’s built-in welcome email covers the basics, but many podcasters have existing welcome sequences in SendGrid with branding, sequences, and conditional logic that the built-in template can’t replicate.…

Add custom merge tags to all emails

Premium Intermediate

Custom merge tags registered via benecaster_email_merge_tags are available in all Benecaster emails. With the Email Editor add-on active, these tags are also available in the drag-and-drop template builder…

Sync email opt-outs to Mailchimp

Premium Beginner

When a subscriber opts out of Benecaster emails via the unsubscribe link, propagate the opt-out to your Mailchimp audience so the preference is consistent across systems. benecaster_email_resubscribed fires…

Add SendGrid category tracking to all emails

Premium Beginner

Tags every outbound Benecaster email with a SendGrid category so the SendGrid dashboard can slice open-rate, bounce-rate, and unsubscribe metrics by email type. The category is attached by…

Register a custom email type with the Email Editor

Premium Intermediate

Any email type registered via benecaster_managed_email_types appears as an editable template in the Email Editor UI. Add-ons that send their own email types — episode notifications, community alerts,…

Capture custom RSS namespace data during an import

Free Beginner

benecaster_episode_imported fires after each episode is saved, whether it came from a one-time import or from Feed Sync — both are core. Feed Sync also runs benecaster_feed_sync_import_data first,…

Parse custom RSS namespace and map to Benecaster custom field

Free Intermediate

benecaster_feed_sync_import_data fires during core Feed Sync, before the draft is created. It reshapes only the keys it documents — title, content, description_rss, post_date, audio_url, file_size, mime_type, duration, episode_number,…

Register an add-on CPT with the custom field system

Premium Intermediate

Benecaster registers benecaster_episode with the field system automatically. Add-ons that introduce their own CPTs (e.g. Guest Manager’s benecaster_guest) must call benecaster_register_field_cpt() inside a benecaster_boot callback so the CPT…

Inject a dynamically generated field group

Free Intermediate

Prepend or append field groups generated at runtime — from external data, plugin state, or computed summaries — without storing them in the database. Synthetic groups (non-integer IDs)…

Add a tab to the episode editor via PHP filter

Free Intermediate

The simplest way to extend the episode editor. Declare a tab with sections and fields using a PHP array — no JavaScript required. The Benecaster admin app fetches…

Inject a React component into a named slot

Premium Advanced

For interactive UI that can’t be expressed as a field declaration — custom pickers, live previews, embedded third-party widgets — add-ons register React components directly into named extension…

Add a custom REST endpoint from your add-on

Premium Intermediate

Register the route with WordPress directly and use Benecaster’s permission callback, benecaster_rest_permission_admin(). No base class, no container, no benecaster_boot — the endpoint is a plain WordPress route that…

Inject a synthetic reference group from an add-on

Free Intermediate

Reference groups organise show-notes links into labelled sections. Groups normally come from the show’s own configuration, but an add-on can append one that exists only at render time…

Perform a community action on episode publish

Premium Intermediate

Benecaster calls onEpisodePublished() on every registered, configured platform when benecaster_episode_published fires. Implement this method to create a discussion thread, post an announcement, pin a notification, or update a…

Build a custom subscriber dashboard with template functions

Premium Intermediate

Build a fully custom subscriber account page from benecaster_get_user_tier_for_show(), benecaster_get_feed_url(), and benecaster_get_template_part() in a theme template. This is the alternative to the built-in Blocks & Widgets account block…

Inject a step into the setup wizard from an add-on

Premium Intermediate

Add-ons inject additional steps into the Setup Wizard by hooking into the steps array before the wizard runs. The wizard re-evaluates which steps are active whenever its state…

Add a custom bridge card to the wizard Subscription step

Premium Intermediate

Add-ons that provide a non-built-in subscription bridge inject their card into the wizard’s Subscription step. The slug must match the bridge’s get_plugin_slug() return value so POST /bridge/activate can…

Add a Custom Section to the Analytics Digest

Premium Intermediate

Add your add-on’s data to any Benecaster Analytics Digest (daily, weekly, or monthly) by injecting a data payload via benecaster_analytics_digest_data and registering a custom section via benecaster_analytics_digest_sections. This…

Trigger a Feed Cache Clear from External Code

Free Beginner

Trigger a Benecaster feed cache clear from any plugin, mu-plugin, or WP-CLI cron job using the benecaster_clear_feed_cache action. Supports global, show-scoped, and tier-scoped clears. benecaster_feed_cache_cleared fires after any…

Customize the Upgrade Prompt for a Specific Show

Premium Beginner

Change the wording of the upgrade prompt a logged-in subscriber sees when they land on an episode above their tier, or add a link to it, using benecaster_upgrade_prompt_html.…

Add a Custom Section to the Show Page

Free Beginner

Use benecaster_after_show_episode_list to inject HTML below the episode listing without overriding a template file. Each show page action hook fires with $show_id as its only argument. Swap to…

Inject Podcasting 2.0 Episode Tags from an Add-on

Free Intermediate

The episode-level half of Podcasting 2.0: transcripts, soundbites, season numbers, per-episode artwork, and credits. Benecaster fills these in from the episode’s own settings, and benecaster_feed_podcast_episode_tags hands the set…

Auto-populate Feed Credits from Guest Manager

Premium Intermediate

Inject read-only Podcasting 2.0 credits into an episode’s Feed Credits section without writing to post meta. Benecaster calls benecaster_podcast2_episode_auto_feed_credits after loading meta-stored credits, merges the returned array into…

Customize [benecaster_current_tier] output

Premium Beginner

The current-tier shortcode drops a subscriber’s tier name onto a page. That is deliberately plain, and often not quite what a podcaster wants — they would rather greet…

Redirect episode navigation links

Free Intermediate

Use benecaster_episode_nav_prev and benecaster_episode_nav_next to change which episode “prev” or “next” points to — for example, skipping bonus episodes, enforcing season boundaries in the Episode Page block, or…

Register a custom related-episodes query strategy

Free Advanced

Use benecaster_related_episodes_query_types to add a custom query strategy to the benecaster_related_episodes shortcode and the related_episodes Episode Page block. Any add-on can register one or more strategies; they appear…

Override the related-episodes list per-episode

Free Beginner

Use benecaster_related_episodes to filter the resolved episode list before the shortcode or Episode Page block renders it. Return a modified array to inject specific episodes, enforce premium-only results,…

Inject or reorder social links programmatically

Free Beginner

Filter the resolved social links array before [benecaster_social_links] or the episode page social block renders them. Each item is ['platform' => string, 'url' => string, 'label' => string].…

Replace the social links HTML entirely

Free Beginner

Filter the final HTML string produced by [benecaster_social_links] or the episode page social block. Use to swap in a custom icon set, wrap the list in additional markup,…

Replace or suppress the RSS link output

Free Beginner

Filter the final output of [benecaster_rss_link]. Use to wrap the link in additional markup, swap in a custom SVG icon, conditionally suppress the link on certain pages, or…

Replace or suppress the platform links output

Free Beginner

Filter the final output of [benecaster_platform_links]. Use to wrap in additional markup, inject custom badge HTML for a specific platform, suppress the block on certain pages, or replace…

Exclude an episode from all search results

Free Beginner

Return false to remove an episode from every search response regardless of tier or query term. Useful when an episode is published but should not be discoverable —…

Augment search result excerpts

Free Beginner

Override the per-result excerpt returned by the search endpoint. Useful to substitute transcript snippets, chapter titles, or custom-formatted highlights. The Transcription Service add-on uses this pattern to surface…

Tell the Add-ons screen that this add-on plugin is loaded

Premium Beginner

Benecaster fires benecaster_installed_addons during admin bootstrapping to build the list of loaded add-ons. Each add-on plugin should hook this filter inside its benecaster_boot callback and append its fully-qualified…

Which subscriber count is the paying one

Free Intermediate

Benecaster issues a token to three different populations: paying subscribers, free-tier bridge members (a [Free] MemberPress level mapped into Benecaster, say), and direct followers who came in through…

React to a free follower signup

Free Intermediate

The follower signup shortcode creates a WordPress user, issues them a follower token, and then fires benecaster_follower_signed_up( int $user_id, int $show_id, string $tier_slug ). The hook means one…

Redirect the account page URL to a custom path

Premium Beginner

benecaster_account_page_url() returns the permalink of the /podcast-account/ page Benecaster creates on activation. Every plugin-generated link to a subscriber’s account — token emails, QR code screens — goes through…

Mutate or block outgoing webhook payloads per event

Premium Intermediate

The outbound webhook system POSTs subscription/token events with a sha256= HMAC header. benecaster_webhook_payload runs once per event after the dispatcher assembles the payload, before signing. Add custom keys,…

React to a badge definition being deleted

Premium Beginner

When a badge definition is deleted, Benecaster quietly removes the tier-auto rules and detaches manual grants — but anything outside of Benecaster doesn’t know it happened. If you’ve…

Replace or wrap the assembled Supporter Wall HTML

Premium Intermediate

Fires after the default markup is assembled for both the populated and empty branches of the benecaster_supporter_wall shortcode. $html is the complete rendered output. $subscribers is the raw…

Add a new payment processor alongside Stripe

Premium Advanced

Implement PodcastPaymentGateway and register your instance through the benecaster_payment_gateways filter. The filter is applied lazily, on first read rather than at plugin load, so registering from a benecaster_boot…

Register an add-on handler on the shared Stripe webhook endpoint

Premium Intermediate

Benecaster exposes a single shared endpoint at POST /benecaster/v1/stripe-webhook that verifies the Stripe-Signature header once and dispatches to per-event handlers. Add-ons register additional handlers via benecaster_stripe_webhook_handlers rather than…

Register a custom export sheet from an add-on

Premium Advanced

The sheets filter fires twice per export request: once when the React UI renders checkboxes and once when the XLSX file is generated (only checked sheets are written).…

Ship template parts from an add-on

Premium Intermediate

Register a directory once at boot and every Benecaster template lookup can find your parts — both ones that replace a core default and ones core has never…

Override teaser content with a chapter preview

Free Beginner

Use benecaster_teaser_content to replace the default word-count or description teaser with any custom preview — for example the first chapter heading from the Chapter Markers add-on. The filter…

Check episode access in a shortcode or widget

Premium Beginner

Use the public access-check functions to conditionally render premium content in any PHP context. benecaster_user_can_access_episode() returns true for public episodes regardless of subscription status. benecaster_get_user_tier_for_show() returns the tier…

Replace the episode share links with a custom share card

Free Beginner

The default episode/share.php renders X, Facebook, and LinkedIn share links. Replace the whole set or inject additional platforms via benecaster_episode_share_links. Each entry is an associative array with label…

Hide the sort controls on the episode archive

Free Beginner

Return false from benecaster_archive_show_filters to suppress the sort/filter bar entirely. Useful when the archive is embedded in a page layout where external filtering is handled by JavaScript or…

Register a custom Member Thanks query type

Premium Advanced

The [benecaster_member_thanks] shortcode features a list of subscribers on any page or episode — recent joiners, top-tier members, or other built-in selections. The query type controls which subscribers…

Tune or bypass the per-IP REST rate limiter

Premium Intermediate

Two situations call for this recipe. First: your add-on registers a REST endpoint that legitimately receives higher traffic than the default bucket allows, and your clients are getting…

Auto-select a credit template based on episode type

Free Intermediate

Use benecaster_credit_options to reorder or mark a specific credit template as default based on episode metadata — for example, always pre-select the guest interview credit template when the…

Log credit applications to an external system

Free Beginner

Use benecaster_credit_applied to send a record to an external system — a webhook, Slack notification, analytics endpoint, or spreadsheet — each time a credit template is stamped onto…

Programmatically stamp a credit on episode save

Free Advanced

Auto-apply the default credit template when a new episode is created so the podcaster never has to click Apply manually. Uses benecaster_apply_default_credit() — the public helper that resolves…

Embed a show QR code on a marketing page

Free Beginner

Use the anonymous public endpoint GET /wp-json/benecaster/v1/shows/{id}/qr.png to embed a show’s public signup QR code on any marketing page, press kit, or static site. The endpoint returns raw…

Track the payment-failed license grace lifecycle

Premium Intermediate

A failed payment on the podcaster’s own Benecaster subscription opens a 30-day grace window. Three actions mark its start, its expiry, and its recovery — enough to drive…

Push donation-enrolled followers to an external newsletter

Free Beginner

Subscribes a newly enrolled follower to an external newsletter platform (ConvertKit shown here) the moment their donation opt-in is confirmed. The benecaster_donor_enrolled_as_follower action fires only when a brand-new…

Add chapter image to the front-end chapter list

Free Beginner

The front-end chapter list renders timestamp and title per row but omits the optional chapter image by default — podcast apps display images via the JSON chapters endpoint,…

Suggest chapter markers from a transcript

Free Intermediate

The chapter editor shows an “Auto-suggest chapters” button when a Transcription Service–style add-on is installed. Clicking it POSTs to the auto-suggest REST endpoint, which defers to the benecaster_chapter_autosuggest…

Tag Manual Grants with User Role

Premium Beginner

The two manual-grant lifecycle actions form a symmetric pair — one fires when a subscriber is comped via the admin “Add subscriber manually” flow, the other when the…

Add Manual Membership Support to a Custom Bridge

Premium Advanced

By default, Benecaster’s “Add subscriber manually” admin action is only available on shows using the built-in membership bridge. Bridge add-ons can unlock this for their bridge by implementing…

Customize Email Header Branding Per Show

Premium Beginner

On a multi-show installation every show sends through the same email wrapper, so without intervention all three of your podcasts arrive looking identical. benecaster_email_wrapper_args receives the show ID,…

Alert PagerDuty When Feeds Go Dark at Day 30

Premium Intermediate

benecaster_license_payment_grace_hard_cutoff fires once, at the end of a 30-day unpaid grace window. At that moment every subscriber on the site has just lost their private feed. For anyone…

Resolve the Outage Alert When Access Is Restored

Premium Intermediate

The other half of Route license hard cutoff to PagerDuty. benecaster_license_payment_grace_recovered fires only when a day-30 cutoff is cleared and tokens are actually restored — never on the…

Render a site-wide show-limit admin notice

Premium Beginner

The built-in show-limit banner appears only on the React Shows portfolio screen (/#/shows). Use this recipe to surface the same alert on every wp-admin page — useful when…

Hide locked episodes from all listing shortcodes

Free Beginner

By default Benecaster renders locked episodes with a “Subscriber only” badge so the episode is still discoverable. This recipe hides locked items entirely — nothing renders in their…

Show a teaser card for locked episodes

Free Intermediate

Where the hide-locked recipe removes locked items entirely, this recipe replaces them with a teaser card that shows the episode title, the first 40 words of the episode…

Highlight Top Supporters on the Donor Wall

Free Beginner

Prepend a “Top supporter” badge to donor-wall cards for donations at or above a configurable amount threshold, without replacing the built-in card markup for lower rows.

Adjust or Disable Export File Auto-Deletion

Premium Beginner

Data exports contain subscriber email addresses and token records, so Benecaster does not keep them lying around: a nightly sweep deletes any export file older than seven days.…

Purchase a buy-up from custom code, safely

Premium Intermediate

Two things make the buy-up purchase endpoint different from a plain authenticated POST, and both are easy to get wrong from outside Benecaster’s own UI. You have to…

Add a quarterly cadence to an existing tier

Premium Intermediate

A membership tier is one Stripe Product with N attached Prices, and those Prices are a collection hanging off the tier rather than a fixed monthly/annual pair on…

Resolve or override an episode's Explicit flag

Free Beginner

The episode-level Explicit flag is a three-value override — 'inherit', 'yes', or 'no' — never a bool. 'inherit' is the default and falls back to the show’s Explicit…

Restyle or reword the Explicit badge

Free Beginner

The Explicit badge is rendered by one class — Benecaster\Episode\ExplicitBadgeRenderer — from every surface it appears on: the episode single page, archive cards, the [benecaster_episodes] list, the [benecaster_player]…

Integrate a community platform not in the Benecaster set

Premium Advanced

Implement CommunityPlatformInterface in your add-on and register the instance through the benecaster_community_platforms filter. The Community Integrations add-on routes all subscription events to every registered platform automatically — including…

Send a Benecaster email type from add-on code

Free Beginner

Registering a type with benecaster_managed_email_types makes it discoverable and editable in the Email Editor. It does not make it send. To actually dispatch one, call benecaster_send_email(). Always pass…

Build a custom follower signup UI

Free Intermediate

[benecaster_follower_signup] is the built-in form. When you want a popup overlay, a Gutenberg block, a custom landing page or a WP-CLI command instead, call benecaster_follower_signup() — it is…

Ask whether this install is staging

Free Intermediate

There are three different questions here and add-ons reliably reach for the wrong one. StagingManager::is_staging() asks “is this a non-production environment?” and is the answer core applies its…

Import a subscriber with their original join date

Premium Intermediate

A migration importing an established audience arrives holding a join date per subscriber. Without carrying it across, every imported token is stamped at import time and TenureBadgeCalculator —…

Override whether a specific episode's downloads get counted

Free Beginner

Resolving whether an episode’s enclosure URL gets substituted for a redirect-proxy URL (and therefore counted) happens in two steps: the episode’s own three-state override (_benecaster_episode_download_tracking) wins when explicitly…

React to a buy-up price migration

Premium Beginner

When a podcaster changes a buy-up’s price, existing holders are grandfathered at their old price by default. The podcaster can instead choose to migrate them onto the new…

React to a One-Click Plan Upgrade

Premium Beginner

benecaster_license_plan_upgraded fires synchronously the moment a podcaster confirms a one-click plan upgrade in Settings → Account → Plan changes — before the next daily validation cron would otherwise…

Register an Add-on Bootstrap With Core's Entitlement Gate

Free Beginner

benecaster_register_addon() replaces the manual any_show_addon_is_active() check add-ons previously wrote inline in their own benecaster_boot handler. Call it once, passing your slug and a bootstrap callback — core invokes…

Customize the License Validation Ping

Premium Intermediate

Filters the complete payload the plugin POSTs to the license server once a day, including the nested telemetry sub-array. Use it to remove or adjust a field before…

Add a Support Diagnostics Section

Premium Beginner

Added feature/security-diagnostics-hardening (Batch 3), 2026-09-11. The hidden Support Diagnostics panel (an admin with manage_options reaches it by appending &bc_support_diag=1 to any Benecaster admin page URL — deliberately undiscoverable,…

Let buy-up holders through a tier gate

Premium Intermediate

min_tier expresses exactly one condition: “at or above this tier”. Anything else — a buy-up, a WordPress role, a date — goes through benecaster_tier_gate_passes, which fires before either…

Break a failed-token spike down by source

Free Intermediate

Core counts failed lookups per show only — deliberately, since a per-IP counter would let an attacker rotating IPs create unbounded storage. The IP hash travels in the…

Tune invalid token alerts per show

Free Beginner

The “Unusual failed feed access” alert defaults to 10 unknown-token requests in 60 minutes, per show. A show with a large audience and a lot of mis-copied URLs…

Audit who acknowledged an admin notice

Free Beginner

Record which admin dismissed a notice and when, for an audit trail or an ops channel. benecaster_notice_dismissed fires once per real dismissal — never for a repeat, a…

Import a follower list from code

Free Intermediate

Add a list of email addresses as free followers from an external system or your own code. Subscribers → Bulk enroll → Add as: Followers is the admin…

Import a back catalogue from an add-on

Free Intermediate

Benecaster’s importer (Feed\FeedBulkImporter) is a stable API. An add-on that guides a podcaster through migration should call it, not copy it. It then gets deduplication by GUID, benecaster_episode_imported,…

Style followers and subscribers differently

Premium Beginner

Free followers stay on the Supporter Wall alongside paying subscribers — core only labels them (a muted Follower chip) and classifies the markup so your theme decides how…

Clean up captured source links on import

Free Intermediate

Both core import paths — the setup wizard’s one-time import and Feed Sync — store each RSS <item><link> (the episode’s page on the old host) as _benecaster_source_link, validated…

Flag imported episodes your own way

Free Intermediate

The Migration Wizard’s reconciliation report, an add-on’s own “what came across?” screen, or a WP-CLI audit all need the same thing: one row per imported draft with the…

Name an add-on's data for Benecaster's uninstall

Free Intermediate

Benecaster’s Delete all data on uninstall switch doesn’t work from a list — it discovers benecaster_-namespaced data by prefix and removes it. That means an add-on’s tables, options,…

Supply a transcript URL from your own service

Free Intermediate

Core’s Podcasting 2.0 auto-detection scans an episode’s attached media for a single .vtt, .srt or .txt file and writes the one it finds to the Transcript URL field.…

React when an episode gains a transcript

Free Intermediate

Do something once, at the moment an episode acquires a Podcasting 2.0 transcript, whatever produced it. The companion to Supply a transcript URL from your own service: that…

Let a non-editor into wp-admin

Free Beginner

Exempt specific people from the subscriber wp-admin redirect, with benecaster_block_subscriber_wpadmin. Signature: benecaster_block_subscriber_wpadmin( bool $should_block, int $user_id ): bool. Free, never licence-gated. Default true. Why a recipe rather than…

Sync a verified email change to your CRM

Free Beginner

Keep an external list in step with a subscriber’s email address, using benecaster_email_changed. Signature: benecaster_email_changed( int $user_id, string $old_email, string $new_email ). Free, never licence-gated. It fires on…

Let a passwordless subscriber set their first password

Free Beginner

Recognise an account whose password Benecaster generated, with \Benecaster\Support\GeneratedPasswordMarker. ⚠⚠ WordPress records nothing that tells these accounts apart, and it cannot be inferred from the hash — every…

Pin a featured episode as "latest"

Free Beginner

[benecaster_latest_episode] and benecaster_get_latest_episode_id() both resolve through this filter, so one callback changes the shortcode, the function and anything built on either. Return null to hide the shortcode entirely.…

Make the transcript link a buy-up perk

Free Intermediate

The episode page shows “Read the transcript” to everyone who can access the episode. To keep it for holders of a “Transcripts” buy-up, narrow the link with benecaster_user_has_buyup().…

Register a token type for a product

Free Intermediate

Give an add-on’s listeners their own token type, so core classifies them correctly everywhere. A token’s type answers who a listener is: one value per person per show.…