Saint Paul's 1928 BCP Calendar
1928 BCP Calendar Standalone WordPress plugin scaffold for a lightweight 1928 Book of Common Prayer liturgical calendar.
by Steve Macias · github.com/stevemacias/ordo_kalendar · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/stevemacias/ordo_kalendar/archive/refs/heads/main.zipReadme
Saint Paul's 1928 BCP Calendar
Standalone WordPress plugin scaffold for a lightweight 1928 Book of Common Prayer liturgical calendar.
Version 0.5.3 — What's New
May–July 2026 content batch — 32 canonical feast pages are now live (up from 17). All content uses 1928 BCP propers only.
New and completed movable feast pages:
- Fourth Sunday after Easter (Easter +28, May 3, 2026) — new entry; Collect "O Almighty God, who alone canst order the unruly wills"; James 1:17; John 16:5.
- Fifth Sunday after Easter (Easter +35, May 10) — completed stub; Collect "O Lord, from whom all good things do come"; James 1:22; John 16:23.
- Sunday after Ascension Day (Easter +42, May 17) — completed stub; Collect "O God, the King of glory"; 1 Peter 4:7; John 15:26.
- Monday in Whitsun Week (Easter +50, May 25) — completed stub; Acts 10:34; John 3:16.
- Tuesday in Whitsun Week (Easter +51, May 26) — completed stub; Acts 8:14; John 10:1.
- First through Eighth Sundays after Trinity (Easter +63 through +112, June 7–July 26) — nine new entries with full 1928 BCP Collects, Epistle and Gospel references, 3-paragraph theological notes, and three FAQs each.
New and completed fixed feast pages:
- Saint Philip and Saint James (May 1) — James 1:1; John 14:1; Collect "O Almighty God, whom truly to know is everlasting life."
- Saint Barnabas (June 11) — Acts 11:22; John 15:12; Collect "O Lord God Almighty, who didst endue thy holy Apostle Barnabas."
- Nativity of Saint John Baptist (June 24) — Isaiah 40:1; Luke 1:57; Collect "Almighty God, by whose providence thy servant John Baptist was wonderfully born."
- Saint Peter (June 29) — Acts 12:1; Matthew 16:13; Collect "O Almighty God, who by thy Son Jesus Christ didst give to thy Apostle Saint Peter."
- Saint James (July 25) — Acts 11:27; Matthew 20:20; Collect "Grant, O merciful God, that as thine holy Apostle Saint James."
Sitemap expanded — get_content_day_dates() in SPBCP_Calendar_Sitemaps updated to include all new movable feast offsets (+28, +63 through +112) and all five new fixed-feast dates (May 1, June 11, June 24, June 29, July 25).
Version 0.5.2 — What's New
- Fatal-error fix:
render_season()—DateTimeImmutable::createFromFormat()was chained directly with->format()without a null check. If the date object was unexpectedlyfalsethis would have caused a fatal error. The return value is now checked withinstanceof DateTimeImmutablebefore formatting. - SEO: invalid feast and season slugs now 404 — Previously
/feast/anything/and/season/anything/returned HTTP 200 with placeholder content, which Google would index as thin pages.maybe_404_invalid_calendar_request()now validates feast and season slugs against the data layer and issues a proper 404 for any unrecognised slug. - Require order corrected —
class-spbcp-calendar-propers.phpis now loaded beforeclass-spbcp-calendar-data.phpin the main plugin bootstrap, matching the dependency relationship (the data class calls the propers class). - Sitemap performance —
SPBCP_Calendar_Sitemaps::get_url_entries()now caches its result in a static variable. WordPress core calls bothget_max_num_pages()andget_url_list()per sitemap request, which previously triggered two full URL-list computations; now it computes once. - Developer tool hardening —
tools/extract-propers-1928.phpnow sends HTTP 403 when accessed from a browser (matching the existing behaviour oftools/validate-calendar-data.php). - Production deployment documentation — README now includes an Installation section, pre-release validator workflow, AIOSEO integration notes, developer tool access notes, supported year range explanation, and invalid-route SEO safety summary.
- QA checklist expanded — TESTING.md rewritten as a 13-section checklist covering activation, valid/invalid routes, SEO titles, meta descriptions, canonical URLs, JSON-LD, sitemaps, content rendering, security, plugin compatibility, and CLI validation.
Version 0.5.1 — What's New
- SEO titles for all route types — Feast, season, day, and month pages now each produce a unique, correctly-formatted
<title>tag. Season pages use "Anglican Liturgical Calendar (1928 BCP)"; day pages include the feast name and date; month pages include the month and year. - Meta descriptions — Every plugin-generated route now outputs a distinct 130–155 character
<meta name="description">tag derived from the page's feast, season, date, or month. - Canonical links for day and month pages — In addition to existing feast and season canonicals,
/1928-bcp-calendar/{year}/{month}/{day}/and/1928-bcp-calendar/{year}/{month}/routes now each emit a<link rel="canonical">pointing to their exact URL. - All in One SEO integration hardened — When AIOSEO is active the plugin no longer outputs canonical or description tags directly. Instead it injects values through
aioseo_title,aioseo_description, andaioseo_canonical_urlfilters so AIOSEO's own output carries the correct data without duplication. Apre_get_document_titlehook at priority 20 overrides AIOSEO's title on plugin pages. - Single SEO context method — All five SEO hooks (
filter_document_title_parts,filter_pre_get_document_title,render_canonical,render_meta_description, AIOSEO filters) share oneget_seo_context()call cached statically per request; no duplicate data-layer lookups.
Version 0.5.0 — What's New
- Completed Holy Week feasts — Palm Sunday, Maundy Thursday, Good Friday, and Easter Even are now marked
complete => truewith full theological notes and three FAQs each; all four are live canonical feast pages included in the sitemap. - Circumcision of Christ corrected — The theological note, which had been accidentally overwritten with Epiphany content, has been replaced with the correct note covering the eighth-day circumcision, the Epistle from Philippians 2, and the Gospel from Luke 2.
- Easter Week octave pages — Monday in Easter Week and Tuesday in Easter Week are now marked
public => trueandcomplete => truewith full 3-paragraph theological notes and three FAQs each (Acts 10:34 + Luke 24:13 Emmaus; Acts 13:26 + Luke 24:36 upper-room appearance).
Version 0.4.0 — What's New
completeflag — Feast definitions now require both'public' => trueAND'complete' => truebefore a canonical feast page is published or included in the sitemap. Entries with onlypublic => trueare treated as staging intent and are excluded from public routing until marked complete.- Renderer safeguards — Day-detail entries with no collect, epistle, or gospel no longer render empty liturgical content sections. Incomplete entries appear by title and date only.
- Validator hardened — New checks warn when
public=truebutcompleteis absent or false; warn for any calendar entry that appears on the grid with no propers data; and FAIL only when a declared-complete public feast is missing required fields.
Version 0.3.0 — What's New
- Standardised internal linking — Feast pages show a clickable next-occurrence date link; day-detail pages show prev/next navigation with actual dates as anchor text; season pages show a current-month link; feast-link anchor text uses the feast's own title throughout.
Version 0.2.0 — What's New
- Season hub pages at clean URLs (
/1928-bcp-calendar/season/{slug}/) for all six liturgical seasons (Advent, Christmas, Epiphany, Lent, Eastertide, Trinity). - Theological notes — 150–300 word original notes for seven major feasts: Easter Day, Ascension Day, Whitsunday, Trinity Sunday, Christmas Day, Epiphany, All Saints' Day.
- FAQ blocks — Three short FAQs per major feast, stored in the data layer, rendered as semantic HTML, with FAQPage JSON-LD on supporting feast pages.
- Internal linking — Feast pages link to their season and related season-mates; season pages list their feasts; day-detail pages show a season link and prev/next day navigation bounded to the supported year range.
- Public flag — Feast definitions now carry
'public' => trueto mark entries that have complete enough content to be canonical pages. Sitemaps and feast-page routing respect this flag. Incomplete entries appear in month views but do not link to feast pages. - Validator warnings — The validator emits non-failing
WARNlines for non-public feasts with partial data, reserving hardFAILfor public feasts with missing required fields.
Current Scope
- Plugin slug:
spbcp-calendar - Shortcode:
[spbcp_calendar] - Optional test attributes:
[spbcp_calendar year="2026" month="5"] - Clean month URLs:
/1928-bcp-calendar/2026/05/ - Clean day URLs:
/1928-bcp-calendar/2026/05/14/ - Canonical feast URLs:
/1928-bcp-calendar/feast/easter-day/ - Season hub URLs:
/1928-bcp-calendar/season/easter/ - Supported calendar route range: 2025 through 2028
- Invalid dates and out-of-range URLs return the active theme's 404 response
- XML sitemap entries for public canonical feast pages, season pages, supported month pages, and populated day pages
- JSON-LD structured data including
AboutPage,Event,BreadcrumbList, andFAQPage - No React, no Blocksy theme edits, no The Events Calendar integration
TODO — Remaining 1928 BCP Propers
The following feasts and Sundays are defined in the data files but not yet marked 'public' => true. They need full collects, epistle references, and gospel references before they are ready to publish as canonical pages.
Fixed Feasts (not yet public)
- Purification of the BVM (February 2)
- Annunciation of the BVM (March 25)
- St. Philip and St. James (May 1)
- St. Barnabas (June 11)
- St. John Baptist (June 24)
- St. Peter (June 29)
- St. James (July 25)
- St. Bartholomew (August 24)
- St. Matthew (September 21)
- St. Michael and All Angels (September 29)
- St. Luke (October 18)
- St. Simon and St. Jude (October 28)
- St. Andrew (November 30)
- St. Thomas (December 21)
- St. Stephen (December 26)
- St. John Evangelist (December 27)
- Holy Innocents (December 28)
Movable Feasts (not yet public)
All Holy Week feasts (Palm Sunday, Maundy Thursday, Good Friday, Easter Even) and Easter Week octave days (Monday and Tuesday in Easter Week) are now complete and public.
Sundays of the Year (not yet in data)
All 27 Sundays after Trinity, all 4 Sundays in Advent, all Sundays after Epiphany, Septuagesima, Sexagesima, Quinquagesima, the five Sundays in Lent (including Passion Sunday and Palm Sunday), and Easter Sunday through the Sunday after Ascension are not yet added as recurring entries.
These require the full Easter computus (already implemented in SPBCP_Calendar_Data::get_easter_for_year()) and offset-based date computation per the existing movable feast pattern.
Adding Future Feasts and Sundays Safely
The plugin uses a two-flag gate to prevent incomplete entries from accidentally becoming public canonical pages. Follow these rules when adding new feast or Sunday entries.
Flag meanings
public |
complete |
Result |
|---|---|---|
| absent / false | absent / false | Entry appears in the calendar grid only. No feast page, no sitemap URL. |
true |
absent / false | Staging intent declared. Still no feast page or sitemap URL. Validator emits a WARN. |
true |
true |
Full canonical feast page published. Included in sitemap. Validator fails if required fields are missing. |
Step-by-step process for a new feast or Sunday
-
Add the stub. In
fixed-feasts.phpormovable-feasts.php, add a minimal entry withslug,title,type,rank,liturgical_color, and eithermonth/day(fixed) oroffset(movable). No flags yet.'second-sunday-after-epiphany' => array( 'slug' => 'second-sunday-after-epiphany', 'title' => 'Second Sunday after Epiphany', 'type' => 'sunday', 'rank' => 'Sunday', 'liturgical_color' => 'green', 'offset' => 14, // Easter − 35 = approximate; recalculate per BCP table ),The entry will appear by title in month and day views. No feast page will be generated. No empty content sections will render.
-
Add propers. Once the Collect, Epistle reference, and Gospel reference are ready, add them directly to the definition or via a
proper_keyentry inincludes/data/propers-1928.php. Add atheological_note(150–300 words, multi-paragraph using\n\n) and at least threefaqsentries. -
Mark as staging. Set
'public' => trueon the definition. The feast page still will not publish (thecompletegate blocks it), but the validator will now warn you that the feast is queued for publication. -
Run the validator.
php tools/validate-calendar-data.phpFix any
FAILlines. ReviewWARNlines. The validator will confirm whether all required fields (collect, epistle_reference, gospel_reference) are present. -
Mark as complete. Once the validator passes cleanly, set
'complete' => true. The canonical feast page will now be live, the URL will appear in the sitemap, and the feast will appear in related-feasts lists on season pages. -
Rebuild and deploy.
zip -r spbcp-calendar.zip spbcp-calendar/ --exclude "*.DS_Store"