benecaster_episode_references
Filters the references array when the References section of the episode page renders. It is a render hook only: it does not run on the episode or references REST responses, and it does not affect what is stored.
You can inject additional keys onto any reference object, remove references, reorder them, or inject entirely synthetic entries with string-based id values. Core renders each url exactly as it is and appends nothing to it, so per-episode click attribution is yours to add: rewrite url inside the filter, which already receives $episode_id.
Why it stays off the REST reads. Those responses feed the episode editor, which posts each reference’s URL back on save — and an edit to a reference attached from the library updates the shared library item. A rewritten URL shown there would be saved over the real one for every episode that cites it. An add-on that relied on this filter to annotate the editor’s data needs another route. There is deliberately no core option to add an episode parameter to reference links.
A theme that overrides benecaster/episode/references.php renders from its own copy and must apply this filter itself.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
$references |
array |
— | Array of reference objects {id, reference_id, label, library_label, url, description, display_label, group_id, display_order}. `label` is the resolved display label (the per-episode override when set); `library_label` is the library item's own label. |
$episode_id |
int |
— | ID of the episode |
$show_id |
int |
— | ID of the show |
Returns:
array
Examples
Inject synthetic affiliate reference
add_filter( 'benecaster_episode_references', function( $references, $episode_id, $show_id ) {
$affiliate_url = 'https://myaffiliate.example.com/?ep=' . $episode_id;
$references[] = [
'id' => 'affiliate-' . $episode_id,
'reference_id' => 0,
'label' => 'Affiliate Partner',
'url' => $affiliate_url,
'description' => '',
'display_label' => 'Affiliate Partner',
'group_id' => null,
'display_order' => 99,
];
return $references;
}, 10, 3 );
Point references at tracked redirect URLs on the episode page
add_filter( 'benecaster_episode_references', function( array $references, int $episode_id, int $show_id ): array {
// The episode editor loads references over REST; leave the stored URLs alone there.
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
return $references;
}
// Keyed by reference_id, which stays the same across every episode that cites the reference.
$tracked = (array) get_option( 'myplugin_tracked_references', [] );
foreach ( $references as &$ref ) {
$reference_id = (int) ( $ref['reference_id'] ?? 0 );
if ( isset( $tracked[ $reference_id ] ) ) {
$ref['url'] = $tracked[ $reference_id ];
}
}
unset( $ref );
return $references;
}, 10, 3 );
Exclude references by group
add_filter( 'benecaster_episode_references', function( array $references, int $episode_id, int $show_id ): array {
return array_values( array_filter( $references, function( array $ref ): bool {
return $ref['group_id'] !== 42; // Exclude internal-only group.
} ) );
}, 10, 3 );
Notes
This filter fires on read, not on write — it does not affect what is stored in the database. The primary use case is an add-on that points references at externally managed URLs (for example, a tracked redirect) without modifying the stored url field. Key that data on reference_id, the library ID shared by every episode that cites the reference. The entry's id is the per-episode usage row and changes every time the episode is saved. The episode page reads only the keys it renders (label, url, description, group_id), so an extra key such as tracked_url is not shown unless your own template uses it. The filter may fire more than once per episode editor load.
Need this built rather than just documented? See our services →