Add LXX2012+WEB Bible translation with UI/API selection - #156
Merged
Conversation
Both texts are public domain and already in USFX format, so no new parser is needed. Adds a translation field to Verse (existing rows backfilled to kjv/rccv/srp1865 per language) and loads the new pairing via a data migration, matching the existing migration-based ingestion mechanism used for KJV/Romanian/Serbian. Also fixes two parse.py/model bugs surfaced by this data: - USFX verse bridges (e.g. id="1-2") crashed the integer verse field; now stored under the first verse number. - A footnote's closing tag unconditionally set is_valid_content=True, corrupting the previous verse's content when a footnote appeared inside a Psalm title (<d>) block, which precedes the first <v> of the chapter.
Wires up the translation field added in the previous commit: a <select> dropdown on the readings page (English only, since Romanian and Serbian each still have exactly one translation), a matching /readings/<tradition>/<cal>/<translation>/... URL segment remembered in session like the existing cal/tradition axes, and an optional ?translation= query parameter on the four Day-returning API endpoints (kept as a query param rather than a new required path segment, to avoid doubling the already-large tradition route matrix). Also fixes the readings page's "Scripture Readings (KJV)" heading, previously hardcoded regardless of language, to reflect whichever translation is actually being displayed.
… label Moves the dropdown out of the cal/tradition nav block and into the Scripture Readings section it actually controls, gives it page-matching styling instead of default browser chrome, and shortens the LXX2012+WEB label so the heading no longer nests parens inside parens.
The select box already indicates the chosen translation for English readers, so the parenthetical is only shown for Romanian/Serbian, which have no dropdown. Also bumps the picker's text/select size and darkens its color slightly for better legibility.
WEB annotates verses with <x> cross-reference elements (e.g. pointing Heb 11:33 back to Daniel 6:22-23) that aren't part of the verse text. parse.py already suppressed <f> footnote content the same way; <x> was missed, so its text (e.g. "11:33 Daniel 6:22-23") was leaking directly into the stored verse content. KJV/Romanian/Serbian never use <x>, so this only affected the new lxx2012-web data -- reloaded via migration 0004 (rolled back to 0003 and reapplied) to pick up the fix.
These two OCA-specific saints aren't in antiochian.org's own commemoration list for these dates (confirmed via data/antiochian_fixed_saints.json), so their readings were leaking into the Greek view alongside the correct Greek-specific reading (Thomas the Apostle / James, son of Alphaeus), which shared the same Reading.ordering value by coincidence. Note: this was originally a 12-date, 23-row fix, but 10 of those dates turned out to be cases where Slavic and Greek traditions genuinely share the same saint (confirmed against the same source file) -- the shared ordering there was coincidental, not a signal that one reading should replace the other. Reverted those 10 after cross-checking; only Oct 6 and Oct 9 checked out as real Slavic-exclusive divergences.
OCA's own feast_name for Aug 1 ("Procession of the Lifegiving Cross; 7
Maccabean Martyrs") confirms the 'Martyrs' Reading rows (Heb 11.33-12.2
/ Matt 10.32-36) are OCA's own version of the Maccabees reading, not a
reference to Elesa or any other commemoration -- Antiochian's own
commemoration list for the date doesn't mention Elesa either. Since
Greek tradition already has its own version of this exact commemoration
(desc='Holy Maccabee Children', same Epistle, different Gospel), the
Slavic-labeled row was leaking into the Greek view as an apparent
duplicate Hebrews reading. Retagged to slavic so each tradition shows
only its own version, matching the same divergence pattern already
used for Oct 6/9 (St Innocent/St Tikhon).
Explains the new selectable translation alongside the existing KJV description, tying it back to the pre-existing note that KJV's Masoretic versification can make a handful of OT readings incorrect -- LXX2012, being a direct Septuagint translation, follows the same versification and OT content (including the anagignoskomena) the lectionary is actually based on.
Explains why WEB was chosen (Majority Text based, an update of the 1901 ASV, avoids interpretive biases of translations like the NIV), notes that LXX2012 and WEB are both from Michael Paul Johnson's public-domain modernization work via eBible.org, and switches both translation links to their Wikipedia articles.
Notes that the Eastern Orthodox Bible (EOB) project began as a revision of the WEB, and links eBible.org directly.
Mirrors the existing beta-note pattern used for the Greek tradition toggle, so first-time visitors notice the newly-added translation option rather than skipping past it.
Replaces the old italic "(beta)" note with the same red status-badge treatment used for the new translation selector, unifying the visual language for "this is a recent addition" across both. Renames new-badge to the more general status-badge since it's now used for both labels. Both badge placements needed flexbox centering (inline-flex + align-items: center) rather than plain vertical-align, since the select box and the badge/text don't share a baseline reliably by default -- vertical-align alone left the badges visibly low relative to their sibling text. Applying flex to both the Slavic and Greek tradition labels (not just Greek) was necessary too, since inline-flex establishes its own baseline calculation that differs from a plain inline label, and doing it asymmetrically threw the two labels out of alignment with each other.
Every push to a non-main branch already triggers the push-event workflow; once that branch has an open PR, the same commit also triggers the pull_request-event workflow, running the full test suite twice for one push. Adds a concurrency group keyed on the branch name (github.head_ref for pull_request events, github.ref_name for push events -- these must be the short name, not github.ref's refs/heads/ prefixed form, or the two event types never share a group) so the older of the two redundant runs gets cancelled instead of both running to completion.
The concurrency group (previous commit) reduced wasted CI time but didn't fix the actual problem: branch protection requires a "test" status check, and both the push- and pull_request-triggered runs report under that same context for the same commit. A cancelled push run could still show as a non-passing required check and block merging, even when the pull_request run succeeded. Restricting push to branches: [main] means only one event type ever fires per commit once a PR exists (pull_request already re-triggers on every push to the PR branch). Trade-off: a branch with no open PR gets no CI run until a PR is opened for it.
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
<select>dropdown on the readings page (English only, since Romanian/Serbian each still have one translation), a/readings/<tradition>/<cal>/<translation>/...URL segment remembered in session, and an optional?translation=query parameter on the four Day-returning API endpoints (kept as a query param rather than a new required path segment, to avoid doubling the tradition route matrix).<v id="1-2">) crashing the integer verse field, and<x>cross-reference elements (e.g. "11:33 Daniel 6:22-23") leaking directly into verse content.commontoslavic, fixing cases where the Greek tradition view showed a duplicate/leftover Slavic-specific reading alongside its own correct one — verified against antiochian.org's own commemoration data date-by-date rather than by heuristic.Test plan
🤖 Generated with Claude Code
https://claude.ai/code/session_01Hf6j2xXQXywHVh3HAVRxB3