benecaster_feed_episode_data
Filters the data array for one episode before its <item> is rendered. Every key reaches the tag it names — the plain RSS elements, the itunes: tags and <content:encoded> are all rendered from the array this filter returns. The most granular per-episode customisation point in the feed, and — with $tier_slug — the way to give the public feed a teaser while paid feeds carry the full show notes.
Fires once per episode, per tier, per feed compilation. On a cold cache for a large show that is many calls, so keep callbacks lightweight.
| Key | Type | Renders as |
|---|---|---|
title |
string | <title> and <itunes:title> |
link |
string | <link> — the episode page URL |
description |
string | <description> — plain text: the Podcatcher Description, or the stripped show notes, plus any episode credit |
summary |
string | <itunes:summary> — the Podcatcher Description only; omitted when empty |
content_encoded |
string (HTML) | <content:encoded> — the show notes with the tier gate resolved, plus any credit; an empty string omits the tag |
pub_date |
string (RFC 2822) | <pubDate> |
guid |
string | <guid isPermaLink="false"> |
enclosure_url |
string | <enclosure url> — omitted, with the whole tag, when empty |
enclosure_size |
int | <enclosure length> (bytes) |
enclosure_type |
string | <enclosure type> — audio/mpeg when empty |
duration |
string | <itunes:duration> — already the tier’s own variant duration when it has one |
explicit |
bool | <itunes:explicit> |
artwork |
string URL | <itunes:image href> |
author |
string | <itunes:author> |
episode_number |
int | <itunes:episode> — omitted when 0 |
season |
int|null | <itunes:season> — only when the show has seasons turned on |
episode_type |
string | <itunes:episodeType> — full, trailer or bonus; any other value renders full |
⚠ description and summary are two keys on purpose. They hold different values by default, so changing one does not move the other. Change both for a teaser that every app shows.
podcast: tags (<podcast:season>, <podcast:episode>, <podcast:transcript> and the rest) are not in this array — they have their own authoritative filter, benecaster_feed_podcast_episode_tags.
Teaser show notes on the public feed, full notes for supporters
$tier_slug makes the per-tier feed a structured edit instead of string surgery on the finished XML. The public feed compiles as tier public.
Set all three keys. Apps differ in which one they show, and they hold different values by default — changing description alone leaves the full notes in <content:encoded>, which is what Apple Podcasts displays.
This changes the public feed only. The episode page on the website is gated separately (benecaster_user_can_access_episode(), [benecaster_tier_gate]).
<?php
add_filter( 'benecaster_feed_episode_data', function ( array $data, int $episode_id, int $show_id, string $tier_slug ): array {
if ( 'public' !== $tier_slug ) {
return $data; // Paying tiers keep the full notes.
}
$teaser = wp_trim_words( $data['description'], 40 ) . ' Full notes for supporters.';
$data['description'] = $teaser; // <description>
$data['summary'] = $teaser; // <itunes:summary>
$data['content_encoded'] = '<p>' . esc_html( $teaser ) . '</p>'; // <content:encoded>
return $data;
}, 10, 4 );
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
$data |
array |
— | Episode data array. See the description for every key and the tag it renders. |
$episode_id |
int |
— | ID of the episode |
$show_id |
int |
— | ID of the show |
$tier_slug |
string |
— | Tier slug for this feed compilation pass (`public` for the public feed) |
Returns:
array
Examples
Teaser show notes on the public feed only
add_filter( 'benecaster_feed_episode_data', function ( array $data, int $episode_id, int $show_id, string $tier_slug ): array {
if ( 'public' === $tier_slug ) {
$teaser = wp_trim_words( $data['description'], 40 ) . ' Full notes for supporters.';
$data['description'] = $teaser;
$data['summary'] = $teaser;
$data['content_encoded'] = '<p>' . esc_html( $teaser ) . '</p>';
}
return $data;
}, 10, 4 );
Override episode title from post meta
add_filter( 'benecaster_feed_episode_data', function ( array $data, int $episode_id ): array {
// Moves both <title> and <itunes:title>.
$seo_title = get_post_meta( $episode_id, '_my_rss_seo_title', true );
if ( $seo_title ) {
$data['title'] = $seo_title;
}
return $data;
}, 10, 2 );
Append sponsor message to description
add_filter( 'benecaster_feed_episode_data', function ( array $data ): array {
$sponsor = get_option( 'my_feed_sponsor_message' );
if ( $sponsor ) {
$data['description'] .= "\n\n" . $sponsor;
}
return $data;
} );
Notes
**Prefer this filter over benecaster_feed_item_xml and benecaster_feed_xml.** Changing structured data before rendering is safer than editing the XML string. To add an element this array has no key for, use benecaster_rss_extra_item_tags.
enclosure_url is also reachable through benecaster_feed_enclosure_url,
which runs earlier; this array receives its result.
$tier_slug was added 2026-09-18 as a trailing argument; a callback registered for three arguments is unaffected.
Before that date the itunes: keys and content_encoded did not reach their tags, whatever this page said.
Need this built rather than just documented? See our services →