Translate the whole site to English: English routes with 301 redirects from the Dutch paths, English UI, docs, seeds and captions, one-time live content migration

This commit is contained in:
2026-10-05 11:25:41 +02:00
parent bbdecdc95b
commit ff547e1677
153 changed files with 1095 additions and 774 deletions
+56 -12
View File
@@ -6,13 +6,15 @@ from molodetz.database import (
now_iso,
db,
)
from molodetz.constants import LEGACY_TOPICS
from molodetz.database.core import make_combined_slug
from molodetz.utils.audit import record
from molodetz.utils.notifications import create_notification
PLACEHOLDER_NOTE = (
"\n\n> Placeholder. Dit is overgenomen uit de oude Molodetz-pagina. "
"retoor vervangt dit later door zijn eigen verhaal."
"\n\n> Placeholder. Carried over from the old Molodetz page. "
"retoor will replace it with his own story."
)
@@ -22,7 +24,7 @@ def create_post(user, title, body, topic, status="draft", is_placeholder=False,
row = insert_post(user["uid"], title, body, topic, status=status, is_placeholder=is_placeholder)
record(request, "post.create", payload={"uid": row["uid"], "status": status}, targets=[("post", row["uid"])], user=user)
if status == "published":
create_notification(user["uid"], "post.published", f"Gepubliceerd: {title}", f"/posts/{row['slug']}")
create_notification(user["uid"], "post.published", f"Published: {title}", f"/posts/{row['slug']}")
return row
@@ -55,18 +57,60 @@ def delete_post(post, actor, request=None):
return stamp
SEED_POSTS = [
(
"standard",
"Thirty-one choices. You have zero.",
"Python 3.12. FastAPI. Jinja2. SQLite. No JWT, because that is a hobby. No JavaScript framework, because that is a catalogue. The document says MUST 107 times. Whoever turns that into \"it depends\" has no taste. They have a roadmap made of other people's tutorials.",
),
("roll", "A pass is not an ambition.", "Settle for good enough and you build good enough. Molodetz starts where that stops."),
("roll", "Finished is a feature.", "A project that stays open is an opinion. A project that is finished is a fact."),
("roll", "The assistant is not a senior.", "AI speeds up the work. It does not replace judgement. Confuse the two and you hand in a chat log."),
("roll", "No course.", "Knowledge travels here from people to people. Not through an ebook promising you will become someone else over a weekend."),
]
LEGACY_SEED_TITLES = {
"Eenendertig keuzes. Jij hebt er nul.": "Thirty-one choices. You have zero.",
"Een zes is geen ambitie.": "A pass is not an ambition.",
"Af is een eigenschap.": "Finished is a feature.",
"De assistent is geen senior.": "The assistant is not a senior.",
"Geen cursus.": "No course.",
}
def seed_placeholder_posts(admin):
seeds = [
("standaard", "Eenendertig keuzes. Jij hebt er nul.", "Python 3.12. FastAPI. Jinja2. SQLite. Geen JWT, want dat is een hobby. Geen JavaScript-framework, want dat is een catalogus. Het document zegt 107 keer MUST. Wie daar \"het hangt ervan af\" van maakt, heeft geen smaak. Die heeft een roadmap van andermans tutorials."),
("rol", "Een zes is geen ambitie.", "Wie tevreden is met voldoende, bouwt voldoende. Molodetz begint waar dat ophoudt."),
("rol", "Af is een eigenschap.", "Een project dat open blijft, is een mening. Een project dat af is, is een feit."),
("rol", "De assistent is geen senior.", "AI versnelt het werk. Het vervangt het oordeel niet. Wie dat door elkaar haalt, levert een chatlog in."),
("rol", "Geen cursus.", "Kennis gaat hier van mensen naar mensen. Niet via een ebook dat belooft dat je in een weekend iemand anders wordt."),
]
created = []
for topic, title, body in seeds:
for topic, title, body in SEED_POSTS:
existing = db["posts"].find_one(title=title, deleted_at=None) if "posts" in db.tables else None
if existing:
continue
created.append(create_post(admin, title, body, topic, status="published", is_placeholder=topic == "rol"))
created.append(create_post(admin, title, body, topic, status="published", is_placeholder=topic == "roll"))
return created
def translate_seeded_posts():
if "posts" not in db.tables:
return 0
seeds = {title: (topic, body) for topic, title, body in SEED_POSTS}
table = db["posts"]
for old, new in LEGACY_TOPICS.items():
for row in list(table.find(topic=old)):
table.update({"uid": row["uid"], "topic": new}, ["uid"])
changed = 0
for dutch, english in LEGACY_SEED_TITLES.items():
topic, body = seeds[english]
for row in list(table.find(title=dutch)):
body_out = body.rstrip() + PLACEHOLDER_NOTE if row.get("is_placeholder") else body
table.update(
{
"uid": row["uid"],
"title": english,
"body": body_out,
"topic": topic,
"slug": make_combined_slug(english, row["uid"]),
"updated_at": now_iso(),
},
["uid"],
)
changed += 1
return changed