Adressen: Slug und Version im Pfad statt Parameter
Seite: /<slug>[/v<N>][/lauf|/buch|/lesen][/<Abschnitt>], Zurück-Taste je Abschnitt. API: /api/themen/<slug>/v<N>/… mit Version als Pflichtteil des Pfads; /api/topics entfällt. Slugs stehen in thema.json und werden beim Start nachgetragen. Unbekannte API-Pfade liefern 404 statt der Seite. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,20 @@ def schluessel(name: str, v: int | None = None) -> str | None:
|
||||
return f"{name}/v{vs[-1] if v is None else v}"
|
||||
|
||||
|
||||
def slug_frei(name: str) -> str:
|
||||
"""Eindeutiger Slug für die Adresse: „Godot 4“ → „godot-4“; bei Kollision „godot-4-2“."""
|
||||
basis = slug(name)
|
||||
vergeben = {t.get("slug") for t in themen()}
|
||||
k, i = basis, 2
|
||||
while k in vergeben:
|
||||
k, i = f"{basis}-{i}", i + 1
|
||||
return k
|
||||
|
||||
|
||||
def name_von_slug(sl: str) -> str | None:
|
||||
return next((t["name"] for t in themen() if t.get("slug") == sl), None)
|
||||
|
||||
|
||||
def version_anlegen(name: str) -> str:
|
||||
n = (versionen(name) or [0])[-1] + 1
|
||||
key = f"{name}/v{n}"
|
||||
@@ -60,8 +74,12 @@ def version_loeschen(key: str) -> None:
|
||||
|
||||
|
||||
def migrieren() -> None:
|
||||
"""Alte Ablage (alles direkt unter storage/<Thema>/) einmalig nach v1/ verschieben."""
|
||||
"""Alte Ablage (alles direkt unter storage/<Thema>/) einmalig nach v1/ verschieben; Slugs nachtragen."""
|
||||
for d in config.STORAGE.glob("*/"):
|
||||
t = _lesen(d / "thema.json", None)
|
||||
if t and not t.get("slug"):
|
||||
t["slug"] = slug_frei(t["name"])
|
||||
_schreiben(d / "thema.json", t)
|
||||
if not (d / "thema.json").exists() or not (d / "state.json").exists() or (d / "v1").exists():
|
||||
continue
|
||||
v1 = d / "v1"
|
||||
@@ -106,7 +124,7 @@ def anlegen(name: str, hinweise: str) -> dict:
|
||||
if d.exists():
|
||||
raise ValueError("Thema existiert schon")
|
||||
d.mkdir(parents=True)
|
||||
t = {"name": name, "titel": name, "hinweise": hinweise.strip(), "angelegt": jetzt()}
|
||||
t = {"name": name, "slug": slug_frei(name), "titel": name, "hinweise": hinweise.strip(), "angelegt": jetzt()}
|
||||
_schreiben(d / "thema.json", t)
|
||||
version_anlegen(name)
|
||||
return t
|
||||
@@ -213,7 +231,7 @@ def slug(text: str) -> str:
|
||||
for a, b in (("ä", "ae"), ("ö", "oe"), ("ü", "ue"), ("ß", "ss")):
|
||||
t = t.replace(a, b)
|
||||
t = re.sub(r"[^a-z0-9]+", "-", t).strip("-")
|
||||
return t[:60] or "kapitel"
|
||||
return t[:60] or "thema"
|
||||
|
||||
|
||||
def position(name: str) -> dict:
|
||||
|
||||
Reference in New Issue
Block a user