Install
Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/mikeyperes/smp-core-podcast-integration/releases/download/v3.3.0/smp-core-podcast-integration-3.3.0.zipHexa WordPress integration for podcast content, ACF field structures, profile relationships, PowerPress metadata, feeds, shortcodes, a persistent audio/video player, playback-preserving navigation, and release diagnostics.
Requirements
- WordPress 6.2 or newer
- PHP 8.0 or newer
- Advanced Custom Fields Pro
- PowerPress for enclosure synchronization and the public podcast feed
- SMP Verified Profiles for profile-backed hosts and guests
Only ACF is required for the field layer. Optional integrations never prevent the settings dashboard or unrelated runtime features from loading.
Architecture
smp-core-podcast-integration.php: canonical WordPress bootstrap and updater configurationinitialization.php: compatibility entrypoint for installations activated under the old basenamesrc/Bootstrap: Core module registration and registriessrc/Admin: Hexa WP Core dashboard and authenticated operationssrc/Acf: canonical podcast field groups with stable ACF keyssrc/Content: content and default-host behaviorsrc/Frontend: shortcodes, audio-source resolution, the persistent player, playback navigation, displays, and feedssrc/Integrations: PowerPress synchronizationsrc/Diagnostics: shared Hexa integration testslib/hexa-wordpress-plugin-core: bundled shared UI, updater, registry, AJAX, and test runtime
The plugin defaults to existing WordPress posts. It does not migrate podcast archives to a new post type. A dedicated episode content model can be selected intentionally from the dashboard.
Mixed-post content-kind contract
ScaleMyPodcast owns the protected _mpp_content_kind post-meta contract. Its
only valid values are episode and article. An explicit episode is
authoritative even before incidental podcast fields exist; an explicit
article vetoes podcast queries, ACF episode fields, default-host processing,
PowerPress synchronization, and podcast player/shortcode resolution even if
legacy podcast metadata remains. Only posts with no content-kind metadata may
temporarily use the historical podcast-marker fallback. Invalid explicit
values fail closed.
Legacy podcast-marker fallback is a pre-backfill compatibility bridge, not a
permanent classifier. The guarded exact-ID migration disables it in the same
transaction that assigns the reviewed episode corpus, preventing a future
unclassified article with ordinary linked-media enclosure metadata from
entering podcast queries or integrations.
Classification is authored through the normal nonce-protected editor meta box. The protected key is deliberately not REST-writable because first-time episode classification has lifecycle side effects, including default-host assignment; allowing a data-only REST write would bypass those guarantees.
The tools-only migration under tools/ is not loaded by WordPress. It refuses
to infer corpus identity from the 158 published, 6 draft, and 1 private counts:
planning requires a read-only, externally reviewed, checksummed list of the
exact 165 IDs. It must not be run without its documented production gates.
Compatibility Contracts
- Existing post, option, ACF, and PowerPress metadata remains in place.
- ACF group keys
group_6844c5d5cf57fandgroup_6848b7b0247ccremain canonical. - All nine legacy shortcode tags remain registered, plus the canonical
[smp_listen_button]and[smp_watch_button]media triggers. - The old active basename
smp-core-podcast-integration/initialization.phpmigrates to the canonical plugin file automatically. - The public PowerPress feed remains
/feed/podcast/. - Optional internal integration feed:
/feed/internal-rss/. - The player uses one audio element and one on-demand privacy-enhanced YouTube iframe. Audio URLs prefer PowerPress, then ACF
audio,audio_url, and the WordPressenclosurevalue; video uses the validated episodeurls_youtubevalue. - No unauthenticated admin AJAX action, public REST route, app shell, hash router, or alternate indexable response is introduced.
Admin
Open Settings > Scale My Podcast. The dashboard uses Hexa WP Core for sidebar tabs, collapsible structures, content-type and ACF controls, snippets, shortcodes, update panels, dynamic buttons, and integration tests.
The Persistent Player tab saves through an authenticated, nonce-protected AJAX action. The player is opt-in by default and exposes independent switches for playback-preserving navigation, inline video, the Audio / Video switch, timestamp transfer, Media Session, remembered preferences, artwork, skip, rate, volume, download, and close controls. Playback-preserving navigation is eligible only while the selected audio or video medium is actively playing; pause, close, end, and error immediately return links and history to ordinary browser behavior. The tab also controls the bounded content selector, excluded paths, timeout, transition, and skip intervals.
Player and Elementor Contract
Use [smp_listen_button] or [smp_watch_button] in an Elementor Shortcode widget, WordPress content, or a PHP template. Optional attributes are post_id, label, and class; Watch also accepts element="button" for legacy button-only placement while its default output is a real YouTube anchor. The server-rendered controls carry both available media sources so visitors can switch formats without leaving the current episode. A native Elementor Watch button may retain its real dynamic YouTube URL and add the smp-watch-button class; the runtime intercepts only an unmodified primary click while inline video is enabled.
For rebuilt Elementor templates, put data-smp-ajax-root on the one content island that should change between pages. Compatible explicit marker values may navigate to each other. Without explicit markers, selector changes are limited to the hardcoded Elementor page, post, single, and archive surface matrix; custom and bounded main.site-main or main#content selectors must match exactly. Keep the fixed player, persistent header, and persistent footer outside that island. Header, footer, navigation, whole-document, broad main, ambiguous selectors, and one-sided or mismatched explicit markers are rejected.
Plugin-owned markup that must live outside the replaceable island uses the inert companion contract. The only currently supported companion is one outside-root `
Releases
1 release. Each count is every asset in that release; expand a row for the breakdown.