-
Notifications
You must be signed in to change notification settings - Fork 9
What's New v10.3
Released May 1, 2026 — Schema.org structured data, Setup Wizard, REST API with full CRUD, multi-campus access controls, expanded debug mode, and a wave of save-path fixes.
10.3.1 (May 1, 2026) — same-day hotfix. The standalone
com_proclaim-10.3.0.zipleft admins on a fatal "Class CWM\Library\Scripture\Helper\ScriptureHelper not found" whenlib_cwmscripturewasn't pre-installed, and even installing viapkg_proclaim-10.3.0.ziphit the same error because the runtime PSR-4 autoloader was initialised before the just-installed library's namespace was registered. 10.3.1 fixes the autoloader race inproclaim.script.phppreflight (manually registers the library namespace if its files are on disk) and falls back to a clear error message instead of a fatal when the library is genuinely missing. Also:composer releasenow shipspkg_proclaim-VERSION.zipalongside the standalone, and the release script no longer trips ontag.gpgsign = true. Usepkg_proclaim-10.3.1.zip.
⚠️ Fresh installs: use 10.3.3 or newer. A clean install (a site with no prior Proclaim) is broken on every shipped 10.3.0–10.3.2 package — preflight looked for the scripture library at the wrong path and postflightrequire_once'd a file that had moved intolib_cwmscripture, aborting the install (#1306). Existing sites upgrading were unaffected. 10.3.3 fixes it (#1304) — always start new sites frompkg_proclaim-10.3.3.zipor later.
Stranded standalone installs now auto-update. Churches still running the old standalone
com_proclaimcomponent (installed before thepkg_proclaimpackage existed) previously saw "no updates" in Extensions → Update and were stuck on an old version. Proclaim's download server now advertises the update to those installs too, so they upgrade to the current package with one click — no manual re-install or migration steps. Applying it moves the site onto the package and runs the usual schema migrations. See ARS Migration Plugin for the details.
🔌 The REST API works from 10.3.6 — not 10.3.4, as originally stated here. Every Proclaim API endpoint returned 404 on every install from 10.3.0 onwards. Three faults had to be fixed, and 10.3.4 only fixed two of them: the webservices plugin was never registered during installation (#1309) and the API classes never reached the location Joomla loads them from (#1310). The third went unnoticed — the
api_accesssetting that switched the API on had no interface and could not be set (#1328), so the API stayed off with no supported way to enable it. It was missed because testing set that value directly in the database instead of through the admin screens.10.3.6 resolves it by removing that setting entirely: the API is switched on and off by enabling or disabling the Web Services - Proclaim plugin, where a Joomla administrator would look first. A single plugin option controls whether reads need a token, and it defaults to requiring one. See REST API.
If you tried the API on 10.3.4 or 10.3.5 and got nothing but 404s, that was why.
For the previous release, see What's New v10.2.
Sermons, teachers, and series now emit JSON-LD on the frontend so search engines and aggregators can index them as first-class entities. An admin Schema tab on each edit form auto-fills from item data, lets you customize per-record overrides, and falls back gracefully when fields are blank. A site-wide Reset Schema action regenerates the cached schema row from current data when teachers/series/etc. change.
A guided first-run experience replaces the cold-start "find every setting" problem. Pick a style (Simple Service, Full Media Ministry, or Multi-Campus), answer five short steps about your ministry, and the wizard applies a tailored configuration preset — frontend layout, podcast defaults, media options, and access rules.
Sermons, teachers, series, media files, and podcasts are exposed via Joomla's webservices API with full GET/POST/PATCH/DELETE coverage. Three access tiers controlled in admin settings: disabled (403 everything), public read-only, or API-key required (Joomla user API tokens). Designed to enable custom church-management integrations without writing PHP.
⚠️ This did not actually work until 10.3.4. Two packaging defects meant every endpoint returned 404 on every install — see the 10.3.4 note at the top of this page. If you tried the API on 10.3.0–10.3.3 and gave up, it was not your configuration.
With the API reachable for the first time, it grew from 5 resources to 12 — adding topics, locations, study types, playlists, comments, servers and templates alongside the original sermons, teachers, series, podcasts and media files.
Not everything accepts writes, deliberately. Servers, templates, comments and playlists are read-only, each for a specific reason: server records hold media-platform credentials, templates are the markup your visitors see, comments would bypass moderation, and playlist sync settings can push changes to a live YouTube account. A write to one returns 404 — the route does not exist.
What the API will never hand out:
- Server credentials. API keys, client secrets and access tokens are withheld from every response, including to a Super User token.
- Commenter email addresses. Never returned, along with the account ID that would link a comment to a site user.
- Anything above the caller's view level. Every list is filtered to the access levels that caller is entitled to, exactly as on the site — a public read cannot surface restricted content. Two entities that had never needed this filter (locations and playlists) gained it before being exposed.
Every change is now recorded. Creates, updates and deletes made through the API appear in Users > Action Logs tagged (via API), using the same messages as the admin interface — so an audit shows both side by side rather than in separate places. Previously an API change left no trace while the identical edit through the interface did.
Switching it on (10.3.6): enable the Web Services - Proclaim plugin. There is no separate Proclaim setting — the earlier api_access option is gone, since its off state simply duplicated the plugin's own.
See REST API for endpoints, field lists and setup — including the two separate permissions that both default to Super Users and are the usual reason a valid token still returns 401.
Content can be filtered by campus location with a view-level security check, so members at one campus see their own content even when teachers, sermons, or series live in a shared catalog. Pairs with the Setup Wizard's Multi-Campus style preset.
The legacy fixed link slots (Facebook, Twitter, blog, link1–3) gave way to a flexible subform supporting 42 platform types with FA6 brand icons — including church-specific platforms (Subsplash, Church Center, Faithlife) and audio/video destinations (Spotify, Apple Podcasts, Amazon Music). Auto-prepends https:// where missing; preserves legacy data and stays backward-compatible on the frontend.
Teacher phone numbers now use the intl-tel-input library: country picker with flags, auto-formatting as you type, validation, and dark-mode skin matching Atum.
The Layout Editor tab on Template forms loads via AJAX after first paint instead of upfront, cutting initial template-edit page load substantially. Plays well with the existing schema-driven settings, multi-context support (messages/teachers/series/etc.), and dynamic options.
A single Joomla package now bundles lib_cwmscripture (the scripture library), plg_content_scripturelinks, and com_proclaim. Drop one zip into Joomla → Install Extensions and everything wires up in the right order.
Playlists become first-class Proclaim entities that stay in sync with your video platform, so the sermons you already manage line up with the playlists viewers actually browse.
- Bulk import + reconcile. One action pulls every playlist from a YouTube channel (or Vimeo Showcase) and creates a Proclaim Playlist for each. Their videos are matched against media you already have — by video ID extracted from the stored URL — so existing studies are linked instead of duplicated.
-
Scheduled re-sync with a conflict gate. A
proclaim.playlistsynctask refreshes already-imported playlists on a schedule (it never silently creates new ones). Neither side clobbers the other: a remote title change is applied only when you haven't edited the playlist locally since the last sync; if both diverged, your local value is kept and the divergence is reported. - Browse Playlists picker. A modal lists the channel's playlists and auto-fills the title when linking a playlist by hand (the edge case — import is the primary path).
-
Platform-neutral. A small three-method capability contract (
supportsPlaylists+ list/extract) means the engine never hardcodes "YouTube." YouTube and Vimeo (via Showcases //me/albums) both opt in; new platforms join by implementing the contract. -
OAuth write-back (bidirectional). When a playlist is opted in to write-back, Proclaim becomes authoritative: a title or description you edit locally is pushed back to the platform (completing the conflict gate instead of just logging it), and — if a Series is linked — every published video in that series is ensured a member of the playlist via the platform's write API (YouTube
playlistItems.insert). This closes the common gap where an uploaded sermon never makes it into its default playlist. All write-back is off by default, OAuth-gated, quota-checked, and supports a dry-run "Preview" before any change is pushed. - Assign playlists per media file. Each media file gains a searchable "Choose Playlist(s)" multi-select — exactly like the Podcast field — so a video can belong to several playlists, picked from those on its server. For a new media file the field is auto-filled from the linked Message's Series, so uploads land in the right playlist without extra clicks. Assignments feed the same write-back path: an assigned video is added to the playlist on the platform on the next sync.
- Optional two-way removal. A new setting, "Remove videos from remote playlists," makes removing a playlist from a media file also remove the video from that playlist on the platform (e.g. YouTube). It's off by default — leave it off and de-selecting only drops the local assignment; turn it on to keep both sides fully in sync.
- AI writing voice options for study text generation.
- Bible Brain (DBP4) provider for text and audio retrieval.
- Study text generation improvements.
The #__assets row maintenance for Proclaim content has been rebuilt around the inherit-from-parent model. New behavior:
- Stops creating empty-rules per-record asset rows on save (was accumulating thousands of empty rows that slowed
Access::preload('com_proclaim')). -
stripEmptyAssetRowis called after every Proclaim Table store and removes any default-rules row Joomla auto-created. - Component-level and per-record Proclaim ACL rules now back up and restore via the existing backup workflow.
- The Assets admin tool was reworked for the new model and runs in batches.
The analytics Quick Stats modal content was too tight against the edges. Added proper padding to the modal body and increased spacing between KPI cards and the media files table.
Batch "Move to Position" for teachers caused random shuffling when multiple teachers shared the same ordering value (e.g., all at 0). Added a teachername tiebreaker to the sort query for deterministic ordering. Also fixed the ordering property type from string to int in CwmteacherTable.
The series list controller was reading the wrong POST field ('ordering' instead of 'order') for AJAX ordering saves. Drag-and-drop reordering was silently broken — it appeared to work but never saved. Fixed by removing the redundant saveOrderAjax override (along with messages, locations, and teachers) so all four controllers now use Joomla's core implementation, which also adds CSRF validation that was previously missing.
PHPUnit tests could not find the Joomla CMS framework because the bootstrap only checked builder.joomla_dir (empty). It now falls back to builder.joomla_paths (the actively used config property), restoring test functionality.
- Updated
BibleProviderFactoryTestto include thebiblebrainprovider added in 10.2 - Updated
sermon-filtersJS test to match current error behavior (inline error with retry button, not native form submit fallback)
Added brace-expansion override to resolve 20 moderate vulnerabilities in Jest's transitive dependencies (dev-only, never shipped to production).
Saving any Proclaim record (teacher, message, series, location, mediafile, server, podcast, template…) crashed with Call to protected method Joomla\CMS\Table\Table::getDatabase() after the row had already been written. Cwmassets::stripEmptyAssetRow was reaching into a method that became protected in Joomla 5+. Switched to Factory::getContainer()->get(DatabaseInterface::class). The fatal masked downstream save logic (e.g. teacher social links appeared to drop rows because the response died before completing).
Editing a teacher showed the Biography tab with no TinyMCE editors visible. The lazy-load that fetched editor markup via AJAX never had a chance to initialize because Joomla only loads the plg_editors_tinymce JS and plg_editor_tinymce script options when an editor field renders server-side — and the initial page render had no editor at all. Reverted to direct render of the short and information fields.
The migration that added the social_links TEXT column on #__bsms_teachers was overwritten in March 2026 by a migration-cleanup commit. Sites whose schema bump ran after that commit never got the column, so saving multiple social links wrote nothing to the JSON column and only the first Facebook URL persisted via the legacy facebooklink mapping ("only one is saving"). Added social_links to the requiredFixes map in the install script — ensureSchemaReady() repairs the column on the next preflight.
Saving a new message left the schema's author field empty until the user clicked Reset Schema. Cause: the schemaorg system plugin fires onContentAfterSave inside parent::save(), but CwmmessageModel::saveTeachers() runs after, so the junction table was empty when the auto-schema queried it. Added CwmschemaorgHelper::ensureSermonAuthor() and call it after saveTeachers() writes the junction. Only fills author when missing, so a user-customized value entered on the Schema tab persists across saves.
The form-load auto-fill for a teacher's schema didn't include the worksFor (organization) block that the save-time builder and Reset-Schema path both have. With the field blank on load, the form posted back an empty worksFor subform, and the save-time preserve-complex-fields loop overrode the auto-derived value with the empty submission. Mirrored the worksFor block into populateTeacher so the field pre-fills from teacher org_name (with admin-setting and site-name fallbacks).
composer release died at step 5/7 (fatal: no tag message?) on systems with tag.gpgsign = true. The script used git tag -f (lightweight), which under signing policy is silently converted to annotated and prompts $EDITOR for a message — saving an empty buffer fails. Switched to git tag -af "$TAG" -m "$TAG" so signed tags work without an editor prompt.
Extensions → Manage → Database perpetually reported the two playlist tables as "Table <prefix>_bsms_playlists( does not exist" — note the stray trailing ( — and clicking Fix never cleared it. Joomla's schema checker strips newlines with no replacement space when parsing update SQL, so a CREATE TABLE with its opening ( on the next line glued the table name to the paren, producing a check query that could never match. Moved the ( onto the CREATE TABLE line (the convention every other update file follows) for #__bsms_playlists and #__bsms_playlist_items. Formatting-only — the DDL executes identically; only the schema-diff parser was affected.
YouTube video titles in the picker cards rendered with literal HTML entities — e.g. The Investigative Judgment*'*s Assurance and *Present Truth Series - **"*The Investigative Judgement… — instead of the intended ' and ". The YouTube Data API returns snippet titles and descriptions already HTML-encoded, and the picker JS escaped them a second time, so ' became &#39; and displayed as raw text. Fixed by decoding entities once at the API boundary (a new decodeApiText() helper in CWMAddonYoutube.php) across all six snippet mappings — channel videos, search, playlists, playlist videos, live videos, and channel info. The JS escaping (the XSS guard) stays intact and now escapes exactly once. The same decode was applied to the import-to-message path, which had been storing the encoded title (') directly into the message title column in the database.
The JBSMDEBUG debug system has been significantly expanded with a new centralized CwmDebug helper class.
Two output modes:
-
log()/startTimer()/stopTimer()— Timing and diagnostics, only active when debug is enabled. Zero overhead when off. -
error()— Always logs tocom_proclaim.errors.php, capturing exceptions from previously silent catch blocks.
Timing instrumentation added to:
- AJAX sermon filters (total request, DB query, template rendering)
- Admin dashboard stats (cache hit/miss detection)
- Scripture passage rendering (provider selection, fallback chain)
- Frontend listing rendering (type, item count, elapsed time)
Error logging added to 20 silent catch blocks:
- Schema.org plugin (13 silent
\Throwablecatches) - Schema.org helper (2 catches)
- Message model schema generation (5 catches)
- MIME type detection and download failures
Output destinations:
- Dedicated
com_proclaim.debug.phplog file (only created when debug is on) - On-screen messages for super admins via Joomla message queue
-
_debugkey in AJAX JSON responses when debug is enabled
- AI writing voice options for study text generation
- Bible Brain (DBP4) provider for text and audio retrieval
- Study text improvements
Routine dependency housekeeping with no user-facing behavior change:
-
intl-tel-inputupgraded v28 → v29. The international phone input library moved its distribution frombuild/todist/and renamed several CSS classes and variables. Migratedphone-input.es6.jsto the v29 API (including switching validation toisValidNumberPrecise()for the new semantics) and updatedphone-input.cssfor the renamed selectors, the removed--iti-dialcode-colorvariable, and the dark-mode (prefers-color-scheme) fallback. -
Removed unused runtime dependencies
php-diffandphar-stream-wrapper— neither was referenced anywhere in the codebase. -
phanstatic analyzer upgraded v5 → v6 (dev-only). -
Patch/minor bumps to
build-tools,php-cs-fixer,phpunit, androave/security-advisories.
Proclaim now records admin activity in Joomla's core User Actions Log (com_actionlogs), giving multi-user ministries an audit trail of who changed what.
- Every content entity is covered — sermons, teachers, series, topics, locations, comments, playlists, media files, message types, template codes, templates, servers, and podcasts.
- All the actions that matter — item added / updated (save path), deleted, and publish-state changes (publish, unpublish, archive, trash).
- Only real changes are logged. Each delete and state change is verified against the database after the action, so a blocked delete (permission or foreign-key), or re-publishing an item that was already published, writes nothing to the log.
-
One click from the control panel. A User Actions Log card on the Proclaim dashboard opens the log pre-filtered to Proclaim (shown only when
com_actionlogsis enabled). - No extra toggle. Proclaim registers as a standard loggable extension, so enable/disable lives in the core User Actions Log options alongside every other component — nothing new to learn.
Podcast directories (Apple, Spotify, etc.) expose no download-analytics API, and a feed's <enclosure> points straight at the media file — so podcast downloads were invisible to Proclaim. This adds the same tracking-redirect technique the major podcast hosts use.
- Counts real downloads. Each episode's enclosure is routed through a Proclaim redirect that records the download — deduplicated per listener per 24 hours (IAB-style), with bots excluded — then sends the app on to the media file. It's counted regardless of which app or directory the listener uses, and the total shows on the Analytics dashboard.
- Works with external hosting. The redirect sends the listener to wherever the media actually lives — this server or an external host/CDN (the common case given storage limits).
- On by default, and safe. Enabled for every podcast out of the box. Episode identity is now pinned to a permanent, frozen GUID rather than the media URL, so routing through the redirect never changes an item's identity — existing subscribers are unaffected and nothing re-downloads. A per-podcast switch lets you opt out (e.g. if you already run a prefix like Podtrac or Blubrry).
- Never blocks playback. Counting is best-effort; if it ever fails, the redirect still happens.
Investigated and confirmed this is a functional feature, not dead code. The format_popular admin setting controls how message popularity scores are calculated (combinations of hits, plays, downloads, and platform stats). Used on the admin dashboard and frontend popular messages dropdown. Closed with documentation.
Need help with your site? Proclaim Support — the place to start for anything to do with your own install · Ask on GitHub
Something wrong with Proclaim itself? Report it on GitHub — bugs and code issues are tracked there, in the open.
More — Proclaim documentation · Helpful videos · Latest release · Christian Web Ministries
Security issues privately to info@christianwebministries.org, not a public tracker. When asking for help, say which Proclaim and Joomla versions you are on.
- Publish Your First Message
- Show Proclaim on Your Site
- Add Audio and Video
- Organise Your Messages
- Set Up Podcasting
- Control How Proclaim Looks
- Import and Migrate
- Maintain Your Site
- Multi-Campus-Admin-Guide
- Multi-Campus-User-Guide
- Template-Customization-Guide
- Vimeo-API-Setup
- Print-Friendly-View
- Content-Security-Policy
- Troubleshooting-FAQ
- Setting-up-your-development-environment
- Standards and Conventions
- Contributing-Workflow
- REST API
- Database-Schema
- Location-API-Reference
- Backward-Compatibility-Breaks-10.1
- ARS Migration Plugin
- Proclaim-Code-Road-map
- Tasks
- Overview
- Admin Center
- Messages
- Media Files
- Servers
- Teachers
- Series
- Podcasts
- Topics
- Locations
- Comments
- Message Types
- Playlists
- Templates
- Utilities