Skip to content

Remove page-based versioning system, add URL bridge middleware (#452)#453

Merged
thibaudcolas merged 3 commits into
mainfrom
remove-vesrioning-system
Jul 9, 2026
Merged

Remove page-based versioning system, add URL bridge middleware (#452)#453
thibaudcolas merged 3 commits into
mainfrom
remove-vesrioning-system

Conversation

@Raghaddahi

@Raghaddahi Raghaddahi commented Jul 1, 2026

Copy link
Copy Markdown
Member

Fixes #452

Description

Removes the existing page-based versioning system (which treated Wagtail versions as fake Locales via LANGUAGE_CODE suffixes like en-6.0.x) and replaces it with a lightweight URL bridge middleware. Old version-suffixed URLs (e.g. /en-6.0.x/how-to-guides/manage-snippets/) now 302-redirect to the bare-locale URL with a ?target_version= query param: /en/how-to-guides/manage-snippets/?target_version=6.0.x.

Why this approach

The fake-locale design required monkey-patching Django's language-code regexes, a cartesian product of LANGUAGES × WAGTAIL_GUIDE_VERSIONS, duplicate HomePage/content trees per version, and complex version-combo fallback logic. Collapsing to bare locales (en, nl, pt-br) eliminates all of that while the bridge middleware keeps existing external /en-X.x/ links working — staged rollout without breaking saved URLs.

Areas requiring careful review

  • apps/core/middleware.py — new VersionedUrlRedirectMiddleware. Regex is strict (latest | N.N.x | N.x), non-GET passes through (no form-submit redirects), 302 (to be flipped to 301 after a week of clean logs). Wired ABOVE LocaleMiddleware so the dotted prefix never reaches locale activation.
  • apps/guide/settings/base.pyWAGTAIL_GUIDE_VERSIONS deleted, LANGUAGES = WAGTAIL_GUIDE_LANGUAGES (bare codes), LANGUAGE_CODE = "en". This is the root unblock; every downstream edit depends on it.
  • apps/core/migrations/0007_initial_footercontent.py — edited historical migration: hardcoded "en-latest" lookup → "en". Safe because prod already has 0007 applied (won't re-run); only fresh test/new installs re-run the edited version.
  • apps/core/models/home.pyget_fallback_pages simplified to plain translation fallback (no version matrix). The old rsplit("-", 1) would crash on bare locale codes.

Testing

New middleware test file

apps/core/tests/test_versioned_url_redirect.py — 7 dedicated tests for VersionedUrlRedirectMiddleware:

poetry run python manage.py test apps.core.tests.test_versioned_url_redirect -v 2

Manual QA worth doing

  • curl -I localhost:8000/en-6.0.x/how-to-guides/manage-snippets/ — confirm 302 to /en/how-to-guides/manage-snippets/?target_version=6.0.x.
  • Verify admin "View live" links still work (the LocaleURLMixin removal affects ContentPage's get_url_parts).

Out of scope (follow-up)

  • Production data migration (step 3) — deleting version-suffixed Locale rows + page trees from the prod DB. To be done after this is deployed and stable.
  • prompts/content/ regeneration — the fetch_content.py script is already updated to use en, but re-running it against the live site should happen after deploy. A separate PR will regenerate prompts/content/en/ and delete the stale en-latest/ directory.

AI usage

The
AI (opencode / glm-5.2) assisted with this PR description ,discussion and review throughout the implementation.
all code is reviewed by me

@Raghaddahi

Copy link
Copy Markdown
Member Author

Tested the versioning-removal branch against a restored copy of production data. The VersionedUrlRedirectMiddleware correctly redirects old versioned URLs (e.g. /en-6.0.x/...) to the new format (/en/...?target_version=6.0.x), confirmed via curl. However, the destination fails with a 500 Internal Server Error, because production data only contains versioned locales (en-latest, en-4.1.x … en-7.4.x, etc.) — there is no plain en locale for Wagtail to resolve the page against. This branch needs a data migration to consolidate locales (e.g., promote en-latest → en) before it can be deployed against real production data.

claude code

@thibaudcolas thibaudcolas temporarily deployed to wagtail-guid-remove-ves-ipb1zl July 9, 2026 06:25 Inactive
@thibaudcolas thibaudcolas force-pushed the remove-vesrioning-system branch from 95990a5 to 58054d9 Compare July 9, 2026 07:35
Comment thread apps/core/middleware.py Outdated
Comment on lines +29 to +30
rest = match.group("rest")
parsed = urlparse(rest)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just rest should be enough no?

@RealOrangeOne RealOrangeOne temporarily deployed to wagtail-guid-remove-ves-2trrvg July 9, 2026 07:38 Inactive
@thibaudcolas thibaudcolas temporarily deployed to wagtail-guid-remove-ves-2trrvg July 9, 2026 08:05 Inactive
@thibaudcolas thibaudcolas merged commit 0e8a469 into main Jul 9, 2026
1 check passed
@thibaudcolas thibaudcolas deleted the remove-vesrioning-system branch July 9, 2026 11:05
@github-project-automation github-project-automation Bot moved this from 🔍 Reviewing to ✅ Done in GSoC 2026: Guide website revamp Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

Remove current versioning system from the site

3 participants