Prefix all SX URLs with /sx/ for WhatsApp-safe sharing

All routes moved under /sx/ prefix:
- / redirects to /sx/
- /sx/ serves home page
- /sx/<path:expr> is the catch-all for SX expression URLs
- Bare /(...) and /~... redirect to /sx/(...) and /sx/~...
- All ~600 hrefs, sx-get attrs, defhandler paths, redirect
  targets, and blueprint routes updated across 44 files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 19:07:09 +00:00
parent acd2fa6541
commit de80d921e9
44 changed files with 701 additions and 687 deletions

View File

@@ -119,15 +119,23 @@ def create_app() -> "Quart":
@app.before_request
async def sx_url_redirect():
"""Redirect old-style paths to SX expression URLs (301)."""
"""Redirect old-style paths and bare root to /sx/ URLs (301)."""
from quart import request, redirect as q_redirect
path = request.path
# Root → /sx/
if path == "/":
return q_redirect("/sx/", 301)
# Skip non-page paths
if path.startswith(("/static/", "/internal/", "/auth/", "/sx/")):
if path.startswith(("/static/", "/internal/", "/auth/")):
return None
# Skip SX expression URLs (already in new format)
# Skip SX expression URLs (already in new format under /sx/)
if path.startswith("/sx/"):
return None
# Redirect bare /(...) to /sx/(...)
if path.startswith("/(") or path.startswith("/~"):
return None
qs = request.query_string.decode()
target = f"/sx{path}" + ("?" + qs if qs else "")
return q_redirect(target, 301)
new_url = redirect_old_url(path)
if new_url:
qs = request.query_string.decode()
@@ -140,20 +148,26 @@ def create_app() -> "Quart":
from quart import request, redirect
path = request.path
# Skip SX expression URLs — they don't use trailing slashes
if "(" in path or path.startswith("/~"):
if "(" in path or "/~" in path:
return None
if (path != "/"
and path != "/sx/"
and not path.endswith("/")
and request.method == "GET"
and not path.startswith(("/static/", "/internal/", "/auth/"))
and not path.startswith(("/static/", "/internal/", "/auth/", "/sx/"))
and "." not in path.rsplit("/", 1)[-1]):
qs = request.query_string.decode()
target = path + "/" + ("?" + qs if qs else "")
return redirect(target, 301)
@app.get("/<path:expr>")
@app.get("/sx/")
async def sx_home():
"""SX docs home page."""
return await eval_sx_url("/")
@app.get("/sx/<path:expr>")
async def sx_eval_route(expr):
"""Catch-all: evaluate SX expression URLs."""
"""Catch-all: evaluate SX expression URLs under /sx/ prefix."""
result = await eval_sx_url(f"/{expr}")
if result is None:
from quart import abort