benecaster_episode_editor_tabs
Filters the tab configuration array used by the episode editor sidebar, allowing add-ons to declare custom tabs with fields that render automatically. The core React app fetches this configuration at page load via `GET /benecaster/v1/admin/extensions` and renders any declared tabs alongside the built-in sidebar tabs.
This is the Tier 1 extension surface — you can declare field-only tabs without writing any JavaScript. Fields with `meta: true` are automatically saved as episode post meta using the field `id` as the meta key. Supported field types are `text`, `textarea`, `select`, `toggle`, `number`, `url`, and `post_select`. For tabs that need custom React components (live previews, third-party embeds, custom pickers), use the Tier 2 SlotFill approach: declare the tab shell here and fill [BenecasterEpisodeEditorTab_{id}](/hooks/BenecasterEpisodeEditorTab_{id}/) with your component. Core tabs occupy the first positions in the sidebar; add-on tabs appear after them in the order they were appended to `$tabs`.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
$tabs |
array |
— | Array of tab declaration arrays. Required keys per tab: `id` (string — unique tab identifier; used as the React tab key and the SlotFill slot name suffix), `label` (string — tab label shown in the sidebar), `sections` (array — each section has `id`, `label`, and `fields`). Optional keys: `icon` (string — icon name from the Benecaster icon set, e.g. `'puzzle'`, `'star'`, `'settings'`), `add_on` (string — add-on slug, shown as a badge on the tab for discoverability). Each entry in `sections[].fields` accepts: `id` (string, required — meta key when `meta: true`, otherwise the React key), `type` (string, required — one of `text`, `textarea`, `select`, `toggle`, `number`, `url`, `post_select`), `label` (string, required — field label in the editor), `default` (mixed, optional — value shown before the episode is first saved), `meta` (bool, optional — when `true` the value is saved as episode post meta using `id` as the key), `options` (array of `{value, label}` objects, required for `select` type). |
Returns:
array
Examples
Add sponsorship tab with text field
add_filter( 'benecaster_episode_editor_tabs', function( $tabs ) {
// Add a "Sponsorships" tab with a text field for the episode sponsor.
$tabs[] = [
'id' => 'sponsorships',
'label' => 'Sponsorships',
'icon' => 'megaphone',
'add_on' => 'my-sponsorships-addon',
'sections' => [
[
'id' => 'main',
'label' => '',
'fields' => [
[
'id' => '_episode_sponsor',
'label' => 'Sponsor name',
'type' => 'text',
'meta' => true,
],
],
],
],
];
return $tabs;
} );
Tab with toggle and textarea fields
add_filter( 'benecaster_episode_editor_tabs', function ( array $tabs ): array {
$tabs[] = [
'id' => 'my-addon',
'label' => __( 'My Add-on', 'my-addon' ),
'icon' => 'puzzle',
'add_on' => 'my-addon',
'sections' => [
[
'id' => 'my-settings',
'label' => __( 'Settings', 'my-addon' ),
'fields' => [
[
'id' => '_my_addon_feature_enabled',
'type' => 'toggle',
'label' => __( 'Enable feature for this episode', 'my-addon' ),
'default' => false,
'meta' => true,
],
[
'id' => '_my_addon_note',
'type' => 'textarea',
'label' => __( 'Internal production note', 'my-addon' ),
'meta' => true,
],
],
],
],
];
return $tabs;
} );
Notes
This is the Tier 1 (PHP config) extension surface — no client-side JavaScript required for field-only tabs. For tabs that need custom React components, use the Tier 2 SlotFill approach: declare the tab shell here, then fill the BenecasterEpisodeEditorTab_{id} slot with your component. Core tabs always appear first in the sidebar.
Related filters: benecaster_settings_pages — declare an add-on page in the show settings nav; benecaster_dashboard_cards — declare a card on the main Benecaster dashboard. See also: the add-episode-editor-tab-via-php recipe for a complete working example.
Affects
- Episode Editor Sidebar