Description
Mattytap Sermons lets a church publish sermons online with the structure they actually need: speakers, series, topics, books of the Bible, and service types, all as proper WordPress taxonomies, all searchable, all filterable. Add audio and video, attach handouts (PDF, DOC, PPT, anything), embed video from YouTube or Vimeo, and ship a fully-featured iTunes-compatible podcast feed for the whole library or for any individual series, speaker, topic, or book.
Mattytap Sermons is a maintained restoration of Sermon Manager by WP for Church. The original plugin was last published to WordPress.org in September 2024 (version 2.30.0); the upstream maintainer’s web presence is no longer reachable, and several publicly-disclosed CVEs remain unpatched in 2.30.0 and earlier. Mattytap Sermons is the successor line. Existing Sermon Manager installs (including 2.30.0) can switch to Mattytap Sermons as a drop-in replacement: the database schema, custom post type (wpfc_sermon), taxonomies (wpfc_preacher, wpfc_sermon_series, etc.), all wpfc_* option keys, six core shortcodes, and view templates are preserved. Multi-attachments for notes and bulletin, post-body editor support, and Twenty Twenty-Four theme wrapper are cherry-picked from upstream 2.30.0.
What Mattytap Sermons preserves
- Same shortcodes (
[sermons],[sermon_images],[list_podcasts],[list_sermons],[latest_series],[sermon_sort_fields]) - Same custom post type and taxonomies: existing sermon data carries over without import
- Same template files in
views/: existing theme overrides continue to work - Same Bib.ly Bible-reference integration
- Same iTunes-compatible podcast feeds
What’s new in Mattytap Sermons
- Active security maintenance, with private vulnerability reporting for responsible disclosure
- Modernised for PHP 8.1+ and WordPress 6.0+
- Bundled outdated third-party dependencies removed or upgraded (CMB2, wp-background-processing, the entry-views polyfill, taxonomy-images)
- Continuing development on GitHub
Popular shortcodes
[sermons]: list the 10 most recent sermons[sermons per_page="20"]: list the 20 most recent sermons[sermon_images]: list all sermon series with associated image in a grid[list_podcasts]: list available podcast services with large buttons[list_sermons]: list all series or speakers in a simple unordered list[latest_series]: display information about the latest sermon series, including the image, title, and description[sermon_sort_fields]: dropdown selections to navigate to sermons by series or speaker
Credits
Mattytap Sermons is a restoration of Sermon Manager for WordPress, originally by WP for Church (Jason Westbrook and contributors). The full upstream contributor list is recorded in CONTRIBUTORS.md. Translations were originally contributed by GITNE (German, Polish), Gilles Pilloud (French), and the Dutch translation behind v2.15.13.
Installation
- Use the “Add New” button in the Plugins section of your WordPress dashboard. Search for “Mattytap Sermons”.
- Activate the plugin.
- Add a sermon through the dashboard.
- Display sermons on the front end via shortcode (
[sermons]in any page or post), or by visitinghttps://yourdomain.example/sermons(with pretty permalinks enabled) orhttps://yourdomain.example/?post_type=wpfc_sermon(without).
Migrating from Sermon Manager
If you have an existing Sermon Manager install, install and activate Mattytap Sermons, then deactivate Sermon Manager. All your sermons, speakers, series, topics, and settings carry over without further action. The two plugins use the same database schema. Don’t run both at once; the schema overlap will cause conflicts.
Migrating from Sermon Browser or Series Engine
Mattytap Sermons inherits Sermon Manager’s import functionality for these older sermon plugins. Once Mattytap Sermons is activated, the importer is available under Tools Import.
FAQ
-
How do I display sermons on the front end?
-
Use the shortcode
[sermons]in any page or post, or visithttps://yourdomain.example/sermons(with pretty permalinks enabled) orhttps://yourdomain.example/?post_type=wpfc_sermon(without). -
Go to Appearance Menus. In “Custom Links” add
https://yourdomain.example/?post_type=wpfc_sermonas the URL and “Sermons” as the label. Click “Add to Menu”. -
I’m coming from Sermon Manager. Will my sermons survive?
-
Yes. Mattytap Sermons uses the same database schema, custom post type, taxonomies, and option keys as Sermon Manager. Activate Mattytap Sermons, deactivate Sermon Manager, and existing sermons keep working. Don’t run both at once. The overlapping schema will conflict.
-
How do I report a bug or request a feature?
-
GitHub Issues. For security issues, please use private vulnerability reporting rather than public issues.
-
Is there a paid version or commercial support?
-
No. Mattytap Sermons is GPLv2 free software with no paid tier, no premium add-ons, and no commercial support. Bug fixes, feature requests, and translation contributions are welcome through GitHub.
Reviews
There are no reviews for this plugin.
Contributors & Developers
“Mattytap Sermons” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “Mattytap Sermons” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
3.1.2
- Hardened the “Specific Background Updates” debug tool: the submitted value is now validated against the registered list of update routines before anything is executed.
- Escaping pass over filtered template output: the previous/next sermon navigation links, the deprecated v1 sermon renderers, the
[sermons]shortcode’s per-sermon output, and the preacher-image filter on archive cards are now escaped at output withwp_kses. The sermon-template allowlist now admits provider iframes so pasted video embed codes continue to render. - The Uncode theme-compatibility init call is now printed via
wp_print_inline_script_tag()instead of a hand-built script tag.
3.1.1
- Completed the Mattytap Sermons rename in user-visible admin text. The settings and Import/Export screens, the plugins-page action link, several settings descriptions, and two front-end error messages still displayed “Sermon Works”; all now read “Mattytap Sermons”. The settings page heading is now also translatable.
- Fixed a PHP warning (undefined array key “display”) in the
[sermon_images]shortcode when no matching term images exist. - Replaced
wp_reset_query()withwp_reset_postdata()after the podcast feed’s secondary loop, the correct reset for a custom WP_Query.
3.1
First stable release of the renamed Mattytap Sermons line, and the first WordPress.org submission. No runtime change against 3.1-rc3: this entry promotes the release-candidate cycle to stable. The rc1, rc2, and rc3 entries below record the rename from Sermon Works, the ten WordPress.org pre-review fixes, the three rc1 playback and widget regressions, and the WordPress 6.0 to 6.8 export-compatibility fix closed during the candidate cycle.
3.1-rc3
- Fixed a WordPress 6.0 to 6.8 compatibility regression in the sermon exporter.
wxr_cdata()guarded its encoding fallback withwp_is_valid_utf8(), a function only available since WordPress 6.9, which would fatal on older supported versions. Switched tomb_check_encoding(), restoring the declared WordPress 6.0 floor. Sites on WordPress 6.9 or later were unaffected. - Raised “Tested up to” to WordPress 7.0.
- Plugin Check housekeeping in the WXR exporter, a near-verbatim port of WordPress core’s
wp-admin/includes/export.php: scoped the self-escapingwxr_cdata()output under a documented escape-sniff exemption, and annotated a prepared query the analyser misread as unprepared. No runtime change.
3.1-rc2
Three regressions surfaced during 3.1-rc1 LocalWP canary verification.
- Plyr 3.5+ removed
embed.setCurrentTime()from the YouTube embed surface; the seek-on-load handler inassets/js/plyr.jswas still calling it directly after settinginstance.currentTimevia Plyr’s high-level API. Dropped the redundant embed-direct call: the high-level setter handles seek normalisation across HTML5, YouTube, and Vimeo in 3.7.x. - The F-escape sweep’s
sm_template_allowed_html()helper didn’t whitelist<source>as an allowed child of<audio>and<video>, so every<source>child was stripped silently when the audio/video render passed throughwp_kses(). Audio and video elements rendered as empty shells with no playable source. Added<source>withsrc,type,media,srcset. - The same helper covered
<select>for theonchangeattribute only and didn’t whitelist<option>,<form>, or the rest of<select>‘s attribute set. The sermon archive sort widget and the five taxonomy templates rendered as bare<select onchange="...">shells with no<option>tags. Added the form-element family.
3.1-rc1
First release-candidate of the renamed line. Sermon Works has been renamed to Mattytap Sermons under the WordPress.org slug mattytap-sermons following plugin-team trademark guidance against the prior name. Strapline updated to “Faithful to the source.” Same caretaker, same codebase, same migration path; existing 3.0.x installs upgrade in place.
This release also closes the ten technical items the WordPress.org reviewer’s automated pre-review flagged against the 3.0.2 submission:
- Removed the
load_plugin_textdomaincall (WordPress.org auto-loads translations since WP 4.6). - Replaced PHP 8.2-deprecated
utf8_encodewithmb_convert_encodingin the WXR exporter’s UTF-8 fallback branch. - Added
sanitize_text_field( wp_unslash() )on the defence-in-depth$_REQUEST['_wpnonce']read in the settings save-handler. - Added
esc_url_raw( wp_unslash() )on the$_SERVER['REQUEST_URI']read in the import form action. - Removed the unpaired
ob_start()atadmin_initpriority 1. The other twelveob_start()sites in the codebase are properly paired withob_end_flush()and continue to work as before. - Annotated 45 reviewer-flagged sites carrying legacy upstream
wpfc_*/wp_sm_*/sm_*prefixes withphpcs:ignoreplus rationale comments. The prefixes themselves are preserved deliberately for drop-in compatibility with Sermon Manager. - Applied
wp_kses()and friends at 40 sites across 11 view templates inviews/. A small helpersm_template_allowed_html()extendswp_kses_allowed_html('post')for Plyrdata-*attributes and audio/video element attributes the default kses table strips. Five genuinely-unfixable sites (CDATA-wrapped strings and attribute-fragment echoes) are left annotated with rationale. - Wrapped editor-pane content in
wp_kses_post()in thethe_contentfilter callback. The[list_podcasts]shortcode is now internationalised via__()/sprintf()and its return value wrapped inwp_kses_post()so static scanners see an explicit escaper at the function boundary. - Consolidated the Plyr enqueue path in
sermons.php: replaced twowp_localize_scriptcalls withwp_add_inline_script; droppedmaybe_print_cloudflare_plyrand its manual<script data-cfasync="false">echo in favour of ascript_loader_tagfilter that injects the attribute on the two Plyr handles. Hoisted the dashboard “At a Glance” widget’s inline<style>block towp_add_inline_styleagainst the dashicons handle. The twoUNCODE.initHeader()inline-script sites in the Uncode theme branch remain inline withphpcs:ignoreplus rationale: those calls fire at a mid-body DOM position the Uncode theme’s header initialisation depends on. - Refreshed bundled vendor libraries: Plyr 3.4.7 3.7.8 (verbatim swap from the upstream npm tarball; no JS-API breaking changes; the 3.7.x line includes preview-thumbnail, focus-visible, and border-radius CSS updates which are absorbed automatically because we ship the precompiled CSS from the same release). wp-color-picker-alpha 2.1.3 3.0.4 (verbatim swap from upstream
main; the 3.0.x line is a full rewrite that drops the WordPress 5.5-removedwpColorPickerL10nglobal dependency. No runtime delta in this plugin because the script is dead code: no CMB2 colorpicker field in the codebase sets'alpha' => true).
Drop-in compatibility ethic preserved: the wpfc_sermon custom post type, the wpfc_preacher and wpfc_sermon_series taxonomies, and all wpfc_* option keys are unchanged. Existing Sermon Manager (or 3.0.x Sermon Works) installs continue to migrate without data loss.
3.0.2
Editor-pane render fix following the 3.0.1 cherry-pick of 'editor' into the wpfc_sermon post type’s supports array. In 3.0.1 the WordPress block (or classic) editor pane was visible on the edit-sermon screen but content typed there did not reach the front-end: the add_wpfc_sermon_content callback that drives the the_content filter for sermon posts replaced the post body entirely with the sermon-template render, discarding post_content. Site administrators reaching for the editor pane first (the natural place for any WordPress user) would publish a sermon and see their typed content vanish on the public page.
3.0.2 closes this. The callback now preserves the incoming post_content and, on singular sermon views where it is non-empty, appends it after the sermon-template render in a <div class="wpfc-sermon-editor-content"> wrapper that themes can target. Existing sermons (whose body content lives in the sermon_description post meta key, not in post_content) are unaffected: their post_content is empty, the conditional skip fires, and the front-end render is byte-identical to 3.0.1. New sermons authored via the editor pane now render their content alongside the legacy sermon_description rendering.
No security delta against 3.0.1; no API surface changes; no data migration. Single-file change in includes/sm-template-functions.php.
3.0.1
Drop-in compatibility cherry-picks from upstream Sermon Manager 2.30.0 (the last WP.org-shipped version of the original plugin), informed by a 10-surface compatibility audit against the 2.30.0 baseline (.restoration/DROP-IN-AUDIT.md):
- Multi-attachments for notes and bulletin: the front-end view template now renders the
sermon_notes_multipleandsermon_bulletin_multiplearrays alongside the singular keys. Existing 2.30.0 sites that ran the upstream multi-attachments migration have data in the_multiplekeys; this restores their visibility on the front-end. Two newfile_listCMB2 fields (“Sermon Notes (multiple)”, “Bulletin (multiple)”) are added to the Sermon Files metabox so Sermon Works admins can also create new multi-attachments themselves. - Post-body editor support:
'editor'is added to thewpfc_sermonpost type’ssupportsarray, enabling the WordPress block (or classic) editor on the edit-sermon screen. The Sermon Works rendering model continues to usesermon_descriptionplus thethe_contentfilter; existing sermons render unchanged. New sermons created post-3.0.1 can populatepost_contentvia the editor pane in addition tosermon_description. - Twenty Twenty-Four theme wrapper: the theme-specific archive wrapper now has a balanced
twentytwentyfourcase opening<div class="wp-block-group has-global-padding is-layout-constrained ..."><div id="primary"><main class="site-main wpfc-sermon-container wpfc-twentytwentyfour ...">and the matching close in the wrapper-end partial. Upstream 2.30.0 ships unbalanced (no matching close); Sermon Works ships balanced.
Three upstream changes from 2.30.0 are deliberately not cherry-picked, with rationale documented in .restoration/DROP-IN-AUDIT.md:
- The full editor-support cluster (REST surface change,
the_contentfilter disablement, AJAXupdate_sermon_postsmigration with “Sync Now” button): the upstream rendering-model swap fromsermon_descriptiontopost_contentis invasive, partial cherry-picks risk broken rendering, and the upstream migration has quality issues (missing capability check, debug residue, no rollback UI). Sermon Works keeps the sermon_description-based rendering model. - The
[latest_sermon]shortcode: the upstream handler has three known bugs (orderby attribute silently ignored due to a typo in query-args assembly, duplicate HTML id on a nested div, static-property side effects that persist across requests). Use[sermons per_page="N" order="DESC" orderby="date"]for the same effect.
Framing correction in README and readme.txt: the original Sermon Manager line was actively maintained on WordPress.org through September 2024 (last published version 2.30.0). The “abandoned since 2019” framing in pre-3.0.1 docs was based on the GitHub state and missed the WP.org line.
3.0
3.0 stable cut. No runtime changes against rc6. This entry promotes the release-candidate cycle to stable, capping the restoration arc that began in rc1.
3.0-rc6
CI gate clearance for WordPress.org submission, no runtime changes against rc5. The Plugin Check workflow now passes cleanly on main. The WXR exporter port (includes/admin/export/class-sm-export-sm.php) is excluded at workflow level: it is a near-verbatim derivative of WordPress core’s wp-admin/includes/export.php, and the project’s phpcs.xml.dist registration of wxr_cdata as customAutoEscapedFunctions is honoured by local PHPCS but not by the Plugin Check action. Targeted phpcs:ignore annotations carrying per-site rationale clear the remaining submission-blocking sniffs: the file-system reads in the PNG/JPEG dimension sniffers (sm_get_png_dimensions, sm_get_jpeg_dimensions), the inline Cloudflare-bypass <script> tag in the Plyr enqueuer, and the transient-cleanup direct-DB call. The audit-deferred warning tail (REST nonce annotations, superglobal-input sanitisation, db-caching, footer-flag enqueues) rides this submission with ignore-warnings: true on the action’s pass/fail logic; warnings still surface in the JSON report for review.
3.0-rc5
WordPress.org submission-ready cut, held back behind one more RC for maintainer verification before the 3.0 stable tag flips. Two work strands gating the stable tag are now closed.
Plugin Check “Bucket B” output-escaping sweep (317 sites across 28 files): every echo and <?= ?> site that the WordPress.org reviewer ruleset flagged as WordPress.Security.EscapeOutput.OutputNotEscaped now uses a context-appropriate escaper. esc_html for text content between tags, esc_attr for HTML attribute values, esc_url for URLs, (int) cast for numeric IDs, wp_kses_post for already-built HTML fragments, esc_textarea for textarea content, and esc_xml-equivalent (esc_html plus CDATA wrapping where appropriate) for XML output in the WXR exporter and the iTunes podcast feed. Where wp_kses_post would strip needed markup (audio/video player iframes, Uncode theme integration), per-line phpcs:ignore annotations carry the rationale rather than weakening the sniff. The WXR exporter also picks up wxr_cdata as a registered custom-auto-escaped function in the project’s PHPCS config.
Pre-3.0 small fixes pulled forward from the pre-submission audit:
- Fixed a runtime PHP 8.0+ warning (
foreach() argument must be of type array|object, string given) insm-core-functions.php:663. Theapply_filters( 'sermon-images-get-the-terms', '', ... )default value was an empty string; foreach over a string fails on PHP 8.0+. Default coerced toarray()with a belt-and-braces(array)cast on the result. - Added the
defined( 'ABSPATH' ) || exit;guard toincludes/class-sm-roles.php(missed in the rc4 sweep). - Fixed two PHP 8.2 deprecation warnings:
"[${time}]"->"[{$time}]"in the Sermon Browser and Sermon Manager importers. Plugin floor stays at PHP 8.1 where this isn’t deprecated, but WordPress.org test environments cover 8.2 and 8.3. - Bug fix in the recent-sermons widget admin form: textarea contents for
before_widget/after_widgetwere being echoed as kses-stripped HTML, which renders as visible literal text in a textarea. Nowesc_textarea, which entity-encodes for the textarea context. Round-trip edit workflow now matches what the user typed at save.
3.0-rc4
WordPress.org Plugin Check sweep, “Bucket A” mechanical fixes (~70 sites across 10 commits):
- Plugin header: added
License: GPLv2andLicense URIlines for WP.org guideline compliance. - Direct file access protection: added
defined( 'ABSPATH' ) or die;guards to 11 view templates (views/*.php). - Replaced
date()withgmdate()(12 sites) orwp_date()(2 user-facing admin column sites) in 9 files. PHPdate()is affected bydate_default_timezone_set()and unsafe inside WordPress. Incidentally corrects a latent bug in the RSS feed (pubDateandlastBuildDatepreviously claimed+0000UTC while passing server-local timestamps). - Replaced
parse_url()withwp_parse_url()(8 sites). WP wrapper suppresses warnings on malformed URLs. - Replaced
strip_tags()withwp_strip_all_tags()(7 sites). WP wrapper additionally strips script/style tag contents. - Replaced
@unlink()withwp_delete_file()(6 sites in the WXR importer). WP wrapper respects thewp_delete_filefilter. - Replaced
rand()withwp_rand()(1 site). WP wrapper produces better random numbers. - i18n: added the
'sermon-works'text-domain argument to 10__()/esc_html__()calls that previously omitted it (Plugin CheckMissingArgDomain). - i18n: corrected 9 calls in the WXR importer that used
'wordpress-importer'instead of'sermon-works'as the text-domain (Plugin CheckTextDomainMismatch). - i18n: added
/* translators: */comments above 3 placeholder strings (Plugin CheckMissingTranslatorsComment).
Tier 2 substantive Plugin Check items (file system operations, prepared SQL audits, enqueued scripts, output escaping) are deferred to a future release; see .restoration/plugin-check-summary.md for the full triage.
3.0-rc3
Bug fix for installs on case-sensitive filesystems (Linux hosts including most production WordPress hosting):
- Rename bundled
includes/vendor/CMB2/includes/CMB2_hookup.phptoCMB2_Hookup.phpso CMB2’s class autoloader can find the file. Without this, activating Sermon Works on a Linux host produced a fatal “class CMB2_Hookup not found” error. The casing inconsistency was inherited from the upstream CMB2 v2.11.0 vendor bundle and only manifested on case-sensitive filesystems; Windows and macOS users would not have noticed.
3.0-rc2
Salvaged bug-fix PRs from the upstream open-PR backlog, ingested with original authors preserved as git commit authors:
- Fix shortcode pagination on static front page (upstream PR #274 by @brianfreytag).
- Defensive guard around the import-message cleanup loop in
sermons.php(upstream PR #292 by @tstephen). Prevents a PHP 8.x fatal when_sm_import_se_messages/_sm_import_sb_messagesoptions are non-array. - Add French Bible versions (Louis Segond 1910, Segond 21) to the verse-popup settings dropdown (upstream PR #264 by @rjorel).
3.0-rc1: Sermon Works restoration
This release renames the plugin from Sermon Manager to Sermon Works (text domain sermon-works) and ships the in-place restoration completed across early 2026:
- Security: 25 issues resolved from a focused audit, including three CVEs filed against the upstream Sermon Manager codebase: CVE-2025-12368 (stored XSS in
[sermon-views]), CVE-2025-63002 (unauthenticated missing authorisation), and CVE-2025-63000 (stored XSS in[list_sermons]/[sermon_images]). All three sinks have been removed or hardened in Sermon Works. - Modernised: PHP 8.1+ and WordPress 6.0+ floor; deprecated WordPress function calls replaced with current equivalents; dead PHP 5.3 compatibility paths and stale upstream marketing links removed.
- Bundled vendor cleanup: CMB2 upgraded v2.2.3.1 v2.11.0; wp-background-processing upgraded 1.0.1 1.4.0; bundled
entry-views.phppolyfill removed (replaced with a small WordPress-native counter);taxonomy-imageslibrary removed (migrated to core term_meta + a dedicated metabox). - Database, shortcodes, post types, taxonomies, and template files unchanged. Existing Sermon Manager installs migrate as a drop-in replacement.
Older releases
For Sermon Manager release history (2.13 through 2.15.16, dating from 2015–2018), see changelog.txt in the plugin directory.
